JDK20 + SpringBoot 3.1.0 + JdbcTemplate 使用

news2024/12/23 4:16:37

JDK20 + SpringBoot 3.1.0 + JdbcTemplate 使用

  • 一.测试数据库 Postgres
  • 二.SpringBoot项目
    • 1.Pom 依赖
    • 2.配置文件
    • 3.启动类
    • 4.数据源配置类
    • 5.实体对象类包装类
    • 6.测试用实体对象
      • 1.基类
      • 2.扩展类
    • 7.测试类

通过 JdbcTemplate 直接执行 SQL 语句,结合源码动态编译即可方便实现动态修改代码逻辑的效果

一.测试数据库 Postgres

在这里插入图片描述

-- public.tb_rabbit_basic definition

-- Drop table

-- DROP TABLE public.tb_rabbit_basic;

CREATE TABLE public.tb_rabbit_basic (
	id int4 NULL,
	animal_name varchar NULL,
	country varchar NULL
);

二.SpringBoot项目

1.Pom 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>org.example</groupId>
    <artifactId>JdbcTemplateDemo</artifactId>
    <version>1.0-SNAPSHOT</version>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <configuration>
                    <source>18</source>
                    <target>18</target>
                </configuration>
            </plugin>
        </plugins>
    </build>

    <properties>
        <maven.compiler.source>20</maven.compiler.source>
        <maven.compiler.target>20</maven.compiler.target>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <spring-boot.version>3.1.0</spring-boot.version>
    </properties>

    <!--配置阿里云依赖包和插件仓库-->
    <repositories>
        <repository>
            <id>aliyun</id>
            <url>https://maven.aliyun.com/repository/central/</url>
            <releases>
                <enabled>true</enabled>
            </releases>
            <snapshots>
                <enabled>true</enabled>
            </snapshots>
        </repository>
    </repositories>

    <dependencies>

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring-boot.version}</version>
        </dependency>

        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.26</version>
        </dependency>

        <!--druid-->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid-spring-boot-starter</artifactId>
            <version>1.2.16</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-autoconfigure</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!--        mybatis-->
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>3.0.2</version>
            <exclusions>
                <exclusion>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-autoconfigure</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.slf4j</groupId>
                    <artifactId>slf4j-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
        <!-- pgsql -->
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>42.6.0</version>
        </dependency>
    </dependencies>
</project>

2.配置文件

server:
  port: 8081

spring:
  datasource:
    postgres:
      readTimeout: 259200000 # 3 * 24 * 60 * 60 * 1000
    druid:
      username: postgres
      password: 123456
      url: jdbc:postgresql://127.0.0.1:5432/wiki_animal_db
      driverClassName: org.postgresql.Driver
      type: com.alibaba.druid.pool.DruidDataSource
      # 下面为连接池的补充设置,应用到上面所有数据源中
      # 初始化大小,最小,最大
      initial-size: 5
      min-idle: 5
      max-active: 20
      # 配置获取连接等待超时的时间
      max-wait: 60000
      # 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
      time-between-eviction-runs-millis: 60000
      # 配置一个连接在池中最小生存的时间,单位是毫秒
      min-evictable-idle-time-millis: 300000
      validation-query: select version()
      test-while-idle: true
      test-on-borrow: false
      test-on-return: false
      # 打开PSCache,并且指定每个连接上PSCache的大小
      pool-prepared-statements: true
      #   配置监控统计拦截的filters,去掉后监控界面sql无法统计,wall用于防火墙
      max-pool-prepared-statement-per-connection-size: 20
      filters: stat,wall
      use-global-data-source-stat: true
      # 通过connectProperties属性来打开mergeSql功能;慢SQL记录
      connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000

3.启动类

package org.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

/**
 * @author moon
 */
@SpringBootApplication
public class JdbcApp {

    public static void main(String[] args) {
        SpringApplication.run(JdbcApp.class, args);
    }
}

