zoukankan      html  css  js  c++  java
  • MyBatis初级实战之三:springboot集成druid

    OpenWrite版:

    欢迎访问我的GitHub

    https://github.com/zq2599/blog_demos

    内容:所有原创文章分类汇总及配套源码,涉及Java、Docker、Kubernetes、DevOPS等;

    本文是《MyBatis初级实战》系列的第三篇,我们将实战springboot、mybatis、druid的集成,并验证;

    关于druid

    1. Druid是数据库连接池,并且能够提供强大的监控和扩展功能;
    2. 官方GitHub地址:https://github.com/alibaba/druid
    3. 本次集成使用了durid官方的starter,名为druid-spring-boot-starter,版本1.1.17,对应druid版本是1.1.17

    本篇概览

    本文由以下内容组成:

    1. 新建springboot工程,里面有详细的集成druid的操作;
    2. 编写和执行单元测试代码,并规避一个由集成druid带来的问题;
    3. 启动springboot应用,通过swagger验证基本功能正常;
    4. 通过断点,确认使用了druid连接池;
    5. 体验druid提供的监控页面;

    源码下载

    1. 如果您不想编码,可以在GitHub下载所有源码,地址和链接信息如下表所示(https://github.com/zq2599/blog_demos):
    名称 链接 备注
    项目主页 https://github.com/zq2599/blog_demos 该项目在GitHub上的主页
    git仓库地址(https) https://github.com/zq2599/blog_demos.git 该项目源码的仓库地址,https协议
    git仓库地址(ssh) git@github.com:zq2599/blog_demos.git 该项目源码的仓库地址,ssh协议
    1. 这个git项目中有多个文件夹,本章的应用在mybatis文件夹下,如下图红框所示:

    在这里插入图片描述

    springboot+mybatis+druid+swagger集成步骤小结

    将整个集成所需步骤列举如下,避免遗漏:

    1. 创建springboot工程;
    2. pom.xml中加入mybaits、druid、swagger依赖;
    3. 配置mybatis-config.xml;
    4. 配置application.yml,里面有数据源、mybatis、druid;
    5. springboot启动类,指定MapperScan;
    6. swagger配置类;
    7. druid配置类;
    8. 数据库实体类;
    9. mybatis的mapper配置文件;
    10. mybatis的mapper类;
    11. 业务代码;
    • 后续按照上述清单进行开发即可;

    开发

    1. 本文的实战使用的数据库和表结构与《MyBatis初级实战之一:Spring Boot集成》一模一样;
    2. 前文《MyBatis初级实战之一:Spring Boot集成》创建了父工程mybatis,本文继续在此工程中新增子工程,名为druidonesource,整个子工程文件结构如下:

    在这里插入图片描述
    3. 在父工程中添加druid的版本管理:

                <dependency>
                    <groupId>com.alibaba</groupId>
                    <artifactId>druid-spring-boot-starter</artifactId>
                    <version>1.1.17</version>
                </dependency>
    
    1. 新工程druidonesource的pom.xml内容如下:
    <?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <parent>
            <groupId>com.bolingcavalry</groupId>
            <artifactId>mybatis</artifactId>
            <version>1.0-SNAPSHOT</version>
            <relativePath>../pom.xml</relativePath>
        </parent>
    
        <groupId>com.bolingcavalry</groupId>
        <artifactId>druidonesource</artifactId>
        <version>0.0.1-SNAPSHOT</version>
        <name>druidonesource</name>
        <description>Demo project for Mybatis Druid (one datasource) in Spring Boot</description>
    
        <properties>
            <java.version>1.8</java.version>
        </properties>
    
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-web</artifactId>
            </dependency>
            <dependency>
                <groupId>org.mybatis.spring.boot</groupId>
                <artifactId>mybatis-spring-boot-starter</artifactId>
            </dependency>
            <dependency>
                <groupId>mysql</groupId>
                <artifactId>mysql-connector-java</artifactId>
                <scope>runtime</scope>
            </dependency>
    
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-starter-test</artifactId>
                <scope>test</scope>
                <exclusions>
                    <exclusion>
                        <groupId>org.junit.vintage</groupId>
                        <artifactId>junit-vintage-engine</artifactId>
                    </exclusion>
                </exclusions>
            </dependency>
    
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger2</artifactId>
            </dependency>
            <!-- swagger-ui -->
            <dependency>
                <groupId>io.springfox</groupId>
                <artifactId>springfox-swagger-ui</artifactId>
            </dependency>
    
            <dependency>
                <groupId>com.alibaba</groupId>
                <artifactId>druid-spring-boot-starter</artifactId>
            </dependency>
    
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>com.google.code.gson</groupId>
                <artifactId>gson</artifactId>
            </dependency>
        </dependencies>
    
        <build>
            <plugins>
                <plugin>
                    <groupId>org.springframework.boot</groupId>
                    <artifactId>spring-boot-maven-plugin</artifactId>
                </plugin>
            </plugins>
        </build>
    
    </project>
    
    1. 新建mybatis-config.xml:
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <typeAliases>
            <!-- 映射文件中的类不用写全路径了-->
            <package name="com.bolingcavalry.druidonesource.entity"/>
        </typeAliases>
    </configuration>
    
    1. 配置application.yml,请重点关注druid的配置,还请注意stat-view-servlet,这里是druid监控页面的登录配置:
    server:
      port: 8080
    
    spring:
      #1.JDBC数据源
      datasource:
        username: root
        password: 123456
        url: jdbc:mysql://192.168.50.43:3306/mybatis?useUnicode=true&characterEncoding=utf-8&useSSL=true&serverTimezone=UTC
        driver-class-name: com.mysql.cj.jdbc.Driver
        #2.连接池配置
        druid:
          #初始化连接池的连接数量 大小,最小,最大
          initial-size: 5
          min-idle: 5
          max-active: 20
          #配置获取连接等待超时的时间
          max-wait: 60000
          #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒
          time-between-eviction-runs-millis: 60000
          # 配置一个连接在池中最小生存的时间,单位是毫秒
          min-evictable-idle-time-millis: 30000
          # 配置一个连接在池中最大生存的时间,单位是毫秒
          max-evictable-idle-time-millis: 300000
          validation-query: SELECT 1 FROM user
          test-while-idle: true
          test-on-borrow: true
          test-on-return: false
          # 是否缓存preparedStatement,也就是PSCache  官方建议MySQL下建议关闭   个人建议如果想用SQL防火墙 建议打开
          pool-prepared-statements: true
          max-pool-prepared-statement-per-connection-size: 20
          # 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙
          filters: stat,wall,slf4j
          filter:
            stat:
              merge-sql: true
              slow-sql-millis: 5000
          #3.基础监控配置
          web-stat-filter:
            enabled: true
            url-pattern: /*
            #设置不统计哪些URL
            exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*"
            session-stat-enable: true
            session-stat-max-count: 100
          stat-view-servlet:
            enabled: true
            url-pattern: /druid/*
            reset-enable: true
            #设置监控页面的登录名和密码
            login-username: admin
            login-password: admin
            allow: 127.0.0.1
            #deny: 192.168.1.100
    
    # mybatis配置
    mybatis:
      # 配置文件所在位置
      config-location: classpath:mybatis-config.xml
      # 映射文件所在位置
      mapper-locations: classpath:mappers/*Mapper.xml
    
    # 日志配置
    logging:
      level:
        root: INFO
        com:
          bolingcavalry:
            druidonesource:
              mapper: debug
    
    1. 创建启动类,要带上MapperScan注解:
    package com.bolingcavalry.druidonesource;
    
    import org.mybatis.spring.annotation.MapperScan;
    import org.springframework.boot.SpringApplication;
    import org.springframework.boot.autoconfigure.SpringBootApplication;
    
    @SpringBootApplication
    @MapperScan("com.bolingcavalry.druidonesource.mapper")
    public class DuridOneSourceApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(DuridOneSourceApplication.class, args);
        }
    }
    
    1. 创建swagger配置类:
    package com.bolingcavalry.druidonesource;
    
    import springfox.documentation.service.Contact;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import springfox.documentation.builders.ApiInfoBuilder;
    import springfox.documentation.builders.PathSelectors;
    import springfox.documentation.builders.RequestHandlerSelectors;
    import springfox.documentation.service.ApiInfo;
    import springfox.documentation.service.Tag;
    import springfox.documentation.spi.DocumentationType;
    import springfox.documentation.spring.web.plugins.Docket;
    import springfox.documentation.swagger2.annotations.EnableSwagger2;
    
    /**
     * @Description: swagger配置类
     * @author: willzhao E-mail: zq2599@gmail.com
     * @date: 2020/8/11 7:54
     */
    @Configuration
    @EnableSwagger2
    public class SwaggerConfig {
    
        @Bean
        public Docket createRestApi() {
            return new Docket(DocumentationType.SWAGGER_2)
                    .apiInfo(apiInfo())
                    .tags(new Tag("UserController", "用户服务"), new Tag("LogController", "日志服务"))
                    .select()
                    // 当前包路径
                    .apis(RequestHandlerSelectors.basePackage("com.bolingcavalry.druidonesource.controller"))
                    .paths(PathSelectors.any())
                    .build();
        }
    
        //构建 api文档的详细信息函数,注意这里的注解引用的是哪个
        private ApiInfo apiInfo() {
            return new ApiInfoBuilder()
                    //页面标题
                    .title("MyBatis CURD操作")
                    //创建人
                    .contact(new Contact("程序员欣宸", "https://github.com/zq2599/blog_demos", "zq2599@gmail.com"))
                    //版本号
                    .version("1.0")
                    //描述
                    .description("API 描述")
                    .build();
        }
    }
    
    1. 创建druid配置类,如下,可见是通过使用application.yml中配置的参数对DruidDataSource进行配置:
    package com.bolingcavalry.druidonesource;
    
    import com.alibaba.druid.pool.DruidDataSource;
    import com.alibaba.druid.support.http.StatViewServlet;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Value;
    import org.springframework.boot.web.servlet.ServletRegistrationBean;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    
    /**
     * @Description: druid配置类
     * @author: willzhao E-mail: zq2599@gmail.com
     * @date: 2020/8/18 08:12
     */
    @Configuration
    public class DruidConfig {
    
        private static final Logger logger = LoggerFactory.getLogger(DruidConfig.class);
    
        @Value("${spring.datasource.url}")
        private String dbUrl;
        @Value("${spring.datasource.username}")
        private String username;
        @Value("${spring.datasource.password}")
        private String password;
        @Value("${spring.datasource.driver-class-name}")
        private String driverClassName;
        @Value("${spring.datasource.druid.initial-size}")
        private int initialSize;
        @Value("${spring.datasource.druid.max-active}")
        private int maxActive;
        @Value("${spring.datasource.druid.min-idle}")
        private int minIdle;
        @Value("${spring.datasource.druid.max-wait}")
        private int maxWait;
        @Value("${spring.datasource.druid.pool-prepared-statements}")
        private boolean poolPreparedStatements;
        @Value("${spring.datasource.druid.max-pool-prepared-statement-per-connection-size}")
        private int maxPoolPreparedStatementPerConnectionSize;
        @Value("${spring.datasource.druid.time-between-eviction-runs-millis}")
        private int timeBetweenEvictionRunsMillis;
        @Value("${spring.datasource.druid.min-evictable-idle-time-millis}")
        private int minEvictableIdleTimeMillis;
        @Value("${spring.datasource.druid.max-evictable-idle-time-millis}")
        private int maxEvictableIdleTimeMillis;
        @Value("${spring.datasource.druid.validation-query}")
        private String validationQuery;
        @Value("${spring.datasource.druid.test-while-idle}")
        private boolean testWhileIdle;
        @Value("${spring.datasource.druid.test-on-borrow}")
        private boolean testOnBorrow;
        @Value("${spring.datasource.druid.test-on-return}")
        private boolean testOnReturn;
        @Value("${spring.datasource.druid.filters}")
        private String filters;
        @Value("{spring.datasource.druid.connection-properties}")
        private String connectionProperties;
    
        /**
         * Druid 连接池配置
         */
        @Bean
        public DruidDataSource dataSource() {
            DruidDataSource datasource = new DruidDataSource();
            datasource.setUrl(dbUrl);
            datasource.setUsername(username);
            datasource.setPassword(password);
            datasource.setDriverClassName(driverClassName);
            datasource.setInitialSize(initialSize);
            datasource.setMinIdle(minIdle);
            datasource.setMaxActive(maxActive);
            datasource.setMaxWait(maxWait);
            datasource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis);
            datasource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
            datasource.setMaxEvictableIdleTimeMillis(minEvictableIdleTimeMillis);
            datasource.setValidationQuery(validationQuery);
            datasource.setTestWhileIdle(testWhileIdle);
            datasource.setTestOnBorrow(testOnBorrow);
            datasource.setTestOnReturn(testOnReturn);
            datasource.setPoolPreparedStatements(poolPreparedStatements);
            datasource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize);
            try {
                datasource.setFilters(filters);
            } catch (Exception e) {
                logger.error("druid configuration initialization filter", e);
            }
            datasource.setConnectionProperties(connectionProperties);
            return datasource;
        }
    
    }
    
    1. 接下来的数据实体类、mapper配置、mapper接口类、业务代码等,除了package不一样,其他的与上一章《MyBatis初级实战之二:增删改查》一模一样,请参考github源码或者上一篇文章来编写,这里就不占篇幅了;

    单元测试(特别注意)

    单元测试时有个问题要特别注意,就是关闭监控功能,否则会导致单元测试失败;

    1. 新建名为application-test.yml的文件,内容和application.yml一样,仅下图红框中的值不同:

    在这里插入图片描述

    1. 单元测试类UserControllerTest的内容与上一章《MyBatis初级实战之二:增删改查》一样,仅下图红框位置是新增的,用于指定使用application-test.yml配置文件:

    在这里插入图片描述

    验证,单元测试

    如下图红框的操作,即可完成单元测试:

    在这里插入图片描述

    验证,swagger

    1. 运行DuridOneSourceApplication类启动应用;
    2. 浏览器打开:http://localhost:8080/swagger-ui.htm,操作如下:

    在这里插入图片描述
    3. 得到响应操作成功,并返回了主键ID:

    在这里插入图片描述

    1. 其他接口也可以通过类似操作在swagger页面上完成;

    确认使用了druid连接池

    1. 上面的操作证明咱们的spring boot应用可以操作数据库,但没办法证明用的是druid数据源(没准用的还是spring boot的默认datasource),因此需要有种更直接的方式来检查数据源详情,因此采用了打断点的手段,查看数据源实例;
    2. UserMapper接口insertWithFields方法的打上断点,如下图红框:

    在这里插入图片描述
    3. 如下图,在DuridOneSourceApplication类上点击鼠标右键,选择红框中的选项,即可以debug的方式启动应用:

    在这里插入图片描述
    4. 启动日志如下图红框,可见debug模式下启动速度很慢,请耐心等待:

    在这里插入图片描述
    5. 再次调用方法就会进入断点位置,这时候可以展开UserMapper对应实例的变量,如下图红框所示,可以确定使用了druid的连接池:

    在这里插入图片描述
    6. 上一篇文章中的工程curd没有使用druid,咱们也打上断点看看数据源啥样的,如下图所示,是个HikariDataSource实例:

    在这里插入图片描述

    体验druid提供的监控页面

    1. 执行DuridOneSourceApplication类启动应用;
    2. 浏览器访问:http://localhost:8080/druid ,如下图,账号密码都是admin(在application.yml中配置的):

    在这里插入图片描述

    1. 在swagger上调用几次接口对数据库进行操作,之后回到druid页面,如下图,可见已经监控到了具体的数据库操作:

    在这里插入图片描述

    • 至此,springboot+mybatis+druid集成的开发和验证就完成了,希望本文能给您一些参考;

    你不孤单,欣宸原创一路相伴

    1. Java系列
    2. Spring系列
    3. Docker系列
    4. kubernetes系列
    5. 数据库+中间件系列
    6. DevOps系列

    欢迎关注公众号:程序员欣宸

    微信搜索「程序员欣宸」,我是欣宸,期待与您一同畅游Java世界...
    https://github.com/zq2599/blog_demos

  • 相关阅读:
    HDU 1022 Train Problem I
    HDU 1702 ACboy needs your help again!
    HDU 1294 Rooted Trees Problem
    HDU 1027 Ignatius and the Princess II
    HDU 3398 String
    HDU 1709 The Balance
    HDU 2152 Fruit
    HDU 1398 Square Coins
    HDU 3571 N-dimensional Sphere
    HDU 2451 Simple Addition Expression
  • 原文地址:https://www.cnblogs.com/bolingcavalry/p/14296129.html
Copyright © 2011-2022 走看看