简概
数据库连接所需的bean
- 事务相关(可选)
- PlatformTransactionManager(DataSourceTransactionManager)
- TransactionTemplate
Spring Boot 做了哪些配置
注意: 符合条件时才进?配置
数据源
数据源相关配置属性
通用:
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=dbuser
spring.datasource.password=dbpass
spring.datasource.driver-class-name=com.mysql.jdbc.Driver(可选)
配置多数据源
注意事项
-
不同数据源的配置要分开 -
关注每次使?的数据源
- 有多个DataSource时系统如何判断
- 对应的设施(事务、ORM等)如何选择DataSource
Spring Boot中的多数据源配置
-
配置@Primary类型的Bean -
排除Spring Boot的?动配置
DataSourceAutoConfiguration DataSourceTransactionManagerAutoConfiguration JdbcTemplateAutoConfiguration
- 示例代码
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class,
DataSourceTransactionManagerAutoConfiguration.class,
JdbcTemplateAutoConfiguration.class})
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
@Bean
@ConfigurationProperties("demo01.datasource")
public DataSourceProperties demo01DataSourceProperties(){
return new DataSourceProperties();
}
@Bean
public DataSource demo01DataSource(){
DataSourceProperties dataSourceProperties=demo01DataSourceProperties();
return dataSourceProperties.initializeDataSourceBuilder().build();
}
@Bean
@Resource // 表明这个方法的参数要按照名字来注入其他的Bean
public PlatformTransactionManager demo01Manager(DataSource demo01DataSource){
return new DataSourceTransactionManager(demo01DataSource);
}
@Bean
@ConfigurationProperties("demo02.datasource")
public DataSourceProperties demo02DataSourceProperties(){
return new DataSourceProperties();
}
@Bean
public DataSource demo02DataSource(){
DataSourceProperties dataSourceProperties=demo02DataSourceProperties();
return dataSourceProperties.initializeDataSourceBuilder().build();
}
@Bean
@Resource
public PlatformTransactionManager demo02Manager(DataSource demo02DataSource){
return new DataSourceTransactionManager(demo02DataSource);
}
}
- application.properties配置文件
management.endpoints.web.exposure.include=*
demo01.datasource.url=jdbc:test:demo01
demo01.datasource.username=shua
demo01.datasource.password=
demo02.datasource.url=jdbc:test:demo02
demo02.datasource.username=shua
demo02.datasource.password=
- 通过actuator查看bean。 https://www.yuque.com/shuashua-qihie/ymgqvk/linz48

连接池
HikariCP
官网:https://github.com/brettwooldridge/HikariCP
在 Spring Boot 中的配置
-
Spring Boot 2.x
- 默认使? HikariCP
- 配置 spring.datasource.hikari.* 【可参考DataSourceConfiguration类】

-
配置 Spring Boot 1.x
- 默认使? Tomcat 连接池,需要移除 tomcat-jdbc 依赖
spring.datasource.type=com.zaxxer.hikari.HikariDataSource 【在application.properties配置文件中配置】
常? HikariCP 配置参数
更多的可参考官网:https://github.com/brettwooldridge/HikariCP
- spring.datasource.hikari.maximumPoolSize=10
- spring.datasource.hikari.minimumIdle=10
- spring.datasource.hikari.idleTimeout=600000
- spring.datasource.hikari.connectionTimeout=30000
- spring.datasource.hikari.maxLifetime=1800000
Alibaba Druid
“Druid连接池是阿?巴巴开源的数据库连接池项?。Druid连接池为监控??, 内置强?的监控功能,监控特性不影响性能。功能强?,能防SQL注?,内置 Logging能诊断Hack应??为。
官网地址:https://github.com/alibaba/druid/wiki/首页
实用功能
- 详细的监控(真的是全?)
- ExceptionSorter,针对主流数据库的返回码都有?持
- SQL 防注?
- 内置加密配置
- 众多扩展点,?便进?定制
数据源配置
- 直接配置 DruidDataSource
- 通过引入
druid-spring-boot-starter 。 在application.properties 中配置spring.datasource.druid.* 相关信息。
spring.datasource.url=jdbc:mysql://localhost/test
spring.datasource.username=shua
spring.datasource.password=n/z7PyA5cvcXvs8px8FVmBVpaRyNsvJb3X7YfS38DJrIg25EbZaZGvH4aHcnc97Om0islpCAPc3MqsGvsrxVJw==
spring.datasource.druid.initial-size=5
spring.datasource.druid.max-active=5
spring.datasource.druid.min-idle=5
spring.datasource.druid.filters=config,stat,slf4j
spring.datasource.druid.connection-properties=config.decrypt=true;config.decrypt.key=${public-key}
spring.datasource.druid.filter.config.enabled=true
spring.datasource.druid.test-on-borrow=true
spring.datasource.druid.test-on-return=true
spring.datasource.druid.test-while-idle=true
public-key=MFwwDQYJKoZIhvcNAQEBBQADSwAwSAJBALS8ng1XvgHrdOgm4pxrnUdt3sXtu/E8My9KzX8sXlz+mXRZQCop7NVQLne25pXHtZoDYuMh3bzoGj6v5HvvAQ8CAwEAAQ==
Filter 配置
spring.datasource.druid.filters=stat,config,wall,log4j (全部使?默认值)
密码加密
spring.datasource.password=<加密密码> spring.datasource.druid.filter.config.enabled=true spring.datasource.druid.connection-properties=config.decrypt=true;config.decrypt.key=
SQL 防注?
spring.datasource.druid.filter.wall.enabled=true spring.datasource.druid.filter.wall.db-type=h2 spring.datasource.druid.filter.wall.config.delete-allow=false spring.datasource.druid.filter.wall.config.drop-table-allow=false
Druid Filter
- ?于定制连接池操作的各种环节
- 可以继承 FilterEventAdapter 以便?便地实现 Filter
- 修改 META-INF/druid-filter.properties 增加 Filter 配置
【待做】连接池选择时的考量点
通过 Spring JDBC 访问数据库
Spring 的 JDBC 操作类
spring-jdbc
- core,JdbcTemplate 等相关核?接?和类
- datasource,数据源相关的辅助类
- object,将基本的 JDBC 操作封装成对象
- support,错误码等其他辅助?具
常?的 Bean 注解
@Component @Repository @Service @Controller @RestController
简单的 JDBC 操作
JdbcTemplate
query queryForObject queryForList update execute
SQL 批处理
小tips:解决IDEA的错误提示
解决IDEA中 Could not autowire. No beans of ‘xxxx’ type found 的错误提示
这个错误提示有时并不会产生影响,程序的编译和运行都是没有问题的。但强迫症也是真的受不了。
修改IDEA设置,降低Autowired检测的级别,将Severity的级别由之前的error改成warning或其它可以忽略的级别。