4.数据源配置类

package org.example.config;

import com.alibaba.druid.pool.DruidDataSource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.jdbc.core.JdbcTemplate;

import java.sql.SQLException;
import java.util.Properties;

/**
 * @author moon
 * @date 2023-09-12 12:00
 * @since 1.8
 */
@Slf4j
@Configuration
public class PostgresDataSource {

    /**
     * Postgres readTimeout 超时 暂定 3D 可能导致存在大量 socket 死链接
     */
    @Value("${spring.datasource.postgres.readTimeout}")
    private int readTimeout;

    @Bean(name = "druidProperties")
    @ConfigurationProperties(prefix = "spring.datasource")
    public Properties druidProperties(){
        return new Properties();
    }

    /**
     * @description: 数据源
     * @params: [properties]
     * @return: com.alibaba.druid.pool.DruidDataSource
     * @create: 2023-09-12
     */
    @Primary
    @Bean(name = "druidDataSource")
    public DruidDataSource druidDataSource(@Qualifier("druidProperties") Properties properties){
        DruidDataSource druidDataSource = new DruidDataSource();
        druidDataSource.configFromPropety(properties);
        try {
            druidDataSource.setSocketTimeout(readTimeout);
            druidDataSource.init();
        } catch (SQLException e) {
            log.error("Postgres Datasource Init Exception:",e);
        }
        return druidDataSource;
    }

    /**
     * jdbc template
     * @param druidDataSource
     * @return
     */
    @Bean(name = "postgresTemplate")
    public JdbcTemplate postgresTemplate(@Qualifier("druidDataSource") DruidDataSource druidDataSource){
        return new JdbcTemplate(druidDataSource);
    }
}

5.实体对象类包装类

用于配置实体对象类,方便解析 JdbcTemplate 查询的返回值
package org.example.config;

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.BeanWrapperImpl;
import org.springframework.beans.NotWritablePropertyException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.dao.DataRetrievalFailureException;
import org.springframework.dao.InvalidDataAccessApiUsageException;
import org.springframework.jdbc.core.RowMapper;
import org.springframework.jdbc.support.JdbcUtils;
import org.springframework.lang.Nullable;
import org.springframework.stereotype.Component;
import org.springframework.util.ClassUtils;
import org.springframework.util.StringUtils;

import java.beans.PropertyDescriptor;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.*;
import java.util.concurrent.Semaphore;
import java.util.concurrent.TimeUnit;

/**
 * @author moon
 * @date 2023-09-11 18:08
 * @since 1.8
 */
@Slf4j
@Component
public class ColumnRowMap {

    private Map<String,MultiColumnRowMapper> map = new HashMap<>(16);

    Semaphore semaphore = new Semaphore(1);

    /**
     * 获取类包装对象
     * @param clazz
     * @return
     */
    public MultiColumnRowMapper getColumnRowMap(Class<?> clazz) {
        while (true){
            boolean acquire = false;
            try {
                acquire = semaphore.tryAcquire(3, TimeUnit.SECONDS);
                if (acquire){
                    MultiColumnRowMapper mapper = map.get(clazz.getName());
                    if (null == mapper){
                        mapper = new MultiColumnRowMapper<>(clazz);
                        map.put(clazz.getName(),mapper);
                    }
                    //返回
                    return mapper;
                }
            } catch (InterruptedException e) {
                log.error("get column row map exception:",e);
            } finally {
                if (acquire){
                    semaphore.release();
                }
            }
        }
    }

    static class MultiColumnRowMapper<T> implements RowMapper<T> {

        /**
         * 日志
         */
        protected final Log logger = LogFactory.getLog(this.getClass());

        /**
         * 转换类型
         */
        @Nullable
        private Class<T> requiredType;

        /**
         * 缓存类属性
         */
        @Nullable
        private Map<String, PropertyDescriptor> mappedFields;

