zoukankan      html  css  js  c++  java
  • SpringBoot【三】 整合 JDBC、Druid、MyBatis

    Spring Data

    对于数据访问层,无论是 SQL(关系型数据库)还是 NOSQL(非关系型数据库),Spring Boot 底层都是采用 Spring Data 的方式进行统一处理。

    Spring Data 也是 Spring 中与 Spring Boot、Spring Cloud 等齐名的知名项目。

    Sping Data 官网:https://spring.io/projects/spring-data

    数据库相关的启动器:https://docs.spring.io/spring-boot/docs/2.3.1.RELEASE/reference/htmlsingle/#using-boot-starter

    整合 JDBC

    1. 创建测试项目,引入【Web】 Spring Web、【SQL】JDBC API、MySQL Driver 依赖

    2. 项目建好之后,已经自动帮我们导入了如下的启动器:

      <!--web-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-web</artifactId>
      </dependency>
      <!--JDBC-->
      <dependency>
         <groupId>org.springframework.boot</groupId>
         <artifactId>spring-boot-starter-jdbc</artifactId>
      </dependency>
      <!--MySQL-->
      <dependency>
         <groupId>mysql</groupId>
         <artifactId>mysql-connector-java</artifactId>
         <scope>runtime</scope>
      </dependency>
      
    3. 编写 yaml 配置文件连接数据库

      spring:
        datasource:
          username: root
          password: root
          # 假如时区报错了,就增加一个时区的配置 serverTimezone=UTC
          url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
       	driver-class-name: com.mysql.jdbc.Driver
      
    4. 配置完这些就可以直接使用了,因为 SpringBoot 已经默认帮我们进行了自动配置,测试类测试

      @SpringBootTest
      class Springboot04DataApplicationTests {
      
         @Autowired //DI注入数据源
         DataSource dataSource;
          
         @Test
         void contextLoads() throws SQLException{
            // 查看默认的数据源 class com.zaxxer.hikari.HikariDataSource
            System.out.println(dataSource.getClass());
            // 获得数据库连接
            Connection connection = dataSource.getConnection();
            System.out.println(connection);
            // 关闭连接
            connection.close();
         }
      }
      
    5. 结果:默认配置的数据源为 : class com.zaxxer.hikari.HikariDataSource

    数据源配置分析:

    数据源的所有自动配置都在 :DataSourceAutoConfiguration

    @Import({ DataSourceConfiguration.Hikari.class, 	
             DataSourceConfiguration.Tomcat.class,
             DataSourceConfiguration.Dbcp2.class, 
             DataSourceConfiguration.Generic.class,
             DataSourceJmxConfiguration.class })
    protected static class PooledDataSourceConfiguration {
    }
    

    这里导入的类都在 DataSourceConfiguration 中,默认使用 HikariDataSource 数据源,而以前版本,如 SpringBoot 1.5 默认使用 org.apache.tomcat.jdbc.pool.DataSource 作为数据源。

    可以使用 spring.datasource.type 指定自定义的数据源类型,值为要使用的连接池实现的完全限定名。

    HikariDataSource 号称 Java WEB 当前速度最快的数据源,相比于传统的 C3P0 、DBCP、Tomcat jdbc 等连接池更加优秀。

    JdbcTemplate

    • 有了数据源(com.zaxxer.hikari.HikariDataSource),就拿到数据库连接(java.sql.Connection),有了连接,就可以使用原生的 JDBC 语句来操作数据库;
    • 即使不使用第三方第数据库操作框架如 MyBatis 等,Spring 本身也对原生的 JDBC 做了轻量级的封装,即JdbcTemplate。
    • 数据库操作的所有 CRUD 方法都在 JdbcTemplate 中。
    • Spring Boot 不仅提供了默认的数据源,同时默认已经配置好了 JdbcTemplate 放在了容器中,只需注入即可使用。
    • JdbcTemplate 的自动配置是依赖 org.springframework.boot.autoconfigure.jdbc 包下的 JdbcTemplateConfiguration

    JdbcTemplate 主要提供的几类方法:

    • execute 方法:可以用于执行任何 SQL 语句,一般用于执行 DDL 语句;
    • update 方法及 batchUpdate 方法:update 方法用于执行新增、修改、删除等语句;batchUpdate 方法用于执行批处理相关语句;
    • query 方法及 queryForXXX 方法:用于执行查询相关语句;
    • call 方法:用于执行存储过程、函数相关语句。

    CRUD 操作:编写一个 Controller 类,注入 jdbcTemplate,编写测试方法进行访问测试

    @RestController
    public class JDBCController {
        
    	/**
         * Spring Boot 默认提供了数据源,默认提供了 org.springframework.jdbc.core.JdbcTemplate
         * JdbcTemplate 中会自己注入数据源,用于简化 JDBC操作
         * 还能避免一些常见的错误,使用起来也不用再自己来关闭数据库连接
         */
        @Autowired
        JdbcTemplate jdbcTemplate;
    
        //查询数据库所有信息
        // 没有实体类,数据库中的东西怎么获取?map
        // List 中的1个 Map 对应数据库的 1行数据
        // Map 中的 key 对应数据库的字段名,value 对应数据库的字段值
        @GetMapping("/userList")
        public List<Map<String, Object>> userList(){
            String sql = "select * from user";
            List<Map<String, Object>> maps = jdbcTemplate.queryForList(sql);
            return maps;
        }
    
        @GetMapping("/addUser")
        public String addList(){
            String sql = "insert into mybatis.user(id, name, pwd) VALUES (4,'赵六','123456')";
            jdbcTemplate.update(sql);
            return "add-ok";
        }
    
    
        @GetMapping("/updateUser/{id}")
        public String updateList(@PathVariable("id") int id){
            String sql = "update mybatis.user set name=?, pwd=? where id="+id;
            //封装
            Object[] objects = new Object[2];
            objects[0] = "xiaoming";
            objects[1] = "0000";
            jdbcTemplate.update(sql,objects);
            return "update-ok";
        }
    
        @GetMapping("/deleteUser/{id}")
        public String deleteList(@PathVariable("id") int id){
            String sql = "delete from mybatis.user where id=?";
            jdbcTemplate.update(sql, id);
            return "delete-ok";
        }
    }
    

    整合 Druid

    1、配置 Druid

    1. 添加 Druid 数据源依赖

      <!-- Druid -->
      <dependency>
         <groupId>com.alibaba</groupId>
         <artifactId>druid</artifactId>
         <version>1.1.21</version>
      </dependency>
      
    2. 切换数据源:通过 spring.datasource.type 指定数据源

      spring:
        datasource:
          username: root
          password: root
          url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
          driver-class-name: com.mysql.jdbc.Driver
          # 自定义数据源
          type: com.alibaba.druid.pool.DruidDataSource
      
    3. 数据源切换之后,在测试类中注入 DataSource,获取并输出,输出结果为 class com.alibaba.druid.pool.DruidDataSource,说明切换成功

    4. 切换成功之后,就可以设置数据源连接初始化大小、最大连接数、等待时间、最小连接数等设置项,可以查看源码

      spring:
        datasource:
          username: root
          password: root
          url: jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
          driver-class-name: com.mysql.jdbc.Driver
          # 自定义数据源
          type: com.alibaba.druid.pool.DruidDataSource
      
          #Spring Boot 默认是不注入这些属性值的,需要自己绑定
          #druid 数据源专有配置
          initialSize: 5
          minIdle: 5
          maxActive: 20
          maxWait: 60000
          timeBetweenEvictionRunsMillis: 60000
          minEvictableIdleTimeMillis: 300000
          validationQuery: SELECT 1 FROM DUAL
          testWhileIdle: true
          testOnBorrow: false
          testOnReturn: false
          poolPreparedStatements: true
      
          #配置监控统计拦截的filters,stat:监控统计、log4j:日志记录、wall:防御sql注入
          #如果允许时报错  java.lang.ClassNotFoundException: org.apache.log4j.Priority
          #则导入 log4j 依赖即可,Maven 地址:https://mvnrepository.com/artifact/log4j/log4j
          filters: stat,wall,log4j
          maxPoolPreparedStatementPerConnectionSize: 20
          useGlobalDataSourceStat: true
          connectionProperties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=500
      
    5. 导入 Log4j 的依赖

      <dependency>
         <groupId>log4j</groupId>
         <artifactId>log4j</artifactId>
         <version>1.2.17</version>
      </dependency>
      
    6. 需要手动为 DruidDataSource 绑定全局配置文件中的参数,再添加到容器中,而不再使用 Spring Boot 的自动生成,新建一个配置类 DruidConfig.class

      @Configuration
      public class DruidConfig {
          /*
             将自定义的 Druid数据源添加到容器中,不再让 Spring Boot 自动创建
             @ConfigurationProperties(prefix = "spring.datasource"):作用就是将全局配置文件中前缀为 spring.datasource 的属性值注入到 com.alibaba.druid.pool.DruidDataSource 的同名参数中
           */
          @ConfigurationProperties(prefix = "spring.datasource")
          @Bean 
          public DataSource duridDataSource(){
              return new DruidDataSource();
          }
      }
      
    7. 测试

      @SpringBootTestclass 
      SpringbootDataJdbcApplicationTests {
          //DI注入数据源    
          @Autowired    
          DataSource dataSource;
          @Test    
          public void contextLoads() throws SQLException {        
              //看一下默认数据源        
              System.out.println(dataSource.getClass());        
              //获得连接        
              Connection connection =   dataSource.getConnection();        		
              System.out.println(connection);
              DruidDataSource druidDataSource = (DruidDataSource) dataSource;        	
              System.out.println("druidDataSource 数据源最大连接数:" + druidDataSource.getMaxActive());        
              System.out.println("druidDataSource 数据源初始化连接数:" + druidDataSource.getInitialSize());
              //关闭连接        
              connection.close();    
          }
      }
      
    8. 输出设置的参数,说明配置生效

    2、配置 Druid 数据源监控

    Druid 数据源具有监控的功能,并提供了一个 web 界面方便用户查看,类似安装路由器时,人家也提供了一个默认的 web 页面。

    需要设置 Druid 的后台管理页面,比如登录账号、密码等配置,浏览器访问 :http://localhost:8080/druid/login.html,输入设置的账号和密码即可查看

    @Configuration
    public class DruidConfig {
    
        @ConfigurationProperties(prefix = "spring.datasource")
        @Bean
        public DataSource duridDataSource(){
            return new DruidDataSource();
        }
    
        // 配置 Druid 监控管理后台的Servlet
        // 后台监控功能:web.xml,ServletRegistrationBean
        // 因为SpringBoot内置了servlet容器,所以没有web.xml,替代方法:ServletRegistrationBean
        @Bean
        public ServletRegistrationBean statViewServlet(){
            ServletRegistrationBean<StatViewServlet> bean = new ServletRegistrationBean<>(new StatViewServlet(), "/druid/*");
            // 后台需要有人登陆,账号密码设置
            HashMap<String, String> initParameters = new HashMap<>();
            // 增加配置,这些参数可以在 com.alibaba.druid.support.http.StatViewServlet 
            // 的父类 com.alibaba.druid.support.http.ResourceServlet 中找到
            // 登陆的key是固定的loginUsername、loginPassword
            initParameters.put("loginUsername", "admin");
            initParameters.put("loginPassword", "123456");
    
            // 允许谁可以访问,为空或者为null时,表示允许所有访问
            initParameters.put("allow", "");
            // 禁止谁能访问 initParameters.put("deny", "");
    
            bean.setInitParameters(initParameters);//设置初始化参数
            return bean;
        }
    

    3、配置 Druid web 监控 filter 过滤器

    // web 监控的 filter
    // WebStatFilter:用于配置 web和Druid数据源之间的管理关联监控统计
    @Bean
    public FilterRegistrationBean webStatFilter(){
        FilterRegistrationBean bean = new FilterRegistrationBean();
    
        bean.setFilter(new WebStatFilter());
        // 可以过滤哪些请求
        Map<String, String> initParamters = new HashMap<>();
        //exclusions:设置哪些请求进行过滤排除掉,这些东西不进行统计,
        initParamters.put("exclusions", "*.js,*.css,/druid/*");
        bean.setInitParameters(initParamters);
        
        //"/*" 表示过滤所有请求
        bean.setUrlPatterns(Arrays.asList("/*"));
        return bean;
    }
    

    整合 MyBatis

    官方文档:http://mybatis.org/spring-boot-starter/mybatis-spring-boot-autoconfigure/dependency-info.html

    1. 创建测试项目,引入【Web】 Spring Web、【SQL】JDBC API、MySQL Driver 依赖

    2. 导入 MyBatis 所需要的依赖

      <!-- mybatis-spring-boot-starter:整合 -->
      <dependency>
         <groupId>org.mybatis.spring.boot</groupId>
         <artifactId>mybatis-spring-boot-starter</artifactId>
         <version>2.1.1</version>
      </dependency>
      
    3. 配置数据库连接信息

      spring.datasource.username=root
      spring.datasource.password=root
      spring.datasource.url=jdbc:mysql://localhost:3306/mybatis?serverTimezone=UTC&useUnicode=true&characterEncoding=utf-8
      spring.datasource.driver-class-name=com.mysql.cj.jdbc.NonRegisteringDriver
      
      # 整合 MyBatis
      mybatis.type-aliases-package=com.song.pojo
      mybatis.mapper-locations=classpath:mybatis/mapper/*.xml
      
    4. 测试数据库是否连接成功

      @SpringBootTest
      class Springboot05MybatisApplicationTests {
      
         @Autowired
         DataSource dataSource;
      
         @Test
         void contextLoads() throws SQLException {
            System.out.println(dataSource.getClass());
            System.out.println(dataSource.getConnection());
         }
      }
      
    5. 创建实体类 User,导入 Lombok

      @Data
      @AllArgsConstructor
      @NoArgsConstructor
      public class User {
          private int id;
          private String name;
          private String pwd;
      }
      
    6. 创建 mapper 目录以及对应的 Mapper 接口 UserMapper.class

      // 这个注解表示这是一个 mybatis 的 mapper类 dao
      @Mapper
      @Repository
      public interface UserMapper {
      
          List<User> queryUserList();
      
          User queryUserById();
      
          int addUser(User user);
      
          int UpdateUser(User user);
      
          int deleteUser(int id);
      }
      
    7. 对应的 Mapper 映射文件 UserMapper.xml(在 resources/mybatis/mapper 目录下,如果在 java 目录下需要配置静态资源过滤)

      <?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.song.mapper.UserMapper">
      
          <select id="queryUserList" resultType="User">
              select * from User
          </select>
      
          <select id="queryUserById" resultType="User">
              select * from User where id = #{id}
          </select>
      
          <insert id="addUser" parameterType="User">
              insert into mybatis.user (id, name, pwd) values (#{id},#{name},#{pwd})
          </insert>
      
          <update id="UpdateUser" parameterType="User">
              update mybatis.user set name=#{name},pwd=#{pwd} where id=#{id}
          </update>
      
          <delete id="deleteUser" parameterType="int">
              delete from mybatis.user where id=#{id};
          </delete>
      
      </mapper>
      
    8. maven 配置资源过滤问题(当 UserMapper.xml 和 UserMapper.class 在同一个目录时需要配置)

      <resources>    
          <resource>        
              <directory>src/main/java</directory>        
              <includes>            
                  <include>**/*.xml</include>        
              </includes>        
              <filtering>true</filtering>    
          </resource>
      </resources>
      
    9. 编写 UserController 进行测试!

      @RestController
      public class UserController {
          @Autowired
          private UserMapper userMapper;
      
          @GetMapping("/queryUserList")
          public List<User> queryUserList(){
              List<User> userList = userMapper.queryUserList();
              for (User user: userList) {
                  System.out.println(user);
              }
              return userList;
          }
          
          //...增删改方法
      }
      
    10. 启动项目访问进行测试

  • 相关阅读:
    Spring bean
    spring bean初始化及销毁你必须要掌握的回调方法
    一张图搞懂Spring bean的完整生命周期
    获取Spring的ApplicationContext的几种方式
    你必须了解Spring的生态
    Spring的核心模块解析
    Spring 5.0
    纯分享scp协议如何工作
    我眼中的SAML (Security Assertion Markup Language)
    7z文件格式及其源码的分析(五)
  • 原文地址:https://www.cnblogs.com/Songzw/p/13276854.html
Copyright © 2011-2022 走看看