1、简介
springboot 支持关系型数据库的相关组件进行配置,包括数据源、连接池、事务管理器等的自动配置。降低了数据库使用的难度,除了 mysql 还支持 Derby、H2等嵌入式数据库的自动配置,MongoDB、Redis、elasticsearch等常用的 NoSQL 的数据库自动配置。
本文以 mysql 数据库为例。
2、数据源
引入以下依赖:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-jdbc</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
spring-boot-starter-data-jdbc 依赖中包含一个默认的 HikariCP 连接池,以及连接 JDBC 需要的相关依赖,但是具体的数据库驱动是需要额外导入的,上述导入的是 mysql 驱动。
数据源的自动配置类是 DataSourceAutoConfiguration 类,配置类是 DataSourceProperties 。
// 配置采用的前缀是:spring.datasource.*
@ConfigurationProperties(prefix = "spring.datasource")
// 配置数据库连接池参数 spring.datasource.hikari.*
2.1、自定义数据源
如果自定义数据源,直接注册一个 DataSorce 数据源实现类即可,根据 springboot 自动配置类使用的条件注解配置规则,如果应用已经注册相关的数据源实例,自动配置类中相关数据库连接池中的数据源就不会自动配置了。示例如下:
@SpringBootConfiguration(proxyBeanMethods = false)
public class DSource {
@Bean
@ConfigurationProperties(prefix = "spring.datasource")
public DataSource dataSource(){
return new XxxDataSource();
}
}
还可以进行多数据源配置:
@SpringBootConfiguration(proxyBeanMethods = false)
public class DSource {
@Primary
@Bean
@ConfigurationProperties(prefix = "spring.datasource.one")
public DataSource dataSource1(){
return new XxxDataSource();
}
@Bean
@ConfigurationProperties(prefix = "spring.datasource.two")
public DataSource dataSource2(){
return new XxxDataSource();
}
}
2.2、连接池
2.2.1、HikariCP 连接池
spring-boot-starter-data-jdbc(包含 spring-boot-starter-jdbc)、spring-boot-starter-data-jpa 都默认使用 HikariCP 连接池,可以通过 spring.datasource.type 指定使用的是哪个连接池。
2.2.2、druid 连接池
国内推荐使用 Druid 连接池,这是一个为监控而生的连接池,具有强大的扩展和监控功能,使用 Druid 配置数据源参数:spring.datasource.druid.*。
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid-spring-boot-starter</artifactId>
<version>1.2.5</version>
</dependency>
如果 Druid 数据源没有配置相关参数(usename、password等参数),则取 springboot 通用的数据源配置参数。
3、事务管理器
springboot 提供事务和事务管理器的自动配置(spring-boot-starter-data-jdbc 中会包含事务相关的包),绑定 TransactionProperties 类,通过 spring.transaction.* 进行参数配置。在需要使用事务的方法上添加 @Transactional 注解即可。
3.1、事务失效场景
1、数据库引擎不支持事务,例如:mysql 的 MyISAM,只有 InnoDB 支持事务。
2、使用的方法不是在 spring 容器中的对象(未被 spring 容器管理)。
3、使用的方法不是 public 的。
4、发生本类中的自身方法相互调用,这种情况没有经过 spring 的代理类,默认只有调用外部代理类的方法,事务才生效。(解决方案:1)、在事务所在的类中注入自己,使用注入的对象调用;2)、可以在当前线程中获取代理类,可以通过以下方式)。
// 在类上添加以下注解
@EnableAspectJAutoProxy(exposeProxy=true)
// 然后在调用方法的时候使用
((当前类实现的接口)AopContext.currentProxy()).**()
5、设置不支持事务,事务的传播行为被设置为 NOT_SUPPORT。
6、异常捕获没有被抛出。
7、抛出的异常类型不匹配,spring 默认回滚的是 RuntimeException 异常,如果要指定发生什么异常回滚事务,则在 @Transactional(rollbackFor=Exception.class) 注解中指定。
4、总结
本文介绍 springboot 数据访问的方式,从数据源到数据库连接池,再到事务管理,更进一步加强对 springboot 使用数据源的理解。有关如何自定义事务管理器,进一步理解数据库连接池等内容在后文详解。
本人是一个从小白自学计算机技术,对运维、后端、各种中间件技术、大数据等有一定的学习心得,想获取自学总结资料(pdf版本)或者希望共同学习,关注微信公众号:it自学社团。后台回复相应技术名称/技术点即可获得。(本人学习宗旨:学会了就要免费分享)