        @Nullable
        private Set<String> mappedProperties;

        private boolean primitivesDefaultedForNullValue = true;

        /**
         * 是否校验属性一致
         */
        private boolean checkFullyPopulated = false;

        public void setCheckFullyPopulated(boolean checkFullyPopulated) {
            this.checkFullyPopulated = checkFullyPopulated;
        }

        public boolean isCheckFullyPopulated() {
            return this.checkFullyPopulated;
        }

        public void setPrimitivesDefaultedForNullValue(boolean primitivesDefaultedForNullValue) {
            this.primitivesDefaultedForNullValue = primitivesDefaultedForNullValue;
        }

        public boolean isPrimitivesDefaultedForNullValue() {
            return this.primitivesDefaultedForNullValue;
        }

        /**
         * 构造并解析目标类属性信息
         * @param requiredType
         */
        public MultiColumnRowMapper(Class<T> requiredType) {
            this.requiredType = requiredType;
            init();
        }

        /**
         * 解析属性
         */
        private void init(){
            PropertyDescriptor[] var2 = BeanUtils.getPropertyDescriptors(requiredType);
            int var3 = var2.length;
            this.mappedFields = new HashMap(var3);
            this.mappedProperties = new HashSet(var3);
            for(int var4 = 0; var4 < var3; ++var4) {
                PropertyDescriptor pd = var2[var4];
                if (pd.getWriteMethod() != null) {
                    String lowerCaseName = this.lowerCaseName(pd.getName());
                    this.mappedFields.put(lowerCaseName, pd);
                    String underscoreName = this.underscoreName(pd.getName());
                    if (!lowerCaseName.equals(underscoreName)) {
                        this.mappedFields.put(underscoreName, pd);
                    }
                    this.mappedProperties.add(pd.getName());
                }
            }
        }

        /**
         * 将返回信息转为指定类对象
         * @param rs
         * @param rowNumber
         * @return
         * @throws SQLException
         */
        @Nullable
        public T mapRow(ResultSet rs, int rowNumber) throws SQLException {
            ResultSetMetaData rsmd = rs.getMetaData();
            int columnCount = rsmd.getColumnCount();
            T mappedObject = BeanUtils.instantiateClass(requiredType);
            Set<String> populatedProperties = this.isCheckFullyPopulated() ? new HashSet() : null;
            BeanWrapperImpl bw = new BeanWrapperImpl();
            bw.setBeanInstance(mappedObject);
            PropertyDescriptor pd;
            for(int index = 1; index <= columnCount; ++index) {
                String column = JdbcUtils.lookupColumnName(rsmd, index);
                String field = this.lowerCaseName(StringUtils.delete(column, " "));
                pd = this.mappedFields != null ? this.mappedFields.get(field) : null;
                if (pd != null) {
                    try {
                        Object value = this.getColumnValue(rs, index, pd);
                        if (rowNumber == 0 && this.logger.isDebugEnabled()) {
                            this.logger.debug("Mapping column '" + column + "' to property '" + pd.getName() + "' of type '" + ClassUtils.getQualifiedName(pd.getPropertyType()) + "'");
                        }
                        try {
                            bw.setPropertyValue(pd.getName(), value);
                        } catch (TypeMismatchException var14) {
                            if (value != null || !this.primitivesDefaultedForNullValue) {
                                throw var14;
                            }

                            if (this.logger.isDebugEnabled()) {
                                this.logger.debug("Intercepted TypeMismatchException for row " + rowNumber + " and column '" + column + "' with null value when setting property '" + pd.getName() + "' of type '" + ClassUtils.getQualifiedName(pd.getPropertyType()) + "' on object: " + mappedObject, var14);
                            }
                        }

                        if (populatedProperties != null) {
                            populatedProperties.add(pd.getName());
                        }
                    } catch (NotWritablePropertyException var15) {
                        throw new DataRetrievalFailureException("Unable to map column '" + column + "' to property '" + pd.getName() + "'", var15);
                    }
                }
            }
            //校验属性一致性
            if (populatedProperties != null && !populatedProperties.equals(this.mappedProperties)) {
                throw new InvalidDataAccessApiUsageException("Given ResultSet does not contain all fields necessary to populate object of " + this.requiredType.getName() + ": " + this.mappedProperties);
            } else {
                return mappedObject;
            }
        }

