gradle 整合springboot druid flyway 并实现数据库密码加密
前言
打算自己写个项目玩玩,记录下项目构筑期间的问题
新建项目
idea直接使用spring initlizr生成初始项目, 直接把基础项目spring boot ,flyway,spring web整合了进去,如果项目生成不了可以切换阿里镜像,我这里生成项目没啥问题就不管了
整合druid
// druid链接池implementation group: 'com.alibaba', name: 'druid-spring-boot-starter', version: '1.2.21'
直接导的spring boot start的包
配置文件
spring:datasource:type: com.alibaba.druid.pool.DruidDataSourcedriverClassName: com.mysql.cj.jdbc.Driverurl: jdbc:mysql://localhost:3306/test?serverTimezone=Asia/Shanghai&characterEncoding=UTF-8&useSSL=falseusername: rootpassword: root123druid:# 下面为连接池的补充设置,应用到上面所有数据源中# 初始化大小,最小,最大initial-size: 5min-idle: 5max-active: 20# 配置获取连接等待超时的时间max-wait: 60000# 配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒time-between-eviction-runs-millis: 60000# 配置一个连接在池中最小生存的时间,单位是毫秒min-evictable-idle-time-millis: 300000# sql 校验validation-query: select count(1) from sys.objects Where type='U' And type_desc='USER_TABLE'test-while-idle: truetest-on-borrow: falsetest-on-return: false# 打开PSCache,并且指定每个连接上PSCache的大小pool-prepared-statements: true# 配置监控统计拦截的filters,去掉后监控界面sql无法统计,'wall'用于防火墙max-pool-prepared-statement-per-connection-size: 20filters: stat # wall 若开启 wall,会把 if 中的 and 判断为注入进行拦截use-global-data-source-stat: true# 通过connectProperties属性来打开mergeSql功能;慢SQL记录connect-properties: druid.stat.mergeSql=true;druid.stat.slowSqlMillis=5000# 配置监控统计拦截的filters,去掉后监控界面sql无法统计。stat:监控统计 log4:日志记录 wall:防御sql注入# 如果运行时报错:ClassNotFoundException:orgapache.log4j.Priority,则导入log4j依赖即可filters: stat,wall,log4j
这个时候出现第一个问题
官网是说可以将数据库地址这些配置在druid下的,但是我配置进去后发现启动会报错说找不到url,只能拿出来了
Description:Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.Reason: Failed to determine suitable jdbc url
然后最后一个配置说需要log4j的日志依赖,于是导了log4j2的依赖
// log4j2 日志工具implementation group: 'org.springframework.boot', name: 'spring-boot-starter-log4j2', version: '3.2.2'
这个时候新问题来了,log4j与spring自带日志插件冲突,需要排除spring日志插件,有俩种方式
- 一个个依赖去找到排除依赖
- 配置项目的排除依赖
一个个依赖排除
compile('org.springframework.boot:spring-boot-starter-web'){exclude group: 'commons-logging', module: 'commons-logging'exclude group: 'org.springframework.boot' ,module: 'spring-boot-starter-logging'}compile('org.springframework:spring-test:4.2.4.RELEASE'){exclude group: 'commons-logging', module: 'commons-logging'exclude group: 'org.springframework.boot' ,module: 'spring-boot-starter-logging'}implementation ('org.springframework.boot:spring-boot-starter-security'){exclude group: 'commons-logging', module: 'commons-logging'exclude group: 'org.springframework.boot' ,module: 'spring-boot-starter-logging'}
全局依赖排除
dependencies中添加
configurations.configureEach {exclude group: "commons-logging", module: "commons-logging"exclude group: 'org.springframework.boot' ,module: 'spring-boot-starter-logging'}
我选择是直接全局去除防止后续新的依赖造成影响
log4j2还可以去配置更多的配置,但不是我这边的重点,就不细研究了,重点是整合druid
整合flyway
flyway就简单很多,添加配置文件就好了
spring:flyway:# 启用或禁用 flywayenabled: true# flyway 的 clean 命令会删除指定 schema 下的所有 table, 生产务必禁掉。这个默认值是 false 理论上作为默认配置是不科学的。clean-disabled: true# SQL 脚本的目录,多个路径使用逗号分隔 默认值 classpath:db/migrationlocations: classpath:db/migration# metadata 版本控制信息表 默认 flyway_schema_historytable: flyway_schema_history# 如果没有 flyway_schema_history 这个 metadata 表, 在执行 flyway migrate 命令之前, 必须先执行 flyway baseline 命令# 设置为 true 后 flyway 将在需要 baseline 的时候, 自动执行一次 baseline。baseline-on-migrate: true# 指定 baseline 的版本号,默认值为 1, 低于该版本号的 SQL 文件, migrate 时会被忽略baseline-version: 0# 字符编码 默认 UTF-8encoding: UTF-8# 是否允许不按顺序迁移 开发建议 true 生产建议 falseout-of-order: false# 需要 flyway 管控的 schema list,这里我们配置为flyway 缺省的话, 使用spring.datasource.url 配置的那个 schema,# 可以指定多个schema, 但仅会在第一个schema下建立 metadata 表, 也仅在第一个schema应用migration sql 脚本.# 但flyway Clean 命令会依次在这些schema下都执行一遍. 所以 确保生产 spring.flyway.clean-disabled 为 true#schemas: flyway# 执行迁移时是否自动调用验证 当你的 版本不符合逻辑 比如 你先执行了 DML 而没有 对应的DDL 会抛出异常validate-on-migrate: true
数据库密码加密
数据库加密遇到的主要问题还是网上大部分文章都是基于1.1.x版本的druid来写的,我导的包是1.2.21,1.1的配置和我的估计不兼容了
首先是测试类调用druid的工具类生成公钥和私钥,以及加密后的密码
这一步有的1.1.x的文章是直接去运行jar包,但我这边不确定是1.2的原因,还是gradle的原因,直接运行jar包失败了
import org.junit.jupiter.api.Test;import static com.alibaba.druid.filter.config.ConfigTools.encrypt;
import static com.alibaba.druid.filter.config.ConfigTools.genKeyPair;public class ConfigToolsTest {@Testpublic void testPassword() throws Exception {String password = "你的密码";String[] arr = genKeyPair(512);System.out.println("privateKey:" + arr[0]);System.out.println("publicKey:" + arr[1]);System.out.println("password:" + encrypt(arr[0], password));}
}
运行测试类生成的password替换配置文件中配置的数据库密码
配置完后发现还是有问题,然后找资料发现是springboot3与druid不太兼容,好像是springboot3改了些包导致的,解决方案也简单,导druid针对spring boot3修改的包就行
implementation group: 'com.alibaba', name: 'druid-spring-boot-3-starter', version: '1.2.21'
导入后之前数据库账号密码放druid配置里面不起作用的问题也解决了
新的配置如下
public-key: 测试类生成的公钥
private-key: 测试类生成的私钥(复原密码使用,可以不配置,我只是记录下)spring:datasource:druid:driver-class-name: com.mysql.cj.jdbc.Driverurl: mysql地址username: 用户名password: 测试类生成的密码connection-properties: config.decrypt=true;config.decrypt.key=${public-key}# druid-spring-boot-starter 依赖自动生效 druid,可以不配置 type 属性,但建议配置type: com.alibaba.druid.pool.DruidDataSource