十三:java web(5)-- Spring数据持久层

目录

Spring 数据持久层

1. Spring 与 JDBC

1.1 使用 Spring 管理数据库连接

1.1.2 Apache Commons DBCP 基于配置文件xml 使用

1.1.3 Apache Commons DBCP 基于配置类使用

1.1.4 HikariCP 基于配置文件xml 使用 推荐使用 Spring Boot 默认连接池

1.1.5 HikariCP 基于配置类 使用

1.2 JdbcTemplate 的使用

1.2.1 DataSource 注入到 JdbcTemplate 基于xml方式

1.2.2 DataSource 注入到 JdbcTemplate 基于配置类方式

1.2.3 JdbcTemplate 基本操作  感觉了解就好 

1.3 总结:

2. Spring 与 ORM 框架

2.1 ORM框架是什么

2.2 集成 MyBatis 

基于xml 配置的方式 前提是你连接池可以连接上你数据库

2.2.1 引入pom.xml

2.2.2 编写配置文件 applicationContext.xml

2.2.3 编写实体类

2.2.4 编写mapper接口

2.2.5 编写mapper.xml

2.2.6 在使用的类 注入mapper类

2.2.7 主函数调用

3. 事务管理

3.1 事务管理的基础概念

3.2 声明式事务管理(@Transactional)

3.3 编程式事务管理