        @Nullable
        protected Object getColumnValue(ResultSet rs, int index, PropertyDescriptor pd) throws SQLException {
            return JdbcUtils.getResultSetValue(rs, index, pd.getPropertyType());
        }

        protected String lowerCaseName(String name) {
            return name.toLowerCase(Locale.US);
        }

        protected String underscoreName(String name) {
            if (!StringUtils.hasLength(name)) {
                return "";
            } else {
                StringBuilder result = new StringBuilder();
                result.append(Character.toLowerCase(name.charAt(0)));

                for(int i = 1; i < name.length(); ++i) {
                    char c = name.charAt(i);
                    if (Character.isUpperCase(c)) {
                        result.append('_').append(Character.toLowerCase(c));
                    } else {
                        result.append(c);
                    }
                }

                return result.toString();
            }
        }

    }

}

6.测试用实体对象

1.基类

package org.example.entity;

import lombok.Data;

/**
 * @author moon
 * @date 2023-09-12 10:45
 * @since 1.8
 */
@Data
public class BaseAnimal {

    private int id;
    private String animalName;
    private String country;

}

2.扩展类

package org.example.entity;

/**
 * @author moon
 * @date 2023-09-12 10:48
 * @since 1.8
 */
public class Rabbit extends BaseAnimal{
}

7.测试类

package org.example.controller;

import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.example.config.ColumnRowMap;
import org.example.entity.Rabbit;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.support.rowset.SqlRowSet;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * @author moon
 * @date 2023-09-12 11:52
 * @since 1.8
 */
@Slf4j
@RestController
@RequestMapping("/animal")
public class AnimalController {

    @Resource(name = "postgresTemplate")
    private JdbcTemplate postgresTemplate;

    @Autowired
    private ColumnRowMap columnRowMap;

    /**
     * 插入 通过 ? 参数占位符
     */
    @GetMapping("/insert")
    public void insert(){
        postgresTemplate.update("INSERT INTO PUBLIC.TB_RABBIT_BASIC (ID, ANIMAL_NAME, COUNTRY) VALUES (?,?,?)",18,"海棠兔","法国");
    }

    /**
     * 批量插入
     */
    @GetMapping("/batchInsert")
    public void batchInsert(){
        List<Object[]> list = new ArrayList<>(3);
        list.add(new Object[]{19,"海棠兔","法国"});
        list.add(new Object[]{20,"喜马拉雅兔","中国"});
        list.add(new Object[]{30,"野兔","比利时"});
        postgresTemplate.batchUpdate("INSERT INTO PUBLIC.TB_RABBIT_BASIC (ID, ANIMAL_NAME, COUNTRY) VALUES (?,?,?)",list);
    }

    /**
     * 更新
     */
    @GetMapping("/update")
    public void update(){
        postgresTemplate.update("UPDATE PUBLIC.TB_RABBIT_BASIC SET COUNTRY = ? WHERE ID = ?","法国+",19);
    }

    /**
     * 更新
     */
    @GetMapping("/batchUpdate")
    public void batchUpdate(){
        List<Object[]> list = new ArrayList<>(3);
        list.add(new Object[]{"法国+++",19});
        list.add(new Object[]{"中国+++",20});
        list.add(new Object[]{"比利时+++",30});
        postgresTemplate.batchUpdate("UPDATE PUBLIC.TB_RABBIT_BASIC SET COUNTRY = ? WHERE ID = ?",list);
    }