Spring 的事务抽象
?致的事务模型
- JDBC/Hibernate/myBatis
- DataSource/JTA
事务抽象的核?接?
PlatformTransactionManager ,部分实现类如下:
DataSourceTransactionManager HibernateTransactionManager JtaTransactionManager

TransactionDefinition ,几种属性如下:(注意TransactionDefinition 是一个接口哦)
Propagation Isolation Timeout Read-only status

事务传播特性
详情可查看TransactionDefinition接口
传播特性 | 属性值 | 注释 |
---|
PROPAGATION_REQUIRED | 0 | 当前有事务就用当前的,没有就用新的 | PROPAGATION_SUPPORTS | 1 | 事务可有可无,不是必须的 | PROPAGATION_MANDATORY | 2 | 当前一定要有事务,不然就抛异常 | PROPAGATION_REQUIRES_NEW | 3 | 无论是否有事务,都起个新的事务 | PROPAGATION_NOT_SUPPORTED | 4 | 不支持事务,按非事务方式运行 | PROPAGATION_NEVER | 5 | 不支持事务,如果有事务则抛异常 | PROPAGATION_NESTED | 6 | 当前有事务就在当前事务里再起一个事务 |
REQUIRES_NEW 与 NESTED 事务传播特性的说明
事务隔离级别
详情可查看TransactionDefinition接口,默认隔离级别为ISOLATION_DEFAULT,值为-1,即由具体的数据库决定隔离级别。
隔离性 | 属性值 | 注释 |
---|
ISOLATION_READ_UNCOMMITTED | 1 | 读未提交 | ISOLATION_READ_COMMITTED | 2 | 读已提交 | ISOLATION_REPEATABLE_READ | 4 | 可重复读 | ISOLATION_SERIALIZABLE | 8 | 串行读 |
编程式事务
有两种实现方式:1. TransactionTemplate 类;2. PlatformTransactionManager 类
TransactionTemplate 类,调用execute()方法时可传入的对象:
- TransactionCallback
- TransactionCallbackWithoutResult
代码示例(仅展示了核心代码)
public void insert(){
transactionTemplate.execute(new TransactionCallbackWithoutResult() {
@Override
protected void doInTransactionWithoutResult(TransactionStatus status) {
String sql="INSERT INTO `user`(`username`) VALUES ('刷刷');";
jdbcTemplate.execute(sql);
System.out.println(selectAll());
status.setRollbackOnly();
}
});
System.out.println(selectAll());
}
PlatformTransactionManager
- 可以传?
TransactionDefinition 进?定义
具体使用可参考https://blog.csdn.net/z69183787/article/details/8463507
声明式事务
基于注解的配置?式
开启事务注解的?式
使用事务
添加 @Transactional 注解即可。@Transactional 的一些可配置项:
transactionManager propagation isolation timeout readOnly

怎么判断回滚或者说何时回滚?
可通过@Transactional 的rollbackFor 属性指明当出现特定的异常时进行回滚。
事务失效demo
比如下述情况,调用insert()方法时,事务就不会进行回滚。原因在于动态代理。

事务生效策略:

事务操作实现的本质
- Spring 的声明式事务本质上是通过 AOP 来增强了类的功能。
- Spring 的 AOP 本质上就是为类做了?个代理。 看似在调???写的类,实际?的是增强后的代理类
问题的解法
Spring 的 JDBC 异常抽象
概览
Spring 会将数据操作的异常转换为 DataAccessException , ?论使?何种数据访问?式,都能使??样的异常 。

Spring是怎么认识那些错误码的
通过 SQLErrorCodeSQLExceptionTranslator 解析错误码
ErrorCode 定义 的位置:
-
org/springframework/jdbc/support/sql-error-codes.xml  -
Classpath 下的 sql-error-codes.xml
【待补充】定制错误码
|