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. 启动项目访问进行测试

原文地址:https://www.cnblogs.com/Songzw/p/13276854.html