    /**
     * 删除
     */
    @GetMapping("/delete")
    public void delete(){
        postgresTemplate.update("DELETE FROM PUBLIC.TB_RABBIT_BASIC WHERE ID = ?",19);
    }

    /**
     * 批量删除
     */
    @GetMapping("/batchDelete")
    public int[] batchDelete(){
        List<Object[]> list = new ArrayList<>();
        list.add(new Object[]{19});
        list.add(new Object[]{20});
        list.add(new Object[]{30});
        int[] result = postgresTemplate.batchUpdate("DELETE FROM PUBLIC.TB_RABBIT_BASIC WHERE ID = ?",list);
        return  result;
    }

    /**
     * 查询 select *
     * @return
     */
    @GetMapping("/queryForMap")
    public Map<String, Object> queryForMap(){
        return postgresTemplate.queryForMap("SELECT * FROM PUBLIC.TB_RABBIT_BASIC WHERE ID = ?",18);
    }

    /**
     * 查询 query for row set
     * @return
     */
    @GetMapping("/queryForRowSet")
    public void queryForRowSet(){
        SqlRowSet rowSet = postgresTemplate.queryForRowSet("SELECT * FROM PUBLIC.TB_RABBIT_BASIC WHERE ID = ?",18);
        while (rowSet.next()){
            int rowId = rowSet.getRow();
            Integer ID = rowSet.getInt("ID");
            String ANIMAL_NAME = rowSet.getString("ANIMAL_NAME");
            String COUNTRY = rowSet.getString("COUNTRY");
            log.info("rowId {} id {} animalName {} country {}",rowId,ID,ANIMAL_NAME,COUNTRY);
        }
    }

    /**
     * 查询 query for object
     * @return
     */
    @GetMapping("/queryForObject")
    public Object queryForObject(){
        return postgresTemplate.queryForObject("SELECT ID AS id FROM PUBLIC.TB_RABBIT_BASIC WHERE ID = ?", Integer.class,18);
    }

    /**
     * 查询 query for object
     * @return
     */
    @GetMapping("/queryForObjectMapper")
    public Object queryForObjectMapper(){
        return postgresTemplate.queryForObject("SELECT ID AS id, ANIMAL_NAME AS animalName, COUNTRY AS country FROM PUBLIC.TB_RABBIT_BASIC WHERE ID = ?",columnRowMap.getColumnRowMap(Rabbit.class),18);
    }

    /**
     * 查询 query for object
     * @return
     */
    @GetMapping("/queryForList")
    public List<Map<String, Object>> queryForList(){
        return postgresTemplate.queryForList("SELECT ID AS id, ANIMAL_NAME AS animalName, COUNTRY AS country FROM PUBLIC.TB_RABBIT_BASIC");
    }

    /**
     * 查询 query for object class
     * @return
     */
    @GetMapping("/queryForListClass")
    public List<Rabbit> queryForListClass(){
        return postgresTemplate.query("SELECT ID AS id, ANIMAL_NAME AS animalName, COUNTRY AS country FROM PUBLIC.TB_RABBIT_BASIC",columnRowMap.getColumnRowMap(Rabbit.class));
    }
}

以批量查询为例:http://127.0.0.1:8081/animal/queryForListClass

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1004781.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

复现SCI文章系列教程 | 文章复现一(IF 7.3):文章讨论与文章分析套路讲解

一、本期复现文章 本系列教程从今天开始&#xff0c;前面想做&#xff0c;但是又没时间。作为佛系博主的我来说&#xff0c;这个系列教程算是一个长久的计划。会涉及医学和植物两大类。本系列教程详细情况可以看《复现SCI文章系列教程》. 我们第一篇复现的文章寻找的是的来自…

Spring MVC:请求转发与请求重定向