Spring 数据持久层

  • 1. Spring 与 JDBC

    • 1.1 使用 Spring 管理数据库连接

      • 1.1.1 Spring 提供了数据源(DataSource)的管理方式,通过将数据库连接池配置为一个 Spring Bean,Spring 可以帮助我们管理连接的创建与销毁。常用的数据源有:

        • DriverManagerDataSource:仅适用于测试环境,因为它不使用连接池。
        • Apache Commons DBCP:提供了基本的连接池功能。
        • HikariCP:高性能的连接池管理器。
      • 1.1.2 Apache Commons DBCP 基于配置文件xml 使用
        • pom.xml
          •         <dependency><groupId>org.apache.commons</groupId><artifactId>commons-dbcp2</artifactId><version>2.9.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency>
        • 配置文件 applicationContext.xml
          • <?xml version="1.0" encoding="UTF-8"?>
            <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--    applicationContext.xml 是 Spring 框架中的配置文件,通常用于定义 Spring IoC(控制反转)容器中的 Bean 配置和管理。这个文件主要用于将 Spring 的配置项和组件描述清楚,告知 Spring 容器如何实例化、配置和管理应用程序中的各种对象(Bean)。它是 Spring 配置的传统方式之一(除了注解和 Java 配置类)。--><bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource"><!-- 数据库驱动类 --><property name="driverClassName" value="com.mysql.cj.jdbc.Driver" /><!-- 数据库连接 URL --><property name="url" value="jdbc:mysql://localhost:3306/lirui" /><!-- 数据库用户名 --><property name="username" value="root" /><!-- 数据库密码 --><property name="password" value="root" /><!-- 可选的连接池参数 --><!-- 初始连接数 --><property name="initialSize" value="5" /><!-- 最大连接数 --><property name="maxTotal" value="20" /><!-- 最小空闲连接数 --><property name="minIdle" value="5" /><!-- 最大空闲连接数 --><property name="maxIdle" value="10" /><!-- 最大等待时间(毫秒),连接池用尽时的等待时长 --><property name="maxWaitMillis" value="10000" /></bean><!-- 配置 Engine Bean,带参数构造函数 --><bean id="engine" class="com.lirui.car.Engine"><constructor-arg value="V8" /></bean><!-- 配置 GPS Bean --><bean id="gps" class="com.lirui.car.GPSImpl" /><!-- 配置 Radio Bean --><bean id="radio" class="com.lirui.car.RadioImpl" /><!-- 配置 Car Bean,使用 setter 注入 --><bean id="car" class="com.lirui.car.Car"><property name="engine" ref="engine" /><property name="gps" ref="gps" /><property name="radio" ref="radio" /><property name="dataSource" ref="dataSource" /></bean></beans>
            
        • 调用
          • package com.lirui.car;import org.springframework.beans.factory.annotation.Autowired;import javax.sql.DataSource;
            import java.sql.Connection;
            import java.sql.PreparedStatement;
            import java.sql.ResultSet;
            import java.sql.SQLException;public class Car {private Engine engine;private GPS gps;private Radio radio;private DataSource dataSource;// Setters for dependency injectionpublic void setEngine(Engine engine) {this.engine = engine;}public void setGps(GPS gps) {this.gps = gps;}public void setRadio(Radio radio) {this.radio = radio;}public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}public void drive() {// 使用 DataSource 获取数据库连接并执行查询String sql = "SELECT id, ui_path, menu_type FROM t_sys_resource";try (Connection connection = dataSource.getConnection();PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery()) {// 遍历查询结果while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("ui_path");String email = resultSet.getString("menu_type");System.out.println("ID: " + id + ", ui_path: " + name + ", menu_type: " + email);}} catch (SQLException e) {e.printStackTrace();}System.out.println("引擎"+engine.getType() );gps.navigate();radio.playMusic();}
            }
            
        • 主函数
          •     public static void main(String[] args) {// 加载 Spring 配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 获取 userService BeanCar car = context.getBean("car", Car.class);// 调用方法car.drive();}

      • 1.1.3 Apache Commons DBCP 基于配置类使用
        • pom.xml

          •         <dependency><groupId>org.apache.commons</groupId><artifactId>commons-dbcp2</artifactId><version>2.9.0</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency>
        • application.properties

          • db.url=jdbc:mysql://localhost:3306/lirui
            db.username=root
            db.password=root
            db.driverClassName=com.mysql.cj.jdbc.Driver
            
        • config配置文件

          • package com.lirui.carconfig;import org.apache.commons.dbcp2.BasicDataSource;
            import org.springframework.beans.factory.annotation.Value;
            import org.springframework.context.annotation.*;import javax.sql.DataSource;@Configuration
            @ComponentScan(basePackages = "com.lirui.carconfig")
            @PropertySource("classpath:application.properties")
            @EnableAspectJAutoProxy
            public class AppConfig {@Value("${db.url}")private String dbUrl;@Value("${db.username}")private String dbUsername;@Value("${db.password}")private String dbPassword;@Value("${db.driverClassName}")private String driverClassName;@Beanpublic DataSource dataSource() {BasicDataSource dataSource = new BasicDataSource();dataSource.setDriverClassName(driverClassName);dataSource.setUrl(dbUrl);dataSource.setUsername(dbUsername);dataSource.setPassword(dbPassword);dataSource.setInitialSize(5);dataSource.setMaxTotal(20);dataSource.setMinIdle(5);dataSource.setMaxIdle(10);dataSource.setMaxWaitMillis(10000);return dataSource;}@Beanpublic Engine engine() {return new Engine("V8");}@Beanpublic GPS gps() {return new GPSImpl();}@Beanpublic Radio radio() {return new RadioImpl();}@Beanpublic Car car() {Car car = new Car();car.setEngine(engine());car.setGps(gps());car.setRadio(radio());car.setDataSource(dataSource());return car;}
            }
        • 调用

          • package com.lirui.carconfig;import org.springframework.beans.factory.annotation.Autowired;import javax.sql.DataSource;
            import java.sql.Connection;
            import java.sql.PreparedStatement;
            import java.sql.ResultSet;
            import java.sql.SQLException;public class Car {private Engine engine;private GPS gps;private Radio radio;private DataSource dataSource;public void setEngine(Engine engine) {this.engine = engine;}public void setGps(GPS gps) {this.gps = gps;}public void setRadio(Radio radio) {this.radio = radio;}public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}public void drive() {// 使用 DataSource 获取数据库连接并执行查询String sql = "SELECT id, ui_path, menu_type FROM t_sys_resource";try (Connection connection = dataSource.getConnection();PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery()) {// 遍历查询结果while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("ui_path");String email = resultSet.getString("menu_type");System.out.println("ID: " + id + ", ui_path: " + name + ", menu_type: " + email);}} catch (SQLException e) {e.printStackTrace();}System.out.println("引擎" + engine.getType());gps.navigate();radio.playMusic();}
            }
            
        • 主函数

          • package com.lirui.carconfig;import org.springframework.context.ApplicationContext;
            import org.springframework.context.annotation.AnnotationConfigApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {// 使用 Java 配置类来初始化 Spring 容器AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 获取 Car 实例,依赖项会自动注入Car car = context.getBean(Car.class);car.drive();context.close();}
            }
            

      • 1.1.4 HikariCP 基于配置文件xml 使用 推荐使用 Spring Boot 默认连接池
        • pom.xml (1.8版本 选3.x  11及以上 5.x)
          •         <!-- HikariCP 连接池依赖 --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>3.4.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency>
        • 配置文件 applicationContext.xml
          • <?xml version="1.0" encoding="UTF-8"?>
            <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--    applicationContext.xml 是 Spring 框架中的配置文件,通常用于定义 Spring IoC(控制反转)容器中的 Bean 配置和管理。这个文件主要用于将 Spring 的配置项和组件描述清楚,告知 Spring 容器如何实例化、配置和管理应用程序中的各种对象(Bean)。它是 Spring 配置的传统方式之一(除了注解和 Java 配置类)。--><!-- HikariCP 配置 --><bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"><!-- 设置数据库连接池配置 --><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/lirui?useSSL=false&amp;serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="root"/><!-- HikariCP 连接池相关参数 --><property name="maximumPoolSize" value="10"/> <!-- 最大连接数 --><property name="minimumIdle" value="5"/>     <!-- 最小空闲连接数 --><property name="connectionTimeout" value="30000"/> <!-- 连接超时(毫秒) --><property name="idleTimeout" value="600000"/> <!-- 空闲连接超时(毫秒) --><property name="maxLifetime" value="1800000"/> <!-- 连接最大生命周期(毫秒) --></bean><!-- 配置 Engine Bean,带参数构造函数 --><bean id="engine" class="com.lirui.car.Engine"><constructor-arg value="V8" /></bean><!-- 配置 GPS Bean --><bean id="gps" class="com.lirui.car.GPSImpl" /><!-- 配置 Radio Bean --><bean id="radio" class="com.lirui.car.RadioImpl" /><!-- 配置 Car Bean,使用 setter 注入 --><bean id="car" class="com.lirui.car.Car"><property name="engine" ref="engine" /><property name="gps" ref="gps" /><property name="radio" ref="radio" /><property name="dataSource" ref="dataSource" /></bean></beans>
            
        • sql调用函数
          • package com.lirui.car;import javax.sql.DataSource;
            import java.sql.Connection;
            import java.sql.PreparedStatement;
            import java.sql.ResultSet;
            import java.sql.SQLException;public class Car {private Engine engine;private GPS gps;private Radio radio;private DataSource dataSource;// Setters for dependency injectionpublic void setEngine(Engine engine) {this.engine = engine;}public void setGps(GPS gps) {this.gps = gps;}public void setRadio(Radio radio) {this.radio = radio;}public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}public void drive() {// 使用 DataSource 获取数据库连接并执行查询String sql = "SELECT id, ui_path, menu_type FROM t_sys_resource";try (Connection connection = dataSource.getConnection();PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery()) {// 遍历查询结果while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("ui_path");String email = resultSet.getString("menu_type");System.out.println("ID: " + id + ", ui_path: " + name + ", menu_type: " + email);}} catch (SQLException e) {e.printStackTrace();}System.out.println("引擎"+engine.getType() );gps.navigate();radio.playMusic();}
            }
            
        • 主函数
          • package com.lirui.car;import com.lirui.example.UserService;
            import org.springframework.context.ApplicationContext;
            import org.springframework.context.annotation.AnnotationConfigApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {// 加载 Spring 配置文件ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");// 获取 userService BeanCar car = context.getBean("car", Car.class);// 调用方法car.drive();}
            }
            

      • 1.1.5 HikariCP 基于配置类 使用
        • 和DBCP 差不多样的用法  改一下就可以了
        • package com.lirui.carconfig;import com.zaxxer.hikari.HikariConfig;
          import com.zaxxer.hikari.HikariDataSource;
          import org.apache.commons.dbcp2.BasicDataSource;
          import org.springframework.beans.factory.annotation.Value;
          import org.springframework.context.annotation.*;import javax.sql.DataSource;@Configuration
          @ComponentScan(basePackages = "com.lirui.carconfig")
          @PropertySource("classpath:application.properties")
          @EnableAspectJAutoProxy
          public class AppConfig {@Beanpublic DataSource dataSource() {HikariConfig hikariConfig = new HikariConfig();// 数据库连接信息hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");hikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/lirui?useSSL=false&serverTimezone=UTC");hikariConfig.setUsername("root");hikariConfig.setPassword("root");// HikariCP 连接池设置hikariConfig.setMaximumPoolSize(10);      // 最大连接数hikariConfig.setMinimumIdle(5);           // 最小空闲连接数hikariConfig.setConnectionTimeout(30000); // 连接超时(毫秒)hikariConfig.setIdleTimeout(600000);      // 空闲连接超时(毫秒)hikariConfig.setMaxLifetime(1800000);     // 最大连接生命周期(毫秒)return new HikariDataSource(hikariConfig);}@Beanpublic Engine engine() {return new Engine("V8");}@Beanpublic GPS gps() {return new GPSImpl();}@Beanpublic Radio radio() {return new RadioImpl();}@Beanpublic Car car() {Car car = new Car();car.setEngine(engine());car.setGps(gps());car.setRadio(radio());car.setDataSource(dataSource());return car;}
          }

    • 1.2 JdbcTemplate 的使用

      • JdbcTemplate 是 Spring 提供的简化数据库操作的工具类,能帮助我们避免繁琐的资源管理代码,如连接获取与关闭等。我们只需将 DataSource 注入到 JdbcTemplate 中即可。后面所有的演示就用HikariCP 连接池了

      • 1.2.1 DataSource 注入到 JdbcTemplate 基于xml方式
        • 演示的内容还是根据前面代码修改的哈

        • pom.xml

          •         <dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.9.RELEASE</version></dependency><!-- HikariCP 连接池依赖 --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>3.4.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency>
            
        • applicationContext.xml  原来是直接把dataSource 注入到car类中去 现在是先把dataSource 注入到jdbc 然后将jdbc注入car类中

          • <?xml version="1.0" encoding="UTF-8"?>
            <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd"><!--    applicationContext.xml 是 Spring 框架中的配置文件,通常用于定义 Spring IoC(控制反转)容器中的 Bean 配置和管理。这个文件主要用于将 Spring 的配置项和组件描述清楚,告知 Spring 容器如何实例化、配置和管理应用程序中的各种对象(Bean)。它是 Spring 配置的传统方式之一(除了注解和 Java 配置类)。--><!-- HikariCP 配置 --><bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"><!-- 设置数据库连接池配置 --><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/lirui?useSSL=false&amp;serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="root"/><!-- HikariCP 连接池相关参数 --><property name="maximumPoolSize" value="10"/> <!-- 最大连接数 --><property name="minimumIdle" value="5"/>     <!-- 最小空闲连接数 --><property name="connectionTimeout" value="30000"/> <!-- 连接超时(毫秒) --><property name="idleTimeout" value="600000"/> <!-- 空闲连接超时(毫秒) --><property name="maxLifetime" value="1800000"/> <!-- 连接最大生命周期(毫秒) --></bean><!-- 配置 Engine Bean,带参数构造函数 --><bean id="engine" class="com.lirui.car.Engine"><constructor-arg value="V8" /></bean><!-- 配置 GPS Bean --><bean id="gps" class="com.lirui.car.GPSImpl" /><!-- 配置 Radio Bean --><bean id="radio" class="com.lirui.car.RadioImpl" /><!-- 配置 Car Bean,使用 setter 注入 --><bean id="car" class="com.lirui.car.Car"><property name="engine" ref="engine" /><property name="gps" ref="gps" /><property name="radio" ref="radio" /><property name="jdbcTemplate" ref="jdbcTemplate" /></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><constructor-arg ref="dataSource" /></bean></beans>
            
        • 调用函数

          • package com.lirui.carconfig;import org.springframework.beans.factory.annotation.Autowired;import javax.sql.DataSource;
            import java.sql.Connection;
            import java.sql.PreparedStatement;
            import java.sql.ResultSet;
            import java.sql.SQLException;public class Car {private Engine engine;private GPS gps;private Radio radio;private DataSource dataSource;public void setEngine(Engine engine) {this.engine = engine;}public void setGps(GPS gps) {this.gps = gps;}public void setRadio(Radio radio) {this.radio = radio;}public void setDataSource(DataSource dataSource) {this.dataSource = dataSource;}public void drive() {// 使用 DataSource 获取数据库连接并执行查询String sql = "SELECT id, ui_path, menu_type FROM t_sys_resource";try (Connection connection = dataSource.getConnection();PreparedStatement statement = connection.prepareStatement(sql);ResultSet resultSet = statement.executeQuery()) {// 遍历查询结果while (resultSet.next()) {int id = resultSet.getInt("id");String name = resultSet.getString("ui_path");String email = resultSet.getString("menu_type");System.out.println("ID: " + id + ", ui_path: " + name + ", menu_type: " + email);}} catch (SQLException e) {e.printStackTrace();}System.out.println("引擎" + engine.getType());gps.navigate();radio.playMusic();}
            }
            
        • 主函数

          • package com.lirui.carconfig;import org.springframework.context.ApplicationContext;
            import org.springframework.context.annotation.AnnotationConfigApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {// 使用 Java 配置类来初始化 Spring 容器AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 获取 Car 实例,依赖项会自动注入Car car = context.getBean(Car.class);car.drive();context.close();}
            }
            
      • 1.2.2 DataSource 注入到 JdbcTemplate 基于配置类方式
        • 配置类
          • package com.lirui.carconfig;import com.zaxxer.hikari.HikariConfig;
            import com.zaxxer.hikari.HikariDataSource;
            import org.apache.commons.dbcp2.BasicDataSource;
            import org.springframework.beans.factory.annotation.Value;
            import org.springframework.context.annotation.*;
            import org.springframework.jdbc.core.JdbcTemplate;import javax.sql.DataSource;@Configuration
            @ComponentScan(basePackages = "com.lirui.carconfig")
            @PropertySource("classpath:application.properties")
            @EnableAspectJAutoProxy
            public class AppConfig {@Value("${db.url}")private String dbUrl;@Beanpublic DataSource dataSource() {HikariConfig hikariConfig = new HikariConfig();// 数据库连接信息hikariConfig.setDriverClassName("com.mysql.cj.jdbc.Driver");hikariConfig.setJdbcUrl("jdbc:mysql://localhost:3306/lirui?useSSL=false&serverTimezone=UTC");hikariConfig.setUsername("root");hikariConfig.setPassword("root");// HikariCP 连接池设置hikariConfig.setMaximumPoolSize(10);      // 最大连接数hikariConfig.setMinimumIdle(5);           // 最小空闲连接数hikariConfig.setConnectionTimeout(30000); // 连接超时(毫秒)hikariConfig.setIdleTimeout(600000);      // 空闲连接超时(毫秒)hikariConfig.setMaxLifetime(1800000);     // 最大连接生命周期(毫秒)return new HikariDataSource(hikariConfig);}@Beanpublic JdbcTemplate jdbcTemplate(DataSource dataSource) {return new JdbcTemplate(dataSource);  // 将 DataSource 注入 JdbcTemplate}@Beanpublic Engine engine() {return new Engine("V8");}@Beanpublic GPS gps() {return new GPSImpl();}@Beanpublic Radio radio() {return new RadioImpl();}@Beanpublic Car car() {Car car = new Car();car.setEngine(engine());car.setGps(gps());car.setRadio(radio());return car;}
            }
        • 主类
          • package com.lirui.carconfig;import org.springframework.context.ApplicationContext;
            import org.springframework.context.annotation.AnnotationConfigApplicationContext;
            import org.springframework.context.support.ClassPathXmlApplicationContext;public class Main {public static void main(String[] args) {// 使用 Java 配置类来初始化 Spring 容器AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 获取 Car 实例,依赖项会自动注入Car car = context.getBean(Car.class);car.drive();context.close();}
            }
            

        • 1.2.3 JdbcTemplate 基本操作  感觉了解就好 
          • 增、删、改操作
            • update(String sql):执行插入、更新或删除操作。
            • update(String sql, Object... args):带参数的增、删、改操作。
            • String sql = "INSERT INTO users (name, age) VALUES (?, ?)";
              jdbcTemplate.update(sql, "张三", 25);
              
          • 查询单个值
            • queryForObject(String sql, Class<T> requiredType):查询单个结果,例如获取记录总数。
            • queryForObject(String sql, Object[] args, Class<T> requiredType):带参数的查询单个值。
            • String sql = "SELECT COUNT(*) FROM users";
              int count = jdbcTemplate.queryForObject(sql, Integer.class);
              
          • 查询单行数据
            • queryForObject(String sql, RowMapper<T> rowMapper):查询并返回一行数据。
            • queryForObject(String sql, Object[] args, RowMapper<T> rowMapper):带参数的单行查询。
            • String sql = "SELECT * FROM users WHERE id = ?";
              User user = jdbcTemplate.queryForObject(sql, new Object[]{1}, new BeanPropertyRowMapper<>(User.class));
              
          • 查询多行数据
            • query(String sql, RowMapper<T> rowMapper):查询多行数据。
            • query(String sql, Object[] args, RowMapper<T> rowMapper):带参数的多行查询。
            • String sql = "SELECT * FROM users";
              List<User> users = jdbcTemplate.query(sql, new BeanPropertyRowMapper<>(User.class));
              
          • 批量更新
            • batchUpdate(String sql, List<Object[]> batchArgs):批量操作。
            • String sql = "INSERT INTO users (name, age) VALUES (?, ?)";
              List<Object[]> batchArgs = Arrays.asList(new Object[]{"张三", 28},new Object[]{"李四", 23},new Object[]{"王五", 29}
              );
              jdbcTemplate.batchUpdate(sql, batchArgs);
              
          • 事务管理
            • 在使用 JdbcTemplate 进行数据库操作时,Spring 的事务管理框架可以确保一组数据库操作要么全部成功,要么全部回滚。Spring 支持声明式事务管理,可以通过 @Transactional 注解来管理事务。
            • @Service
              public class UserService {@Autowiredprivate JdbcTemplate jdbcTemplate;@Transactionalpublic void createUser(User user) {String sql = "INSERT INTO users (name, age) VALUES (?, ?)";jdbcTemplate.update(sql, user.getName(), user.getAge());}
              }
    • 1.3 总结:

      • MySQL:关系型数据库,提供 JDBC 驱动程序让 Java 应用程序可以与它连接。

      • JDBC 驱动:MySQL 提供 com.mysql.cj.jdbc.Driver 驱动,让 Java 可以通过 JDBC 与 MySQL 进行交互。

      • 数据库连接池

        • DBCP2HikariCP 都是连接池实现,负责管理数据库连接。

        • 连接池的目的是提高性能,避免每次数据库操作都创建和销毁连接。

      • 优化

        • HikariCP:提供更高性能的连接池,减少连接获取和释放的延迟,是当前推荐的连接池。

        • DBCP2:是另一个常用的连接池,性能稍逊于 HikariCP,但依然可靠。

      • Spring JDBC

        • 提供简化的数据库操作,利用 JdbcTemplate 简化查询、插入等操作。

        • DBCP2HikariCP 配合使用,通过 DataSource 获取数据库连接池中的连接。

      • 关系:

        • MySQL → 提供数据库和 JDBC 驱动。

        • JDBC 驱动 → 让 Java 可以连接到 MySQL。

        • DBCP2 / HikariCP → 管理与 MySQL 的连接池,提高连接效率。

        • Spring JDBC → 通过 JdbcTemplate 简化与 MySQL 的数据库交互。

  • 2. Spring 与 ORM 框架

    • 2.1 ORM框架是什么

      • ORM 的基本概念

        • ORM 的核心思想是将对象模型与关系数据库的表结构映射在一起,使得数据库的操作能够像操作对象一样进行。通过 ORM,开发人员可以使用对象的属性(而非 SQL 查询语句)来进行增、删、改、查等操作。ORM 框架负责将对象的数据转换成 SQL 查询语句,并将查询结果映射回对象。

      • ORM 的工作原理

        • ORM 框架通过映射关系(通常称为映射配置)将数据库表的字段与 Java 对象的属性进行绑定。ORM 框架执行 CRUD(创建、读取、更新、删除)操作时,框架会自动生成相应的 SQL 语句并与数据库交互,然后将数据库中的数据映射回 Java 对象。

          例如,一个 User 类的 Java 对象,可能会映射到数据库中的 users 表。User 类中的每个字段(例如 idnameemail)都与表中的相应列进行关联。

      • ORM 的常见框架

        • MyBatis (会写接入 )

        • Hibernate

        • JPA (Java Persistence API)

    • 2.2 集成 MyBatis 

      • 基于xml 配置的方式 前提是你连接池可以连接上你数据库
      • 2.2.1 引入pom.xml
        • ​​​​​​​
          mybatis主要配置<dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.10</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.7</version></dependency><!-- 分隔 --><?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>com.lirui</groupId><artifactId>demo05</artifactId><version>1.0-SNAPSHOT</version><properties><maven.compiler.source>8</maven.compiler.source><maven.compiler.target>8</maven.compiler.target><project.build.sourceEncoding>UTF-8</project.build.sourceEncoding></properties><dependencies><!-- Spring Context --><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.10</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-aop</artifactId><version>5.3.10</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjrt</artifactId><version>1.9.8</version></dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.9.8</version></dependency><dependency><groupId>org.apache.commons</groupId><artifactId>commons-dbcp2</artifactId><version>2.9.0</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-jdbc</artifactId><version>5.0.9.RELEASE</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis</artifactId><version>3.5.10</version></dependency><dependency><groupId>org.mybatis</groupId><artifactId>mybatis-spring</artifactId><version>2.0.7</version></dependency><!-- HikariCP 连接池依赖 --><dependency><groupId>com.zaxxer</groupId><artifactId>HikariCP</artifactId><version>3.4.5</version></dependency><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.33</version></dependency><!-- Spring Beans --><dependency><groupId>org.springframework</groupId><artifactId>spring-beans</artifactId><version>5.3.10</version></dependency><dependency><groupId>org.springframework</groupId><artifactId>spring-context</artifactId><version>5.3.10</version></dependency></dependencies></project>
      • 2.2.2 编写配置文件​​​​​​​ applicationContext.xml
        • <?xml version="1.0" encoding="UTF-8"?>
          <beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"xmlns:tx="http://www.springframework.org/schema/tx"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/aop https://www.springframework.org/schema/aop/spring-aop.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd"><!--    applicationContext.xml 是 Spring 框架中的配置文件,通常用于定义 Spring IoC(控制反转)容器中的 Bean 配置和管理。这个文件主要用于将 Spring 的配置项和组件描述清楚,告知 Spring 容器如何实例化、配置和管理应用程序中的各种对象(Bean)。它是 Spring 配置的传统方式之一(除了注解和 Java 配置类)。--><!-- HikariCP 配置 --><bean id="dataSource" class="com.zaxxer.hikari.HikariDataSource"><!-- 设置数据库连接池配置 --><property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/><property name="jdbcUrl" value="jdbc:mysql://localhost:3306/lirui?useSSL=false&amp;serverTimezone=UTC"/><property name="username" value="root"/><property name="password" value="root"/><!-- HikariCP 连接池相关参数 --><property name="maximumPoolSize" value="10"/> <!-- 最大连接数 --><property name="minimumIdle" value="5"/>     <!-- 最小空闲连接数 --><property name="connectionTimeout" value="30000"/> <!-- 连接超时(毫秒) --><property name="idleTimeout" value="600000"/> <!-- 空闲连接超时(毫秒) --><property name="maxLifetime" value="1800000"/> <!-- 连接最大生命周期(毫秒) --></bean><!-- SqlSessionFactory配置 --><bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"><!-- 将 HikariCP 数据源注入到 SqlSessionFactoryBean --><property name="dataSource" ref="dataSource"/><!-- 将 MyBatis 的 Mapper XML 文件路径注入到 SqlSessionFactoryBean --><property name="mapperLocations" value="classpath:mapper/*.xml"/></bean><!-- Mapper扫描  把你包下面的接口 注入--><bean class="org.mybatis.spring.mapper.MapperScannerConfigurer"><property name="basePackage" value="com.lirui.demoMybatis"/></bean><!-- 提供事务管理 --><bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/></bean><!-- 配置事务注解 --><tx:annotation-driven transaction-manager="transactionManager"/><!-- 配置 Engine Bean,带参数构造函数 --><bean id="engine" class="com.lirui.car.Engine"><constructor-arg value="V8"/></bean><!-- 配置 GPS Bean --><bean id="gps" class="com.lirui.car.GPSImpl"/><!-- 配置 Radio Bean --><bean id="radio" class="com.lirui.car.RadioImpl"/><!-- 配置 Car Bean,使用 setter 注入 --><bean id="car" class="com.lirui.car.Car"><property name="engine" ref="engine"/><property name="gps" ref="gps"/><property name="radio" ref="radio"/><property name="jdbcTemplate" ref="jdbcTemplate"/></bean><bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate"><constructor-arg ref="dataSource"/></bean></beans>
          
      • 2.2.3 编写实体类
        • package com.lirui.demoMybatis.dao;public class User {private int id;private String name;private String email;// 默认构造方法public User() {}// 带参构造方法public User(int id, String name, String email) {this.id = id;this.name = name;this.email = email;}// Getter 和 Setter 方法public int getId() {return id;}public void setId(int id) {this.id = id;}public String getName() {return name;}public void setName(String name) {this.name = name;}public String getEmail() {return email;}public void setEmail(String email) {this.email = email;}// toString 方法@Overridepublic String toString() {return "User{" +"id=" + id +", name='" + name + '\'' +", email='" + email + '\'' +'}';}
          }
          
      • 2.2.4 编写mapper接口
        • package com.lirui.demoMybatis;import com.lirui.demoMybatis.dao.User;import java.util.List;public interface UserMapper {List<User> findAllUsers();User findUserById(int id);void insertUser(User user);void updateUser(User user);void deleteUser(int id);
          }
          
      • 2.2.5 编写mapper.xml
        • <?xml version="1.0" encoding="UTF-8" ?>
          <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
          <mapper namespace="com.lirui.demoMybatis.UserMapper"><!-- 查询所有用户 --><select id="findAllUsers" resultType="com.lirui.demoMybatis.dao.User">SELECT id, name, emailFROM users</select><!-- 根据 ID 查询用户 --><select id="findUserById" parameterType="int" resultType="com.lirui.demoMybatis.dao.User">SELECT id, name, emailFROM usersWHERE id = #{id}</select><!-- 插入一个用户 --><insert id="insertUser" parameterType="com.lirui.demoMybatis.dao.User">INSERT INTO users (name, email)VALUES (#{name}, #{email})</insert><!-- 更新用户信息 --><update id="updateUser" parameterType="com.lirui.demoMybatis.dao.User">UPDATE usersSET name = #{name}, email = #{email}WHERE id = #{id}</update><!-- 删除用户 --><delete id="deleteUser" parameterType="int">DELETE FROM users WHERE id = #{id}</delete></mapper>
          
      • 2.2.6 在使用的类 注入mapper类
        • 前提是在配置文件中 路径正确 能扫描到
        • package com.lirui.car;import com.lirui.demoMybatis.UserMapper;
          import com.lirui.demoMybatis.dao.User;
          import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.jdbc.core.BeanPropertyRowMapper;
          import org.springframework.jdbc.core.JdbcTemplate;import javax.sql.DataSource;
          import java.sql.Connection;
          import java.sql.PreparedStatement;
          import java.sql.ResultSet;
          import java.sql.SQLException;
          import java.util.List;
          import java.util.Map;public class Car {private Engine engine;private GPS gps;private Radio radio;private JdbcTemplate jdbcTemplate;@Autowiredprivate UserMapper userMapper;// Setters for dependency injectionpublic void setEngine(Engine engine) {this.engine = engine;}public void setGps(GPS gps) {this.gps = gps;}public void setRadio(Radio radio) {this.radio = radio;}public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {this.jdbcTemplate = jdbcTemplate;}public void drive() {List<User> allUsers = userMapper.findAllUsers();for (User allUser : allUsers) {System.out.println(allUser.getEmail());}System.out.println("引擎"+engine.getType() );gps.navigate();radio.playMusic();}
          }
          
      • 2.2.7 主函数调用
  • 3. 事务管理

    • 3.1 事务管理的基础概念

      • ​​​​​​​​​​​​​​事务是数据库管理系统中的一组操作,这些操作要么完全成功,要么完全失败。事务的基本特性(ACID)包括:

        • 原子性 (Atomicity):事务中的所有操作要么全部完成,要么全部不做。

        • 一致性 (Consistency):事务的执行必须将数据库从一种一致性状态转移到另一种一致性状态。

        • 隔离性 (Isolation):并发执行的事务之间应该相互隔离,事务的执行不应该受到其他事务的影响。

        • 持久性 (Durability):事务一旦提交,它对数据库的修改应该是永久性的。

      • 在 Spring 中,事务管理分为两种方式:

        • 声明式事务管理(使用 @Transactional 注解)

        • 编程式事务管理(通过 TransactionTemplateTransactionManager

    • 3.2 声明式事务管理(@Transactional)

      • ​​​​​​​​​​​​​​声明式事务管理是通过 AOP(面向切面编程)来管理事务。Spring 提供了 @Transactional 注解来简化事务管理。通过这种方式,不需要手动管理事务的开始、提交、回滚等,而是由 Spring 容器自动处理。
      • 使用 @Transactional 注解
        • 基础配置
          • 确保你的 Spring 配置文件中启用了事务管理。你可以在 applicationContext.xml 中添加如下配置:
          • <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"><property name="dataSource" ref="dataSource"/>
            </bean><tx:annotation-driven transaction-manager="transactionManager"/>
            
          • tx:annotation-driven 告诉 Spring 容器启用基于注解的事务管理。
        • 在方法中使用 @Transactional
          • 在需要事务管理的方法上使用 @Transactional 注解,Spring 会自动处理该方法的事务。
          • ​​​​​​​​​​​​​​
            import org.springframework.stereotype.Service;
            import org.springframework.transaction.annotation.Transactional;@Service
            public class UserService {@Transactionalpublic void createUser(User user) {// 开始事务userDao.save(user); // 执行数据库操作// 如果发生异常,会自动回滚事务}
            }
            
        • 事务传播行为
          • @Transactional 注解有多个属性可以配置事务的行为,最常用的属性包括:

            • propagation:事务传播行为,表示当前事务如何与已有事务交互。常见值有:

              • REQUIRED(默认值):如果当前方法存在事务,则加入该事务,否则创建一个新事务。

              • REQUIRES_NEW:无论当前是否存在事务,都会新开一个事务。

              • SUPPORTS:如果当前方法存在事务,则使用该事务,否则以非事务方式执行。

            • isolation:事务隔离级别,表示事务对其他事务的可见性。常见值有:

              • READ_COMMITTED:读取已提交的数据。

              • READ_UNCOMMITTED:读取未提交的数据。

              • REPEATABLE_READ:确保事务在执行过程中读取到的数据始终一致。

              • SERIALIZABLE:最高的隔离级别,事务间完全隔离。

            • timeout:事务的超时时间,超过指定时间,事务会自动回滚。

            • rollbackFor:指定哪些异常会触发事务回滚。

            • @Transactional(propagation = Propagation.REQUIRED, isolation = Isolation.READ_COMMITTED, rollbackFor = Exception.class)
              public void someMethod() {// 事务逻辑
              }
              
        • 回滚设置
          • 默认情况下,Spring 只会在遇到运行时异常(RuntimeException)时回滚事务。如果你希望指定的异常也回滚事务,可以通过 rollbackFornoRollbackFor 属性来指定:
          • @Transactional(rollbackFor = {SQLException.class, IOException.class})
            public void someMethod() {// 如果发生 SQLException 或 IOException,将会回滚事务
            }
            
    • 3.3 编程式事务管理

      • ​​​​​​​编程式事务管理是指在代码中手动控制事务的开始、提交和回滚。Spring 提供了 TransactionTemplatePlatformTransactionManager 来实现编程式事务管理。
      •  使用 TransactionTemplate
        • TransactionTemplate 是一种简化编程式事务管理的方式,利用它可以不需要显式地控制事务的提交和回滚。
        • import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.stereotype.Service;
          import org.springframework.transaction.PlatformTransactionManager;
          import org.springframework.transaction.TransactionStatus;
          import org.springframework.transaction.support.TransactionCallback;
          import org.springframework.transaction.support.TransactionTemplate;@Service
          public class UserService {@Autowiredprivate PlatformTransactionManager transactionManager;@Autowiredprivate UserDao userDao;public void createUser(User user) {TransactionTemplate transactionTemplate = new TransactionTemplate(transactionManager);transactionTemplate.execute(new TransactionCallback<Void>() {@Overridepublic Void doInTransaction(TransactionStatus status) {try {userDao.save(user); // 执行数据库操作} catch (Exception e) {status.setRollbackOnly(); // 异常时标记事务回滚throw e;}return null;}});}
          }
          
      • 使用 PlatformTransactionManagerTransactionStatus

        • ​​​​​​​如果希望有更多的控制权,也可以直接使用 PlatformTransactionManager 来手动管理事务。

        • import org.springframework.beans.factory.annotation.Autowired;
          import org.springframework.stereotype.Service;
          import org.springframework.transaction.PlatformTransactionManager;
          import org.springframework.transaction.TransactionStatus;
          import org.springframework.transaction.support.DefaultTransactionDefinition;@Service
          public class UserService {@Autowiredprivate PlatformTransactionManager transactionManager;@Autowiredprivate UserDao userDao;public void createUser(User user) {// 创建事务定义DefaultTransactionDefinition def = new DefaultTransactionDefinition();def.setIsolationLevel(DefaultTransactionDefinition.ISOLATION_READ_COMMITTED);def.setPropagationBehavior(DefaultTransactionDefinition.PROPAGATION_REQUIRED);// 开始事务TransactionStatus status = transactionManager.getTransaction(def);try {userDao.save(user); // 执行数据库操作transactionManager.commit(status); // 提交事务} catch (Exception e) {transactionManager.rollback(status); // 回滚事务throw e;}}
          }
          

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

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

相关文章

uniApp之uni-file-picker使用踩坑

标题党~也不算坑吧 就是初体验 上传是需要存储一下子的&#xff0c;我以为uniApp是自己免费开的服务给大家中转使用&#xff0c;就没管这个事&#xff0c;但是官网是这么说的&#xff1a; 就我是怎么发现的&#xff0c;使用了一段时间后&#xff0c;上传的图片都裂了&#xff…

开源竞争-大数据项目期末考核

开源竞争&#xff1a; 自己没有办法完全掌握技术的时候就开源这个技术&#xff0c;培养出更多的技术依赖&#xff0c;让更多人完善你的技术&#xff0c;那么这不就是在砸罐子吗&#xff1f;一个行业里面总会有人砸罐子的&#xff0c;你不如先砸还能听个想。 客观现实&#xf…

Flutter3.22.2中SliverAppBar设置背景色滑动显示颜色错误

在使用Flutter项目开发中&#xff0c;可能会有页面需要滑动收起标题栏的效果&#xff0c;一般都会使用SliverAppBar来实现&#xff0c;当项目的Flutter的SDK版本升级到3.4后&#xff0c;发现使用了SliverAppBar的页面&#xff0c;在滑动过程中&#xff0c;标题栏和状态栏的颜色…

SpringBoot3中swagger无法使用

前言 springboot 3开始javax包改成了jakarta&#xff0c;而swagger-oas等包中依然使用的是javax&#xff0c;所以报错。另外springfox已经停止更新有段时间了&#xff0c;并且不支持OpenAPI 3标准&#xff0c;升级Springboot 3.0以后会有更多问题暴露出来。而SpringBoot 3只支…

使用docker安装zlmediakit服务(zlm)

zlmediakit安装 zlmediakit安装需要依赖环境和系统配置&#xff0c;所以采用docker的方式来安装不容易出错。 docker pull拉取镜像(最新) docker pull zlmediakit/zlmediakit:master然后先运行起来 sudo docker run -d -p 1935:1935 -p 80:80 -p 8554:554 -p 10000:10000 -p …

第九周预习报告

文章目录 密码系统设计第九周预习报告学习内容AI 对学习内容的总结&#xff08;1分&#xff09;要求总结 对 AI 总结的反思与补充&#xff08;2分&#xff09;反思与补充 补充内容反思学习思维导图&#xff08;2分&#xff09;要求思维导图代码导图 基于 AI 的学习&#xff08;…

GB/T 43206—2023信息安全技术信息系统密码应用测评要求(五)

文章目录 附录AA.1 概述A.2 密钥产生A.3 密钥分发A.4 密钥存储A.5 密钥使用A.6 密钥更新A.7 密钥归档A. 8 密钥撤销A.9 密钥备份A.10 密钥恢复A.11 密钥销毁 附录B附录C 附录A A.1 概述 密钥管理对于保证密钥全生存周期的安全性至关重要 ,可以保证密钥(除公开密钥外) 不被非授…

phpstudy 使用php8.2.9版本报错问题

phpstudy 使用php8.2.9版本报错问题 1、如果php8的扩展控制面板开启无效的话&#xff0c;可以手动开启试试 2、php有报错日志&#xff1a; Fatal error: Directive ‘track_errors’ is no longer available in PHP in Unknown on line 0 在切换php版本到更高版本时在终端查…

【科普小白】LLM大语言模型的基本原理

一、要了解LLM大模型的基本原理就要先来了解一下自然语言处理&#xff08;NLP&#xff09;。 NLP 是 AI 的一个子领域&#xff0c;专注于使计算机能够处理、解释和生成人类语言&#xff0c;主要任务包括&#xff1a;文本分类、自动翻译、问题回答、生成文本等。到底是NLP促生了…

初识网络编程TCP/IP

目录 前言相关名词解释应用层协议——HTTP传输层协议socketTCP帧头格式三次握手、四次挥手 UDPTCP的socket实现 参考博文 前言 刚碰到网络编程&#xff0c;会出现一堆协议、概念、这层次那技术的&#xff0c;头都大了&#xff0c;还是得总结总结…… 相关名词解释 ✨✨网络…

整合本地市场机会 同城小程序打造社区商圈

同城市场中&#xff0c;商家与消费者之间的互动和交易模式正在发生深刻变化&#xff0c;同城小程序成为了企业、商户和消费者之间连接的桥梁&#xff0c;成为打造社区商圈、整合本地市场机会的重要工具。今天小编分享&#xff0c;同城小程序怎么一个软件整合以前十几个APP做的事…

安当ASP系统:适合中小企业的轻量级Radius认证服务器

安当ASP&#xff08;Authentication Service Platform&#xff09;身份认证系统是一款功能强大的身份认证服务平台&#xff0c;特别适用于中小企业。其中&#xff0c;简约型Radius认证服务器是安当ASP系统中的一个重要组成部分。以下是对该系统的详细介绍&#xff1a; 一、主要…

(一)<江科大STM32>——软件环境搭建+新建工程步骤

一、软件环境搭建 &#xff08;1&#xff09;安装 Keil5 MDK 文件路径&#xff1a;江科大stm32入门教程资料/Keil5 MDK/MDK524a.EXE&#xff0c;安装即可&#xff0c;路径不能有中文。 &#xff08;2&#xff09;安装器件支持包 文件路径&#xff1a;江科大stm32入门教程资料…

面试经典 150 题:121,125

121. 买卖股票的最佳时机 【参考代码】 动态规划解决 class Solution { public:int maxProfit(vector<int>& prices) {int size prices.size();int min_price 99999, max_profit 0;for(int i0; i<size; i){if(prices[i] < min_price){min_price prices[i…

Spring boot 读模块项目升级为spring cloud 项目步骤以及问题

1.结构说明 bean 模块 &#xff0c;public 模块&#xff0c; client 模块&#xff0c; erp模块&#xff0c;system 主模块。 2.环境说明以及pom 原本环境 新环境 mysql 5.7 -------------- mysql 8.0 maven 3.9.6 jdk 8 -----------…

Linux系统-初始化

作者介绍&#xff1a;简历上没有一个精通的运维工程师。希望大家多多关注作者&#xff0c;下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 这是Linux进阶部分的最后一大章。讲完这一章以后&#xff0c;我们Linux进阶部分讲完以后&#xff0c;我们的Linux操作部分就…

element-plus的Tree 树形控件添加图标

该文章为本菜鸡学习记录&#xff0c;如有错误还请大佬指教 本人刚开始接触vue框架&#xff0c;在使用element-plus组件想实现树形控件&#xff0c;发现官网的组件示例没有图标区分显示 实现效果 代码 <temple 部分 <el-tree :data"data" node-click"hand…

【详细 工程向】基于Smart3D的五镜头相机三维重建

数据部分&#xff1a; 数据要求 &#xff08;1&#xff09;每条行带至少从 3 个不同的视角进行拍摄。 &#xff08;2&#xff09;相邻相片之间的重叠度通常要求大于三分之二。 &#xff08;3&#xff09;不同拍摄视角之间夹角应该少于 15 度。 &#xff08;4&#xff09;通…

pdf转excel;pdf中表格提取

一、问题描述 在工作中或多或少会遇到&#xff1a;需要将某份pdf中的表格数据提取出来&#xff0c;以便能够“修改使用”数据 可将pdf中的表格提取出来&#xff0c;解决办法还有点复杂 尤其涉及“pdf中表格不是标准的单元格”的时候&#xff0c;提取数据到excel不太容易 比…

mean_x2 = (x**2).mean(dim=dims, keepdims=True)

这行代码的作用是计算输入张量 x 在指定维度上的平方均值&#xff0c;并保持原始维度的形状。具体来说&#xff1a; mean_x2 (x**2).mean(dimdims, keepdimsTrue) # [b,1,1] 参数解释 x**2&#xff1a;对输入张量 x 的每个元素进行平方运算。.mean(dimdims, keepdimsTrue)…