写在前面 本篇来学习SpringBoot如何配置多数据源,所谓多数据源就是一个Java EE项目中采用了不同数据库实例中的多个库,或者是同一个数据库实例中的多个不同库。一般来说,采用MyCat等分布式数据库中间件是比较好的解决方案,这样可以把数据库读写分离、分库分表、备份等操作交给中间件去做,这样Java代码只需要专注于业务即可。不过这并不意味着无法使用Java代码解决类似的问题,在Spring Famework中就可以配置多个数据源,SpringBoot作为其中的佼佼者,自然也同样支持多数据源的配置,只是配置方式有些变化而已。
下面就分别介绍使用Jdbc Template、Mybatis和SpringData JPA等不同持久层框架时的多数据源配置。
Jdbc Template多数据源 Jdbc Template多数据源配置是最简单的一个,因为一个Jdbc Template就对应一个DataSource,开发者只需要提供多个DataSource,再手动配置Jdbc Template即可。具体配置如下:第一步,创建数据库。 使用下面的SQL语句来手动创建两个数据库和表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 drop database if exists jdbcone; create database jdbcone; use jdbcone; drop table if exists book; create table book( id int(11) not null auto_increment comment 'id', name varchar(128) default null comment '名称', author varchar(64) default null comment '作者', primary key(id) )ENGINE=INNODB default charset=utf8; insert into book(id,name,author)values(1,"西游记","吴承恩"); drop database if exists jdbctwo; create database jdbctwo; use jdbctwo; drop table if exists book; create table book( id int(11) not null auto_increment comment 'id', name varchar(128) default null comment '名称', author varchar(64) default null comment '作者', primary key(id) )ENGINE=INNODB default charset=utf8; insert into book(id,name,author)values(1,"红楼梦","曹雪芹");
执行该SQL语句后,可以看出数据库中的信息如下所示:
第二步,创建SpringBoot项目并添加依赖。 使用spring Initializr
构建工具构建一个SpringBoot的Web应用,名称为jdbcmorespringboot
,然后在pom.xml文件中添加如下依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--添加jdbc依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-jdbc</artifactId> </dependency> <!--添加数据库驱动依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--添加数据库连接池依赖--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
请注意这里添加的数据库连接池依赖是druid-spring-boot-starter
。druid-spring-boot-starter
可以帮助开发者在SpringBoot项目中轻松集成Druid数据库连接池和监控。
第三步,配置数据库连接。 在application.properties
配置文件中配置多个数据源的信息:
1 2 3 4 5 6 7 8 9 10 # 数据源1 spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.one.url=jdbc:mysql://127.0.0.1:3306/jdbcone?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.one.username=root spring.datasource.one.password=1234 # 数据源2 spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.two.url=jdbc:mysql://127.0.0.1:3306/jdbctwo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.two.username=root spring.datasource.two.password=1234
这里配置了两个数据源,主要区别是数据库不同,其他都是一样的。第四步,配置数据源。 新建一个config包,并在里面创建一个DataSourceConfig
类,用于配置数据源,这样就可以根据application.properties
文件来生成对应的DataSource。里面的代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Configuration public class DataSourceConfig { @Bean @ConfigurationProperties("spring.datasource.one") public DataSource dsOne(){ return DruidDataSourceBuilder.create().build(); } @Bean @ConfigurationProperties("spring.datasource.two") public DataSource dsTwo(){ return DruidDataSourceBuilder.create().build(); } }
简单解释一下上述代码的含义:
请注意DataSource是javax.sql.DataSource
包内的;
DataSourceConfig
类中提供了两个数据源:dsOne和dsTwo,默认的方法名就是实例名。
@ConfigurationProperties
注解表示使用不同前缀的配置文件来创建不同的DataSource实例。
第五步,配置Jdbc Template。 前面提到过,只要开发者引入了spring-jdbc
依赖,那么若开发者没有提供Jdbc Template
实例时,SpringBoot默认会提供一个Jdbc Template
实例。但是现在是配置多数据源,因此这个Jdbc Template
实例就需要开发者自己来提供了。在config包内新建一个JdbcTemplateConfig
类,用于返回需要的Jdbc Template
实例,相应的代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 @Configuration public class JdbcTemplateConfig { @Bean public JdbcTemplate jdbcTemplateOne(@Qualifier("dsOne")DataSource dataSource){ return new JdbcTemplate(dataSource); } @Bean public JdbcTemplate jdbcTemplateTwo(@Qualifier("dsTwo")DataSource dataSource){ return new JdbcTemplate(dataSource); } }
简单解释一下上述代码的含义:
JdbcTemplateConfig
类中提供了两个JdbcTemplate
实例,每一个JdbcTemplate
实例都需要提供DataSource,由于Spring容器中有两个DataSource实例,因此需要通过方法名来查找。@Qualifier
注解表示查找不同名称的DataSource实例,并注入进来。
第六步,创建Book实体类和BookController类。 新建pojo包,并在里面创建Book实体类,里面的代码为:
1 2 3 4 5 6 public class Book { private Integer id; private String name; private String author; //getter和setter方法 }
接着新建controller包,并在里面创建BookController
类,里面的代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @RestController public class BookController { @Resource(name="jdbcTemplateOne") JdbcTemplate jdbcTemplateOne; @Autowired @Qualifier(value="jdbcTemplateTwo") JdbcTemplate jdbcTemplateTwo; @GetMapping("/test") public void test(){ String sql = "select * from book"; List<Book> booksOne = jdbcTemplateOne.query(sql,new BeanPropertyRowMapper<>(Book.class)); List<Book> booksTwo = jdbcTemplateTwo.query(sql,new BeanPropertyRowMapper<>(Book.class)); System.out.println("booksOne>>>>>>"+booksOne); System.out.println("booksTwo>>>>>>"+booksTwo); } }
简单解释一下上述代码的含义:
注意这里没有定义Repository和Service层,而是直接将JdbcTemplate
注入到了Controller中。在Controller中注入两个不同的JdbcTemplate
有两种方式:第一种,使用@Resource
注解,并指明name属性,然后按照name进行装配,此时会根据实例名查找相应的实例进行注入。第二种,使用@Autowried
注解并结合@Qualifier
注解,其实这种效果等同于使用@Resource
注解。
第七步,运行项目。 运行项目,在浏览器地址栏中输入http://localhost:8080/test
,然后查看控制台的输出信息为:
1 2 booksOne>>>>>>[com.envy.jdbcmorespringboot.pojo.Book@166352ef] booksTwo>>>>>>[com.envy.jdbcmorespringboot.pojo.Book@11ed31ef]
不方便查看,那就给Book实体类提供toString方法,之后再来运行一下:
1 2 booksOne>>>>>>[Book{id=1, name='西游记', author='吴承恩'}] booksTwo>>>>>>[Book{id=1, name='红楼梦', author='曹雪芹'}]
对比一下数据库中的数据:
可以看到数据已经成功取出来了,这表明JdbcTemplate配置多数据源成功。
Mybatis多数据源 JdbcTemplate可以配置多数据源,同样Mybatis也是可以的,只是步骤就稍微复杂一些。
第一步,创建数据库。 使用下面的SQL语句来手动创建两个数据库和表:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 drop database if exists mybatisone; create database mybatisone; use mybatisone; drop table if exists book; create table book( id int(11) not null auto_increment comment 'id', name varchar(128) default null comment '名称', author varchar(64) default null comment '作者', primary key(id) )ENGINE=INNODB default charset=utf8; insert into book(id,name,author)values(1,"西游记","吴承恩"); drop database if exists mybatistwo; create database mybatistwo; use mybatistwo; drop table if exists book; create table book( id int(11) not null auto_increment comment 'id', name varchar(128) default null comment '名称', author varchar(64) default null comment '作者', primary key(id) )ENGINE=INNODB default charset=utf8; insert into book(id,name,author)values(1,"红楼梦","曹雪芹");
执行该SQL语句后,可以看出数据库中的信息如下所示:
第二步,创建SpringBoot项目并添加依赖。 使用spring Initializr
构建工具构建一个SpringBoot的Web应用,名称为mybatismorespringboot
,然后在pom.xml文件中添加如下依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--添加mybatis依赖--> <dependency> <groupId>org.mybatis.spring.boot</groupId> <artifactId>mybatis-spring-boot-starter</artifactId> <version>1.3.2</version> </dependency> <!--添加数据库驱动依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <!--添加数据库连接池依赖--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency>
请注意这里添加的数据库连接池依赖是druid-spring-boot-starter
。druid-spring-boot-starter
可以帮助开发者在SpringBoot项目中轻松集成Druid数据库连接池和监控。
第三步,配置数据库连接。 在application.properties
配置文件中配置多个数据源的信息:
1 2 3 4 5 6 7 8 9 10 # 数据源1 spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.one.url=jdbc:mysql://127.0.0.1:3306/mybatisone?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.one.username=root spring.datasource.one.password=1234 # 数据源2 spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.two.url=jdbc:mysql://127.0.0.1:3306/mybatistwo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.two.username=root spring.datasource.two.password=1234
这里配置了两个数据源,主要区别是数据库不同,其他都是一样的。
第四步,配置数据源。 新建一个config包,并在里面创建一个DataSourceConfig
类,用于配置数据源,这样就可以根据application.properties
文件来生成对应的DataSource。里面的代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 @Configuration public class DataSourceConfig { @Bean @ConfigurationProperties("spring.datasource.one") public DataSource dsOne(){ return DruidDataSourceBuilder.create().build(); } @Bean @ConfigurationProperties("spring.datasource.two") public DataSource dsTwo(){ return DruidDataSourceBuilder.create().build(); } }
简单解释一下上述代码的含义:
请注意DataSource是javax.sql.DataSource
包内的;
DataSourceConfig
类中提供了两个数据源:dsOne和dsTwo,默认的方法名就是实例名。
@ConfigurationProperties
注解表示使用不同前缀的配置文件来创建不同的DataSource实例。
第五步,创建Mybatis配置。 在Jdbc Template
多数据源的配置中这一步就是用来返回Jdbc Template
,但是Mybatis中这一步是用来提供SqlSessionFactory
实例和SqlSessionTemplate
实例。在config包内新建两个配置类:MybatisConfigOne
和MybatisConfigTwo
,分别用于返回对应数据源的SqlSessionFactory
实例和SqlSessionTemplate
实例。这里以MybatisConfigOne
配置类中的代码为例进行解释说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 @Configuration @MapperScan(value = "com.envy.mybatismorespringboot.mapper1",sqlSessionFactoryRef = "sqlSessionFactoryBean1") public class MybatisConfigOne { @Autowired @Qualifier("dsOne") DataSource dsOne; @Bean SqlSessionFactory sqlSessionFactoryBean1() throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dsOne); return factoryBean.getObject(); } @Bean SqlSessionTemplate sqlSessionTemplate1() throws Exception { return new SqlSessionTemplate(sqlSessionFactoryBean1()); } }
@Configuration
注解表明这个类是一个配置类,@MapperScan
注解用于指名包的扫描路径,即mapper接口所在的位置。同时使用sqlSessionFactoryRef
来指定该位置下的mapper将使用SqlSessionFactory
实例。然后定义了一个sqlSessionFactoryBean1
方法用于返回一个SqlSessionFactory
对象,在这个方法中通过factoryBean.setDataSource
方法将DataSource给注入进去,请注意这里创建的SqlSessionFactory
实例,其实也就是@MapperScan
注解中sqlSessionFactoryRef
参数指定的实例。最后提供了一个sqlSessionTemplate1
方法,该方法用于返回一个SqlSessionTemplate
实例,这是一个线程安全类,主要用来管理Mybatis中的SqlSession操作。
MybatisConfigTwo中的代码与前面MybatisConfigOne中的差不多,这里仅仅附上代码,就不做多解释:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 @Configuration @MapperScan(value = "com.envy.mybatismorespringboot.mapper2",sqlSessionFactoryRef = "sqlSessionFactoryBean2") public class MybatisConfigTwo { @Autowired @Qualifier("dsTwo") DataSource dsTwo; @Bean public SqlSessionFactory sqlSessionFactoryBean2() throws Exception { SqlSessionFactoryBean factoryBean = new SqlSessionFactoryBean(); factoryBean.setDataSource(dsTwo); return factoryBean.getObject(); } @Bean public SqlSessionTemplate sqlSessionTemplate2() throws Exception { return new SqlSessionTemplate(sqlSessionFactoryBean2()); } }
第六步,创建Book实体类。 新建pojo包,并在里面创建Book实体类,里面的代码为:
1 2 3 4 5 6 public class Book { private Integer id; private String name; private String author; //getter、setter和toString方法 }
第七步,创建数据库访问层。 新建两个mapper包:mapper1和mapper2,并在里面新建对应的mapper接口和xml文件。其中mapper1包内的BookMapper.java文件中的代码为:
1 2 3 4 5 @Component @Mapper public interface BookMapper { List<Book> getAllBooks(); }
mapper1包内的BookMapper.xml文件中的代码为:
1 2 3 4 5 6 7 8 <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.envy.mybatismorespringboot.mapper1.BookMapper"> <select id="getAllBooks" resultType="com.envy.mybatismorespringboot.pojo.Book"> select * from book </select> </mapper>
便于简化操作和演示,此处仅仅是配置了一个方法。mapper2包内的BookMapper2.java文件和BookMapper2.xml文件中的代码与上述非常相似,这里就不粘贴了,仅仅粘贴项目的目录结构:
第八步,配置pom.xml文件,这一步很重要。 在Maven工程中,XML配置文件建议写在resources目录下,但是很明显上述的BookMapper.xml
文件写在了mapper包内,且不在resources目录下,此时运行项目肯定会抛出mapper文件找不到的异常,因为Maven运行时会忽略包内的xml文件,因此需要在pom.xml文件中重新指明资源文件的位置:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <build> <!--使用mybatis时需要手动指明xml的位置--> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> </resource> </resources> </build>
第九步,创建Controller层。 在controller包内新建BookController
类,这里同样没有service层,因此是直接将Mapper注入到Controller中。里面的代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 @RestController public class BookController { @Autowired BookMapper bookMapper; @Autowired BookMapper2 bookMapper2; @GetMapping("/test") public void test(){ List<Book> bookList1 = bookMapper.getAllBooks(); List<Book> bookList2 = bookMapper2.getAllBooks(); System.out.println("【bookList1】>>>>>>"+bookList1); System.out.println("【bookList2】>>>>>>"+bookList2); } }
第十步,运行项目。 运行项目,在浏览器地址栏中输入http://localhost:8080/test
,然后查看控制台的输出信息为:
1 2 【bookList1】>>>>>>[Book{id=1, name='西游记', author='吴承恩'}] 【bookList2】>>>>>>[Book{id=1, name='红楼梦', author='曹雪芹'}]
对比一下数据库中的数据:
可以看到数据已经成功取出来了,这表明Mybatis配置多数据源成功。
Spring Data JPA多数据源 JPA和Mybatis配置多数据源非常类似,只是JPA配置时主要提供LocalContainerEntityManagerFactoryBean
以及事务管理器,具体的配置如下:
第一步,创建数据库,不创建表。 使用下面的SQL语句来手动创建两个数据库:
1 2 3 4 5 drop database if exists jpaone; create database jpaone; drop database if exists jpatwo; create database jpatwo;
执行该SQL语句后,可以看出数据库中已经有这两个数据库了。
第二步,创建SpringBoot项目并添加依赖。 使用spring Initializr
构建工具构建一个SpringBoot的Web应用,名称为jpamorespringboot
,然后在pom.xml文件中添加如下依赖:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!--添加数据库驱动依赖--> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <!--添加数据库连接池依赖--> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!--添加Spring Data JPA依赖--> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <!--添加lombok依赖--> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency>
请注意这里添加的数据库连接池依赖是druid-spring-boot-starter
。druid-spring-boot-starter
可以帮助开发者在SpringBoot项目中轻松集成Druid数据库连接池和监控。
第三步,配置数据库连接。 在application.properties
配置文件中配置多个数据源及JPA的配置信息:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 # 数据源1 spring.datasource.one.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.one.url=jdbc:mysql://127.0.0.1:3306/jpaone?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.one.username=root spring.datasource.one.password=1234 # 数据源2 spring.datasource.two.type=com.alibaba.druid.pool.DruidDataSource spring.datasource.two.url=jdbc:mysql://127.0.0.1:3306/jpatwo?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC spring.datasource.two.username=root spring.datasource.two.password=1234 # JPA相关配置 spring.jpa.properties.hibernate.dialect.MySQL57InnoDBDialect spring.jpa.properties.database=mysql spring.jpa.properties.hibernate.hbm2ddl.auto=update spring.jpa.properties.show-sql=true
这里配置了两个数据源,主要区别是数据库不同,其他都是一样的。不过需要注意的是JPA多数据源配置与单独的JPA配置有所不同,因为后续的配置要从JpaProperties
中的getProperties
方法中获取所有JPA相关的配置,因此这里的属性前缀都是spring.jpa.properties
。
第四步,配置数据源。 新建一个config包,并在里面创建一个DataSourceConfig
类,用于配置数据源,这样就可以根据application.properties
文件来生成对应的DataSource。里面的代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 @Configuration public class DataSourceConfig { @Bean @ConfigurationProperties("spring.datasource.one") @Primary public DataSource dsOne(){ return DruidDataSourceBuilder.create().build(); } @Bean @ConfigurationProperties("spring.datasource.two") public DataSource dsTwo(){ return DruidDataSourceBuilder.create().build(); } }
不知道你是否注意到,此处在dsOne方法上添加了@Primary
注解。默认的@Autowired
注解是依据类型进行注入,但是此处存在多个类型相同的对象,因此必须使用@Primary
注解来指定优先注入哪个。
第五步,创建Book实体类。 新建pojo包,并在里面创建Book实体类,里面的代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 @Entity(name = "t_user") @Data public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Integer id; private String name; private String gender; private Integer age; }
这样后续会根据实体类在数据库中创建t_user表,表中的id字段自增长。
第六步,创建JPA配置。 接下来是核心配置,根据两个配置好的数据源来创建两个不同的JPA配置。在config包内,新建两个JPA的配置类:JpaOneConfig
和JpaTwoConfig
,用于返回LocalContainerEntityManagerFactoryBean
及事务管理器对象。下面以JpaOneConfig
配置类中的代码为例进行解释说明:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 @Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.envy.jpamorespringboot.dao1",entityManagerFactoryRef = "entityManagerFactoryBeanOne",transactionManagerRef = "platformTransactionManagerOne") public class JpaOneConfig { @Resource(name = "dsOne") DataSource dsOne; @Autowired JpaProperties jpaProperties; @Bean @Primary LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanOne(EntityManagerFactoryBuilder builder){ return builder.dataSource(dsOne) .properties(jpaProperties.getProperties()) .packages("com.envy.jpamorespringboot.pojo") .persistenceUnit("pu1") .build(); } @Bean PlatformTransactionManager platformTransactionManagerOne(EntityManagerFactoryBuilder builder){ LocalContainerEntityManagerFactoryBean factoryOne = entityManagerFactoryBeanOne(builder); return new JpaTransactionManager(factoryOne.getObject()); } }
解释一下上述代码的含义:
使用@Configuration
注解来标识这是一个配置类,接着使用@EnableJpaRepositories
注解来进行JPA的配置,该注解中主要配置三个属性:basePackages
、entityManagerFactoryRef
和transactionManagerRef
。其中basePackages
属性用于指定Repository的所在位置,entityManagerFactoryRef
属性用于指定实体类管理工厂Bean的名称,transactionManagerRef
属性则用来指定事务管理器的引用名称,这里的引用名称就是JpaOneConfig类中注册的Bean的名称(默认的Bean名称为方法名)。
然后创建entityManagerFactoryBeanOne
方法,用于生成一个LocalContainerEntityManagerFactoryBean
对象,而该对象用来提供EntityManager
实例,在该类的创建过程中,首先配置数据源,然后设置JPA相关配置(JpaProperties由系统自动加载),再设置实体类所在的位置,最后配置持久化单元名,若项目中只有一个EntityManagerFactory
,则persistenceUnit
可以省略掉,若有多个,则必须明确指定持久化单元名。
由于项目中会提供两个LocalContainerEntityManagerFactoryBean
实例,故需要在entityManagerFactoryBeanOne
方法上添加@Primary
注释,用于告诉Spring容器时优先使用该实例。
platformTransactionManagerOne
方法用于返回一个PlatformTransactionManager
对象,实际上返回的是一个JpaTransactionManager
对象,它提供对单个EntityManagerFactory
的事务支持,专门用于解决JPA中的事务管理。
上面是第一个JPA的配置信息,第二个JPA的配置与之相似,故这里仅仅只粘贴代码(需要注意的是第二个JPA类中的entityManagerFactoryBeanOne
方法上不能添加@Primary
注解):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 @Configuration @EnableTransactionManagement @EnableJpaRepositories(basePackages = "com.envy.jpamorespringboot.dao2",entityManagerFactoryRef = "entityManagerFactoryBeanTwo",transactionManagerRef = "platformTransactionManagerTwo") public class JpaTwoConfig { @Resource(name = "dsTwo") DataSource dsTwo; @Autowired JpaProperties jpaProperties; @Bean LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanTwo(EntityManagerFactoryBuilder builder){ return builder.dataSource(dsTwo) .properties(jpaProperties.getProperties()) .packages("com.envy.jpamorespringboot.pojo") .persistenceUnit("pu2") .build(); } @Bean PlatformTransactionManager platformTransactionManagerTwo(EntityManagerFactoryBuilder builder){ LocalContainerEntityManagerFactoryBean factoryOne = entityManagerFactoryBeanTwo(builder); return new JpaTransactionManager(factoryOne.getObject()); } }
第七步,创建Repository。 新建dao1和dao2包,并分别在其中新建UserDao和UserDao2接口文件。其中UserDao.java
中的代码为:
1 2 3 4 5 6 7 package com.envy.jpamorespringboot.dao1; import com.envy.jpamorespringboot.pojo.User; import org.springframework.data.jpa.repository.JpaRepository; public interface UserDao extends JpaRepository<User,Integer> { }
其中UserDao2.java
中的代码为:
1 2 3 4 5 6 7 package com.envy.jpamorespringboot.dao2; import com.envy.jpamorespringboot.pojo.User; import org.springframework.data.jpa.repository.JpaRepository; public interface UserDao2 extends JpaRepository<User,Integer> { }
其中UserDao
和UserDao2
分别用于操作不同的数据源。这里粘贴一下此时的目录结构:
第八步,创建Controller。 便于演示和简便,这里就省略Service层,将UserDao直接注入Controller层。新建controller包,并在里面新建UserController.java
文件,里面的代码为:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 @RestController public class UserController { @Autowired private UserDao userDao; @Autowired private UserDao2 userDao2; @GetMapping("/test") public void test(){ User user1 = new User(); user1.setName("小明"); user1.setAge(20); user1.setGender("男"); userDao.save(user1); User user2 = new User(); user2.setName("小美"); user2.setAge(18); user2.setGender("女"); userDao2.save(user2); } }
第九步,运行项目。 运行项目,在浏览器地址栏中输入http://localhost:8080/test
,然后查看数据库是否已经有了这两条记录:
总结 本篇学习了如何在SpringBoot中整合Jdbc Template
、Mybatis
和Spring Data JPA
的多数据源配置,其中Jdbc Template
用的不是很多,基本上不会使用了;而Mybatis
由于其灵活性较好,能进行SQL优化,因此如果开发者需要考虑SQL的性能,建议选用这个。Spring Data JPA
使用起来较为方便,几乎不需要书写SQL语句,特别适合快速开发一个RESTful风格的应用,这一点在实际工作中深有体会。