Spring MVC 请求转发请求重定向附 请求转发 转发&#xff08; forward &#xff09;&#xff0c;指服务器接收请求后&#xff0c;从一个资源跳转到另一个资源中。请求转发是一次请求&#xff0c;不会改变浏览器的请求地址。 简单示例&#xff1a; 1.通过 String 类型的返回值…

开学季买哪个牌子的电容笔好?ipad触控笔推荐平价

我想很多学生们在新学期开始之前就开始买iPad了&#xff0c;如今&#xff0c;作为iPad主要配件之一的电容笔&#xff0c;功能越来越强&#xff0c;使用的人也越来越多。所以&#xff0c;怎样选择一支质量好&#xff0c;价格便宜的电容笔就成了人们最为关注的问题。所以&#xf…

软件测试需求分析

1.1 需求的重要性 1.1.1 软件缺陷的8020原则 1) 在软件测试过程中&#xff0c;从需求分析开始到集成测试阶段引入测试手段&#xff0c;能发现所有缺陷的80%&#xff1b;系统测试阶段引入测试手段&#xff0c;能发现剩余缺陷中80%的缺陷&#xff1b;在运行维护阶段经过长…

云服务器与http服务器

如何与http服务器建立连接&#xff08;客户端&#xff09;&#xff1f; http请求设计格式&#xff1a; 例子&#xff1a; 发送http请求 http数据响应格式&#xff1a; 接收http服务器返回的数据需要进一步进行字符串处理操作&#xff0c;提取有用的数据。

21天学会C++:Day8----范围for与nullptr

目录 ​编辑 1. 范围for 2. nullptr 1. 范围for 我们在写C语言循环遍历代码的时候&#xff0c;无论是用 for循环&#xff0c;while循环都需要考虑循环的起始条件&#xff0c;循环变量的递增逻辑&#xff0c;循环的结束条件。麻烦不说还可能会出错。 int main() {int arr[]…

2023-09-11 LeetCode每日一题(课程表 III)

2023-09-11每日一题 一、题目编号 630. 课程表 III二、题目链接 点击跳转到题目位置 三、题目描述 这里有 n 门不同的在线课程&#xff0c;按从 1 到 n 编号。给你一个数组 courses &#xff0c;其中 courses[i] [durationi, lastDayi] 表示第 i 门课将会 持续 上 durati…

MySQL版数据库原理与应用期末复习重点(1)---关系代数(除运算和自连接查询、手写例题)

文章目录 一、除运算题目二、自连接查询 一、除运算题目 注&#xff1a;在除运算中就包含了选择和投影运算。 二、自连接查询 注&#xff1a;自连接查询一般很少用到。

引爆效率!新一代搜索引擎软件助您快速获取关键数据

一款突破性的搜索引擎软件&#xff0c;助您轻松检索相关数据 →→MsrayPlus官方网址 您是否曾为从海量信息中筛选出关键数据而烦恼&#xff1f;现在&#xff0c;我们为您推出一款全新的搜索引擎软件&#xff0c;让您从繁杂的搜索结果中快速捕捉所需信息。这款软件拥有三大功…

电脑网络不能用?解决99%的网络连接问题...

公文&#xff1a;网络又不能用了&#xff1f; 检查设备连接 首先&#xff0c;我们需要确保所有的网络设备都正确连接。检查以下几点&#xff1a; 路由器状态&#xff1a;确保路由器的电源开关打开&#xff0c;并且显示灯在正常工作。 网线连接&#xff1a;检查所有网线连接…

.Net MVC 使用Areas后存在相同Controller时报错的解决办法; 从上下文获取请求的Area名及Controller名

先来说个额外的问题&#xff1a;如何在请求上下文&#xff08;比如过滤器的中&#xff09;获取请求对应的Area和Controller 名字&#xff1f;&#xff08;假设请求上下文对象为 filterContext &#xff09;&#xff1a; 1. 获取Area名: (string)filterContext.RouteData.DataTo…

山西3D数字化企业品牌展馆

