跳至主要內容

框架分析

wangdx大约 8 分钟

数据库编程

单体项目单数据源-HikariCP

1.
mysqlJ           : '8.0.33',          // MySQL驱动的版本
druid            : '1.2.21',          // Druid版本
springJdbc       : '5.3.31',          // SpringJDBC版本
HikariCP          : '5.1.0',        // 数据连接池

// 以下的配置为数据库开发所需要的依赖:
'mysql-connector-j'                   : "com.mysql:mysql-connector-j:${versions.mysqlJ}",
'druid-spring-boot-starter'           : "com.alibaba:druid-spring-boot-starter:${versions.druid}",
'spring-jdbc'                         : "org.springframework:spring-jdbc:${versions.springJdbc}",
'druid'                               : "com.alibaba:druid:${versions.druid}",
'HikariCP'                   : "com.zaxxer:HikariCP:${versions.HikariCP}",

implementation(libraries.'mysql-connector-j')
implementation(libraries.'HikariCP')
implementation(libraries.'spring-jdbc')
2.
yix.database.driverClassName=com.mysql.cj.jdbc.Driver
yix.database.jdbcUrl=jdbc:mysql://192.168.16.8:3306/yootk
yix.database.username=root
yix.database.password=root
yix.database.connectionTimeOut=3000
yix.database.readOnly=false
yix.database.pool.idleTimeOut=3000
yix.database.pool.maxLifetime=60000
yix.database.pool.maximumPoolSize=60
yix.database.pool.minimumIdle=20
3.
package com.yix.config;

import com.zaxxer.hikari.HikariDataSource;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;

import javax.sql.DataSource;

/**
 * @author wangdx
 */
@Configuration                        // 配置类
@PropertySource("classpath:config/database.properties")    // 配置加载
public class DataSourceConfig {
    @Value("${yix.database.driverClassName}")        // 资源文件读取配置项
    private String driverClassName;            // 数据库驱动程序
    @Value("${yix.database.jdbcUrl}")            // 资源文件读取配置项
    private String jdbcUrl;                // 数据库连接地址
    @Value("${yix.database.username}")            // 资源文件读取配置项
    private String username;                // 用户名
    @Value("${yix.database.password}")            // 资源文件读取配置项
    private String password;                // 密码
    @Value("${yix.database.connectionTimeOut}")        // 资源文件读取配置项
    private long connectionTimeout;            // 连接超时
    @Value("${yix.database.readOnly}")            // 资源文件读取配置项
    private boolean readOnly;                // 只读配置
    @Value("${yix.database.pool.idleTimeOut}")        // 资源文件读取配置项
    private long idleTimeout;                // 连接最小维持时长
    @Value("${yix.database.pool.maxLifetime}")        // 资源文件读取配置项
    private long maxLifetime;                // 连接最大存活时长
    @Value("${yix.database.pool.maximumPoolSize}")    // 资源文件读取配置项
    private int maximumPoolSize;                // 连接池最大维持数量
    @Value("${yix.database.pool.minimumIdle}")        // 资源文件读取配置项
    private int minimumIdle;                // 连接池最小维持数量

    @Bean("dataSource")                    // Bean注册
    public DataSource dataSource() {            // 配置数据源
        HikariDataSource dataSource = new HikariDataSource(); // DataSource子类实例化
        dataSource.setDriverClassName(this.driverClassName); // 驱动程序
        dataSource.setJdbcUrl(this.jdbcUrl);        // JDBC连接地址
        dataSource.setUsername(this.username);        // 用户名
        dataSource.setPassword(this.password);        // 密码
        dataSource.setConnectionTimeout(this.connectionTimeout); // 连接超时
        dataSource.setReadOnly(this.readOnly);        // 是否为只读数据库
        dataSource.setIdleTimeout(this.idleTimeout);    // 最小维持时间
        dataSource.setMaxLifetime(this.maxLifetime);    // 连接的最大时长
        dataSource.setMaximumPoolSize(this.maximumPoolSize); // 连接池最大容量
        dataSource.setMinimumIdle(this.minimumIdle);    // 最小维持连接量
        return dataSource;                // 返回Bean实例
    }
}
4.
@ExtendWith(SpringExtension.class) // 使用JUnit5测试工具
@WebAppConfiguration // 启动WEB运行环境
@SpringBootTest(classes = DruidApplication.class) // 配置程序启动类
public class TestDruidDataSource {
    @Autowired
    private DataSource dataSource;

