摘要
看完本文你将掌握如下知识点:
- Spring Boot对JDBC的支持
- Spring Boot项目多数据源的配置
- Spring Boot的事务管理
- Spring Boot项目多数据源的事务管理
- Spring Boot项目中使用Hibernate4的方法
- Spring Boot项目中使用Mybatis的方法
SpringBoot系列:Spring Boot学习笔记
前言
Spring Boot针对企业开发场景提供了各种『开箱即用』的spring-boot-starter-xxx自动配置依赖模块,这就使得我们开发Spring应用更加快速和高效。比如我们前面创建web项目时使用到的spring-boot-starter-web。
这些spring-boot-starter-xxx不但包含了对该功能的全部依赖包,同时也提供了该功能的自动配置类。我们本节要讨论的『数据访问』就是基于这些spring-boot-starter-xxx的自动配置依赖模块。
环境准备
jdk版本:java version “1.8.0_31”
数据库:10.1.16-MariaDB
脚本
|
|
Spring Boot对JDBC的支持
创建项目
项目创建成功后查看pom,会看到添加了spring-boot-starter-jdbc的依赖
|
|
配置项目
在pom中增加MySQL依赖
|
|
在application.properties中添加数据源配置信息
|
|
项目代码
本例只做简单演示,所以只创建如下3个类,并用一个单元测试类进行测试
Model:Person
|
|
Dao:PersonDao
|
|
Service:PersonService
|
|
单元测试:SpringbootjdbcdemoApplicationTests
|
|
说明
实际上,项目加入spring-boot-starter-jdbc的依赖后,即可在项目代码中通过@Autowired自动注入JdbcTemplate。而数据源的配置则在application.properties中进行配置。
如果不想使用spring-boot-starter-jdbc带来的默认依赖和自动配置,那么采用如下的方式,效果是一样的。
使用自定义的DataSourceConfig
修改pom中的依赖,去掉对spring-boot-starter-jdbc的依赖,并加入对spring-jdbc的依赖,这样我们就失去了对JDBC的自动配置功能了。
|
|
启动类中去掉对DataSourceAutoConfiguration的自动配置支持
|
|
创建DataSourceConfig配置类
|
|
其它代码不需要任何修改,运行效果一致。
说明
为什么SpringBoot为我们提供了spring-boot-starter-jdbc的自动配置解决方案,我们还要自己配置呢,这是因为自动配置并不是那么的强大,spring-boot-starter-jdbc只能支持单一的数据源配置,如果项目中需要关联多个数据源,就需要我们自己处理了。
比如我们在环境准备中创建了两个数据库,接下来我们在项目中增加多数据源的配置。
在application.properties中添加数据源配置信息
|
|
然后在DataSourceConfig配置类中增加如下内容:
|
|
此时需要在Dao中将@Autowired注解替换成@Resource(name = "jdbcTemplate")
,来明确指定要使用哪一个jdbcTemplate对象。
说明
关于如何在项目中使用Hibernate4框架,可以参考:SpringMVC4零配置
Spring Boot的事务管理
JDBC事务管理
如果我们项目中使用的是JDBC的数据访问方案,并且容器中只注册了一个DataSource,那么SpringBoot就会为我们开启DataSourceTransactionManagerAutoConfiguration的自动配置类,其会在容器中注册一个DataSourceTransactionManager事务管理器,同时会开启对注解式事务@Transactional的支持。感兴趣的可以看一下DataSourceTransactionManagerAutoConfiguration的源码。
@Transactional是Spring框架提供的,配置方法参考下面的代码
|
|
如果在测试类上声明@Transactional,则会开启自动回滚,不会产生脏数据
|
|
如果希望自己配置事务,可以在配置类中增加事务管理器的配置,比如,我们在DataSourceConfig中增加如下配置:
|
|
说明
上面的方法只是针对单一数据源进行事务管理的,但是项目中经常会用到多数据源的情况,那么要如何进行事务管理呢?
我们上文讲到了可以在项目中通过配置类,自己配置多个数据源,并通过DataSourceConfig进行了演示,接下来我们添加多个事务管理器。
|
|
这时,我们必须在@Transactional注解中指定要使用哪一个事务管理器
|
|
说明
这样做并不美好,不能对多个数据源同时进行事务管理,比如,我们在一个业务方法里同时对两个数据源进行操作,我们希望只要有一个发生异常,则两个数据源的数据都进行回滚。
那要怎么做呢,我们接着往下看。
多数据源事务管理
这里推荐使用Atomikos,Atomikos支持Mysql、Oracle等多种数据库,可与多种ORM框架集成,如MyBatis、JPA、Hibernate等等,同时支持各种容器下JNDI的多数据源管理。Atomikos官网提供了各种情况下使用Atomikos的Example,本文只对使用JDBC时的情况进行说明。
目前maven中央仓库的最新版本是4.0.4,使用Atomikos,需要在项目中加入如下依赖:
|
|
对DataSourceConfig进行改造:
|
|
项目编译路径下可以创建一个jta.properties文件,用于对Atomikos的相关属性进行配置,不过也可以不加这个文件,因为所有的属性都有默认值。
|
|
Spring Boot中Atomikos与Hibernate4多数据源集成方法
Atomikos与Hibernate4集成方法与JDBC类似,我们在pom中加入hibernate的依赖,并对DataSourceConfig进行改造
pom
|
|
DataSourceConfig
|
|
|
|
CP_HibernateDAO是我们自定义的Hibernate的通用Dao接口,其定义的方法和和实现类CP_Hibernate4DAOImpl代码如下:
|
|
|
|
说明
需要注意两点:
- session必须使用sessionFactory.openSession()的方式获得,不能使用sessionFactory.getCurrentSession()。
- 更新操作必须调用session.flush()方法。
Spring配置文件的方式,可以参考:Spring4+Hibernate4+Atomikos3.3多数据源事务管理
Spring Boot中Mybitas的使用
创建项目时,我们可以选择mybatis-spring-boot-starter依赖,这样可以激活SpringBoot对Mybatis的自动配置类。
pom中添加依赖
|
|
application.properties中添加mybaits的自动配置属性,可以查看MybatisProperties了解可以配置哪些属性
|
|
Mapper接口上要配置@Mapper注解,因为mybatis-spring-boot-starter的自动配置会扫描@Mapper注解来注册Mapper接口。
|
|
此时同样可以使用@Transactional注解
说明
可以使用maven的mybatis-generator插件自动生成代码,参考maven插件–MyBatis自动生成代码
mybatis-spring-boot-starter不利于扩展,所以还是我们自己实现个mybitas的配置类吧。
pom中去掉mybatis-spring-boot-starter的依赖,增加mybatis的依赖
|
|
创建MyBatisConfig
|
|
MyBatisMapperScannerConfig,基于包扫描Mapper,此时不需要配置@Mapper注解
|
|
关闭DataSourceAutoConfiguration,因为这里我们配置了数据源,所以需要关闭该自动配置,另外,MybatisAutoConfiguration也是基于DataSourceAutoConfiguration的,所以关闭了DataSourceAutoConfiguration也就同时关闭了MybatisAutoConfiguration。
Spring Boot中Atomikos与Mybatis多数据源集成方法
pom
|
|
MyBatisConfig
|
|
MyBatisMapperScannerConfig
|
|
这里要说明的是,如果两个数据源下的Mapper起了相同的类名,虽然他们在不同的包路径下,启动也会报错了,因为默认注册Mapper时使用的是类名称(不含包名),此时可以在Mapper上加上@Component(“personMapper”)注解
写在后面的话
Spring Boot为我们提供了大量的spring-boot-starter-xxx来加快我们的开发流程,创建项目时就可以看到可供选择的各种spring-boot-starter-xxx,那么这么多的spring-boot-starter-xxx,我们是否都需要了解呢,如果项目中需要用到某一个功能,是否就应该加入这个spring-boot-starter-xxx呢?
笔者人为,spring-boot-starter-xxx提供的完整jar包依赖和自动配置固然很好,但是当我们要在项目中加入某一个功能时,作为开发人员,是应该清楚的知道该功能的依赖关系和配置逻辑的,所以并不一定需要引入SpringBoot的spring-boot-starter-xxx,而且SpringBoot对这些spring-boot-starter-xxx做的自动配置,如果我们并不熟悉和十分清楚,往往会给我们开发人员造成不明所以的困扰,所以,笔者建议,在对SpringBoot提供的某一个spring-boot-starter-xxx所提供的功能并不十分清楚时,还是使用配置类的方式吧。
还有,由于某些自动配置类的激活是根据项目中是否包含某个class或容器中是否注册了某个bean,所以笔者建议,如果项目中引入了新的jar包,或者手工注册了某个bean,都要通过debug的方式查看是否开启了某个自动配置。
另外,本文代码只是为了辅助说明,比如DriverManagerDataSource正式环境不建议使用,请更换为其它数据源,比如BasicDataSource。