为持续扩大展览群众性和覆盖面、强化影响力和传播力&#xff0c;让更多群众方便快捷、丰富生动地体验展览&#xff0c;展览办委托中央广播电视总台央视网建设了展览数字化网上展馆&#xff0c;通过网络手段&#xff0c;全要素呈现展览内容&#xff0c;全景式还原现场体验&#…

腾讯云2核4G服务器5M带宽 218元一年 优惠价格明细表

腾讯云2核4G服务器5M带宽可以选择轻量应用服务器或云服务器ECS&#xff0c;轻量2核4G5M带宽服务器218元一年&#xff1a; 腾讯云2核4G服务器5M带宽收费 腾讯云2核4G服务器可以选择轻量应用服务器或者ECS云服务器&#xff0c;云服务器ECS是专业级云服务器&#xff0c;大多数使用…

STM32-HAL库06-硬件IIC驱动FM24CL16B非易失存储器

STM32-HAL库06-IIC驱动FM24CL16B非易失存储器 一、所用材料&#xff1a; STM32VGT6自制控制板 STM32CUBEMX&#xff08;HAL库软件&#xff09; MDK5 二、所学内容&#xff1a; 通过HAL库的硬件IIC对FM24CL16B存储器进行写与读取操作。 三、CUBEMX配置&#xff1a; 第一步…

C++继承相关应用练习

1、 实现一个图形类&#xff08;Shape&#xff09;&#xff0c;包含受保护成员属性&#xff1a;周长、面积&#xff0c; 公共成员函数&#xff1a;特殊成员函数书写 定义一个圆形类&#xff08;Circle&#xff09;&#xff0c;继承自图形类&#xff0c;包含私有属性&#xf…

试试用Markdown来设计表单

相信很多后端开发。对于前端知识是比较零碎的&#xff0c;所以很多时候写表单这样的工作&#xff0c;一般就是复制黏贴&#xff0c;然后改改字段。对于HTML格式&#xff0c;一直觉得比较杂乱&#xff0c;不够简洁。 最近TJ发现了一个有趣的小工具&#xff1a;Create HTML Form…

新手请进,Python是什么,Python简介!

Python 是荷兰人 Guido van Rossum &#xff08;吉多范罗苏姆&#xff0c;中国程序员称其为“龟叔”&#xff09;在 1990 年初开发的一种解释型编程语言。 图1&#xff1a;Python 的标志&#xff08;Logo&#xff09; Python 的诞生是极具戏曲性的&#xff0c;据 Guido 自述记载…

【拼多多API接口开发系列】拼多多商品详情接口:卖家必知的赚钱利器

拼多多&#xff0c;作为中国最大的社交电商之一&#xff0c;为卖家提供了丰富的商品详情接口。这些接口可以帮助卖家快速获取商品信息&#xff0c;提高销售效率。本文将详细介绍如何使用拼多多商品详情接口&#xff0c;以及它的优势和注意事项。 一、拼多多商品详情接口概述 …

LabVIEW以编程方式查找系统中DAQ设备的设备名称

LabVIEW以编程方式查找系统中DAQ设备的设备名称 使用DAQmx VI&#xff0c;“创建虚拟通道”函数&#xff0c;这个函数需要物理通道输入端。当使用相同型号的新设备&#xff08;例如&#xff0c;两个不同的USB-6210&#xff09;运行可执行文件时&#xff0c;代码会中断&#xf…

医院院检验科LIS系统源码 检验申请、标本编号、联机采集、报告单的生成与打印、质控图的绘制和数据的检索与备份

一套符合医院院检验科实际需要的管理系统, 实现检验业务全流程的计算机管理。从检验申请、标本编号、联机采集、中文报告单的生成与打印、质控图的绘制和数据的检索与备份。通过将所有仪器自身提供的端口与科室LIS系统中的工作站点连接,实现与医院HIS系统的联网。 通过门诊医生…