    @Test
    public void testDruid() {    // 进行响应测试
        try {
            System.out.println(this.dataSource.getConnection());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

单体项目单数据源-druid

1.
2.
spring:
  yix: # 一个自定义配置项,这个名称就是数据库的名称
    datasource:
      type: com.alibaba.druid.pool.DruidDataSource # 配置数据源的类型
      driver-class-name: com.mysql.cj.jdbc.Driver # MySQL8之后的驱动
      url: jdbc:mysql://192.168.16.8:3306/yootk # 数据库的JDBC连接地址
      username: root # 用户名
      password: root # 密码
      druid: # 定义数据库连接池所需要的相关配置项
        initial-size: 5 # 初始化连接池大小
        min-idle: 10 # 最小维持的连接池大小
        max-active: 50 # 最大可提供的连接数量
        max-wait: 60000 # 最长等待时间
        time-between-eviction-runs-millis: 6000 # 关闭空闲连接间隔(毫秒)
        min-evictable-idle-time-millis: 30000 # 连接最小的生存时间
        validation-query: SELECT 1 FROM dual # 数据库的状态检测
        test-while-idle: true # 判断连接是否可用
        test-on-borrow: false # 在获得连接之前是否要进行测试
        test-on-return: false # 归还连接前是否需要进行测试
        pool-prepared-statements: false # 不缓存PSTMT
        max-pool-prepared-statement-per-connection-size: 20 # 配置PSTMT缓存个数
        stat: # 监控配置
          merge-sql: true # 统计相同的SQL命令
          log-slow-sql: true # 记录慢SQL
          slow-sql-millis: 2000 # 慢SQL执行时间标准
3.
package com.yix.config;

import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.logging.Slf4jLogFilter;
import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.pool.DruidDataSource;
import com.alibaba.druid.wall.WallFilter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

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

/**
 * 自定义的Druid配置类
 *
 * @author wangdx
 */
@Configuration
public class DruidDataSourceConfiguration {
    @Bean("yootkDruidDataSource") // 手工设置Bean名称
    public DruidDataSource getYootkDruidDataSource(
            @Value("${spring.yix.datasource.driver-class-name}")
            String driverClassName, // 数据库驱动程序
            @Value("${spring.yix.datasource.url}")
            String url, // 数据库连接地址
            @Value("${spring.yix.datasource.username}")
            String username, // 数据库的用户名
            @Value("${spring.yix.datasource.password}")
            String password, // 数据库的用户名
            @Value("${spring.yix.datasource.druid.initial-size}")
            int initialSize, // 初始化连接数
            @Value("${spring.yix.datasource.druid.min-idle}")
            int minIdle, // 最小维持连接数
            @Value("${spring.yix.datasource.druid.max-active}")
            int maxActive, // 最大连接数
            @Value("${spring.yix.datasource.druid.max-wait}")
            long maxWait, // 最长等待时间
            @Value("${spring.yix.datasource.druid.time-between-eviction-runs-millis}")
            long timeBetweenEvictionRunsMillis, // 关闭空闲连接间隔
            @Value("${spring.yix.datasource.druid.min-evictable-idle-time-millis}")
            long minEvictableIdleTimeMillis, // 最小存活时间
            @Value("${spring.yix.datasource.druid.validation-query}")
            String validationQuery, // 验证查询
            @Value("${spring.yix.datasource.druid.test-while-idle}")
            boolean testWhileIdle, // 测试空闲连接是否可用
            @Value("${spring.yix.datasource.druid.test-on-borrow}")
            boolean testOnBorrow, // 测试后返回连接
            @Value("${spring.yix.datasource.druid.test-on-return}")
            boolean testOnReturn, // 测试后归还
            @Value("${spring.yix.datasource.druid.pool-prepared-statements}")
            boolean poolPreparedStatements, // 是否缓存PSTMT
            @Value("${spring.yix.datasource.druid.max-pool-prepared-statement-per-connection-size}")
            int maxPoolPreparedStatementPerConnectionSize, // PSTMT缓存个数
            @Autowired StatFilter sqlStatFilter, // 注入SQL监控
            @Autowired WallFilter sqlWallFilter, // 注入SQL防火墙
            @Autowired Slf4jLogFilter logFilter // 日志记录
    ) {
        DruidDataSource dataSource = new DruidDataSource(); // 实例化DataSource子类对象
        dataSource.setDriverClassName(driverClassName); // 数据库驱动程序
        dataSource.setUrl(url); // 数据库的连接地址
        dataSource.setUsername(username); // 数据库用户名
        dataSource.setPassword(password); // 数据库密码
        dataSource.setInitialSize(initialSize); // 连接池初始化大小
        dataSource.setMinIdle(minIdle); // 最小维持的连接数量
        dataSource.setMaxActive(maxActive); // 最大的连接数量
        dataSource.setMaxWait(maxWait); // 最大等待时间
        dataSource.setTimeBetweenEvictionRunsMillis(timeBetweenEvictionRunsMillis); // 检查的间隔时间
        dataSource.setMinEvictableIdleTimeMillis(minEvictableIdleTimeMillis); // 存活时间
        dataSource.setValidationQuery(validationQuery); // 验证SQL
        dataSource.setTestWhileIdle(testWhileIdle); // 测试连接是否可用
        dataSource.setTestOnBorrow(testOnBorrow); // 获取时检测
        dataSource.setTestOnReturn(testOnReturn); // 归还时检测
        dataSource.setPoolPreparedStatements(poolPreparedStatements); // 是否缓存PSTMT
        dataSource.setMaxPoolPreparedStatementPerConnectionSize(maxPoolPreparedStatementPerConnectionSize); // 缓存个数
        // 定义所有可能存在的监控项集合
        List<Filter> filterList = new ArrayList<>();
        filterList.add(sqlStatFilter); // 配置监控项
        filterList.add(sqlWallFilter); // SQL防火墙
        filterList.add(logFilter); // SQL防火墙
        dataSource.setProxyFilters(filterList); // 与DataSource整合
        return dataSource;
    }
}
4.
package com.yix.config;

import com.alibaba.druid.filter.logging.Slf4jLogFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author wangdx
 */
@Configuration
public class DruidLogConfig {
    @Bean("logFilter")
    public Slf4jLogFilter getLogFilter() {
        Slf4jLogFilter logFilter = new Slf4jLogFilter();
        logFilter.setDataSourceLogEnabled(true); // 启用数据库的日志
        logFilter.setStatementExecutableSqlLogEnable(true); // 记录执行日志
        return logFilter;
    }
}
5.
package com.yix.config;

import com.alibaba.druid.filter.stat.StatFilter;
import com.alibaba.druid.support.jakarta.StatViewServlet;
import com.alibaba.druid.support.jakarta.WebStatFilter;
import com.alibaba.druid.wall.WallConfig;
import com.alibaba.druid.wall.WallFilter;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.web.servlet.FilterRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.DependsOn;

/**
 * @author wangdx
 */
@Configuration
public class DruidMonitorConfiguration {
    @Bean("druidStatViewServlet")
    public ServletRegistrationBean<StatViewServlet> getDruidStatViewServlet() {
        ServletRegistrationBean<StatViewServlet> registrationBean = new ServletRegistrationBean<>(
                new StatViewServlet(), "/druid/*"); // 程序的访问路径
        registrationBean.addInitParameter(StatViewServlet.PARAM_NAME_ALLOW, "127.0.0.1"); // 白名单
        registrationBean.addInitParameter(StatViewServlet.PARAM_NAME_DENY, ""); // 黑名单
        registrationBean.addInitParameter(StatViewServlet.PARAM_NAME_USERNAME, "muyan"); // 用户名
        registrationBean.addInitParameter(StatViewServlet.PARAM_NAME_PASSWORD, "yootk");// 密码
        registrationBean.addInitParameter(StatViewServlet.PARAM_NAME_RESET_ENABLE, "true"); // 允许重置
        return registrationBean;
    }

    @Bean
    @DependsOn("webStatFilter")
    public FilterRegistrationBean<WebStatFilter> getDruidWebStatFilter(
            WebStatFilter webStatFilter
    ) {
        FilterRegistrationBean<WebStatFilter> registrationBean = new FilterRegistrationBean<>(webStatFilter);
        registrationBean.addUrlPatterns("/*"); // 对所有的路径都进行监控配置
        registrationBean.addInitParameter(WebStatFilter.PARAM_NAME_EXCLUSIONS,
                "*.js,*.gif,*.jpg,*.bmp,*.css,*.ico,/druid/*"); // 路径排除
        return registrationBean;
    }

    @Bean("webStatFilter")
    public WebStatFilter getWebStatFilter() {   // 获取WEB状态过滤
        WebStatFilter statFilter = new WebStatFilter();
        statFilter.setSessionStatEnable(true); // 对Session状态进行监控
        return statFilter;
    }

    @Bean("sqlStatFilter")
    public StatFilter getSQLStatFilter(
            @Value("${spring.yix.datasource.druid.stat.merge-sql}")
            boolean mergeSql,
            @Value("${spring.yix.datasource.druid.stat.log-slow-sql}")
            boolean logSlowSql,
            @Value("${spring.yix.datasource.druid.stat.slow-sql-millis}")
            long slowSqlMillis
    ) { // 定义关于SQL监控的处理部分
        StatFilter filter = new StatFilter();
        filter.setMergeSql(mergeSql); // 是否需要合并统计
        filter.setLogSlowSql(logSlowSql); // 慢SQL记录
        filter.setSlowSqlMillis(slowSqlMillis); // 慢SQL执行时间
        return filter;
    }

    @Bean("sqlWallConfig")
    public WallConfig getSQLWallConfig() { // 获取防火墙
        WallConfig wc = new WallConfig(); // 配置防火墙
        wc.setMultiStatementAllow(true); // 允许进行多个Statatement操作(批处理)
        wc.setDeleteAllow(false); // 不允许执行删除
        return wc;
    }

    @Bean("sqlWallFilter")
    public WallFilter getSQLWallFilter(WallConfig wallConfig) { // 注入防火墙配置项
        WallFilter filter = new WallFilter();
        filter.setConfig(wallConfig);
        return filter;
    }
}
6.
package com.yix.config;

import com.alibaba.druid.support.spring.stat.DruidStatInterceptor;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.aop.support.JdkRegexpMethodPointcut;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Scope;

/**
 * Spring监控配置类
 *
 * @author wangdx
 */
@Configuration
public class DruidSpringConfig {
    @Bean("druidStatInterceptor")
    public DruidStatInterceptor getDruidStatInterceptor() {
        DruidStatInterceptor interceptor = new DruidStatInterceptor(); // 创建Druid拦截器
        return interceptor;
    }

    @Bean("druidSpringStatPointcut")
    @Scope("prototype")
    public JdkRegexpMethodPointcut getDruidSpringStatPointcut() {   // 获取切面
        JdkRegexpMethodPointcut pointcut = new JdkRegexpMethodPointcut();
        pointcut.setPatterns("com.yix.service.*", "com.yix.action.*", "com.yix.dao.*");
        return pointcut;
    }

    @Bean("druidSpringStatAdvisor")
    public DefaultPointcutAdvisor getDruidSpringStatAdvisor(
            DruidStatInterceptor druidStatInterceptor,
            JdkRegexpMethodPointcut jdkRegexpMethodPointcut
    ) {
        DefaultPointcutAdvisor defaultPointcutAdvisor = new DefaultPointcutAdvisor();
        defaultPointcutAdvisor.setPointcut(jdkRegexpMethodPointcut);
        defaultPointcutAdvisor.setAdvice(druidStatInterceptor);
        return defaultPointcutAdvisor;
    }
}
7.
package com.yix.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.core.JdbcTemplate;

import javax.sql.DataSource;

/**
 * @author wangdx
 */
@Configuration
public class SpringJdbcConfiguration {
    @Bean
    public JdbcTemplate getJdbcTemplate(DataSource dataSource) {
        JdbcTemplate template = new JdbcTemplate();
        template.setDataSource(dataSource);
        return template;
    }
}

4.
@ExtendWith(SpringExtension.class) // 使用JUnit5测试工具
@WebAppConfiguration // 启动WEB运行环境
@SpringBootTest(classes = DruidApplication.class) // 配置程序启动类
public class TestDruidDataSource {
    @Autowired
    private DataSource dataSource;

    @Test
    public void testDruid() {    // 进行响应测试
        try {
            System.out.println(this.dataSource.getConnection());
        } catch (SQLException throwables) {
            throwables.printStackTrace();
        }
    }
}

单数据源-druid-yml

1.
api(libraries.'druid-spring-boot-starter')
2.
server:
  port: 80
spring:
  datasource: # 数据源配置
    druid: # druid相关配置
      type: com.alibaba.druid.pool.DruidDataSource # 配置数据源的类型
      driver-class-name: com.mysql.cj.jdbc.Driver    # 配置MySQL的驱动程序类
      url: jdbc:mysql://192.168.16.8:3306/yootk    # 数据库连接地址
      username: root                # 数据库用户名
      password: root            # 数据库连接密码
      initial-size: 5                # 初始化连接池大小
      min-idle: 10                # 最小维持的连接池大小
      max-active: 20                # 最大支持的连接池大小
      max-wait: 60000                # 最大等待时间(毫秒)
      connectTimeout: 30000          #配置连接超时时间
      socketTimeout: 60000            # 配置网络超时时间
      time-between-eviction-runs-millis: 60000    # 关闭空闲连接间隔(毫秒)
      min-evictable-idle-time-millis: 300000        # 连接最小生存时间(毫秒)
      maxEvictableIdleTimeMillis: 900000           #配置一个连接在池中最大生存的时间,单位是毫秒
      validation-query: SELECT 1 FROM dual        # 数据库状态检测
      test-while-idle: true            # 申请连接的时候检测连接是否有效
      test-on-borrow: false            # 申请连接时检测连接是否有效
      test-on-return: false            # 归还连接时检测连接是否有效
      pool-prepared-statements: false        # PSCache缓存
      max-pool-prepared-statement-per-connection-size: 20    # 配置PS缓存
      filters: stat, wall, slf4j            # 开启过滤
      stat-view-servlet: # 监控界面配置
        enabled: true    # 启用druid监控界面
        allow: 127.0.0.1    # 设置访问白名单
        login-username: yix   # 用户名
        login-password: yix    # 密码
        reset-enable: true  # 允许重置
        url-pattern: /druid/*  # 访问路径
      web-stat-filter: # WEB监控
        enabled: true  # 启动URI监控
        url-pattern: /*   # 跟踪根路径下的全部服务
        exclusions: "*.js,*.gif,*.jpg,*.bmp,*.png,*.css,*.ico,/druid/*"    # 跟踪排除
      filter: # Druid过滤器
        slf4j: # 日志
          enabled: true # 启用SLF4j监控
          data-source-log-enabled: true  # 启用数据库日志
          statement-executable-sql-log-enable: true # 执行日志
          result-set-log-enabled: true # ResultSet日志启用
        stat: # SQL监控
          merge-sql: true # 统计时合并相同的SQL命令
          log-slow-sql: true # 当SQL执行缓慢时是否要进行记录
          slow-sql-millis: 1  # 设置慢SQL的执行时间标准,单位:毫秒
        wall: # SQL防火墙
          enabled: true  # 启用SQL防火墙
          config: # 配置防火墙规则
            multi-statement-allow: true # 允许执行批量SQL
            delete-allow: false # 禁止执行删除语句
      aop-patterns: "com.yix.web.action.*" # Spring监控

多数据源-druid


上次编辑于: