spring boot 多数据源配置与使用
在介绍使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源。在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.properties文件中配置连接参数即可。但是往往随着业务量发展,我们通常会进行数据库拆分或是引入其他数据库,从而我们需要配置多个数据源,下面基于之前的JdbcTemplate和Spring-data-jpa例子分别介绍两种多数据源的配置方式。
多数据源配置
创建一个Spring配置类,定义两个DataSource用来读取application.properties中的不同配置。如下例子中,主数据源配置为spring.datasource.primary开头的配置,第二数据源配置为spring.datasource.secondary开头的配置。
@Configuration
public class DataSourceConfig {
@Bean(name = "primaryDataSource")
@Qualifier("primaryDataSource")
@ConfigurationProperties(prefix="spring.datasource.primary")
public DataSource primaryDataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "secondaryDataSource")
@Qualifier("secondaryDataSource")
@Primary
@ConfigurationProperties(prefix="spring.datasource.secondary")
public DataSource secondaryDataSource() {
return DataSourceBuilder.create().build();
}
}
对应的application.properties配置如下:
spring.datasource.primary.url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=root
spring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver
spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=root
spring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver
JdbcTemplate支持
对JdbcTemplate的支持比较简单,只需要为其注入对应的datasource即可,如下例子,在创建JdbcTemplate的时候分别注入名为primaryDataSource和secondaryDataSource的数据源来区分不同的JdbcTemplate。
@Bean(name = "primaryJdbcTemplate")
public JdbcTemplate primaryJdbcTemplate(
@Qualifier("primaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean(name = "secondaryJdbcTemplate")
public JdbcTemplate secondaryJdbcTemplate(
@Qualifier("secondaryDataSource") DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
接下来通过测试用例来演示如何使用这两个针对不同数据源的JdbcTemplate。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTests {
@Autowired
@Qualifier("primaryJdbcTemplate")
protected JdbcTemplate jdbcTemplate1;
@Autowired
@Qualifier("secondaryJdbcTemplate")
protected JdbcTemplate jdbcTemplate2;
@Before
public void setUp() {
jdbcTemplate1.update("DELETE FROM USER ");
jdbcTemplate2.update("DELETE FROM USER ");
}
@Test
public void test() throws Exception {
// 往第一个数据源中插入两条数据
jdbcTemplate1.update("insert into user(id,name,age) values(?, ?, ?)", 1, "aaa", 20);
jdbcTemplate1.update("insert into user(id,name,age) values(?, ?, ?)", 2, "bbb", 30);
// 往第二个数据源中插入一条数据,若插入的是第一个数据源,则会主键冲突报错
jdbcTemplate2.update("insert into user(id,name,age) values(?, ?, ?)", 1, "aaa", 20);
// 查一下第一个数据源中是否有两条数据,验证插入是否成功
Assert.assertEquals("2", jdbcTemplate1.queryForObject("select count(1) from user", String.class));
// 查一下第一个数据源中是否有两条数据,验证插入是否成功
Assert.assertEquals("1", jdbcTemplate2.queryForObject("select count(1) from user", String.class));
}
}
Spring-data-jpa支持
对于数据源的配置可以沿用上例中DataSourceConfig的实现。
新增对第一数据源的JPA配置,注意两处注释的地方,用于指定数据源对应的Entity实体和Repository定义位置,用@Primary区分主数据源。
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactoryPrimary",
transactionManagerRef="transactionManagerPrimary",
basePackages= { "com.didispace.domain.p" }) //设置Repository所在位置
public class PrimaryConfig {
@Autowired @Qualifier("primaryDataSource")
private DataSource primaryDataSource;
@Primary
@Bean(name = "entityManagerPrimary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Primary
@Bean(name = "entityManagerFactoryPrimary")
public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary (EntityManagerFactoryBuilder builder) {
return builder
.dataSource(primaryDataSource)
.properties(getVendorProperties(primaryDataSource))
.packages("com.didispace.domain.p") //设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
@Autowired
private JpaProperties jpaProperties;
private Map<String, String> getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}
@Primary
@Bean(name = "transactionManagerPrimary")
public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
新增对第二数据源的JPA配置,内容与第一数据源类似,具体如下:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactorySecondary",
transactionManagerRef="transactionManagerSecondary",
basePackages= { "com.didispace.domain.s" }) //设置Repository所在位置
public class SecondaryConfig {
@Autowired @Qualifier("secondaryDataSource")
private DataSource secondaryDataSource;
@Bean(name = "entityManagerSecondary")
public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
return entityManagerFactorySecondary(builder).getObject().createEntityManager();
}
@Bean(name = "entityManagerFactorySecondary")
public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary (EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondaryDataSource)
.properties(getVendorProperties(secondaryDataSource))
.packages("com.didispace.domain.s") //设置实体类所在位置
.persistenceUnit("secondaryPersistenceUnit")
.build();
}
@Autowired
private JpaProperties jpaProperties;
private Map<String, String> getVendorProperties(DataSource dataSource) {
return jpaProperties.getHibernateProperties(dataSource);
}
@Bean(name = "transactionManagerSecondary")
PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
完成了以上配置之后,主数据源的实体和数据访问对象位于:com.didispace.domain.p,次数据源的实体和数据访问接口位于:com.didispace.domain.s。
分别在这两个package下创建各自的实体和数据访问接口
- 主数据源下,创建User实体和对应的Repository接口
@Entity
public class User {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private Integer age;
public User(){}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
// 省略getter、setter
}
public interface UserRepository extends JpaRepository<User, Long> {
}
- 从数据源下,创建Message实体和对应的Repository接口
@Entity
public class Message {
@Id
@GeneratedValue
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
private String content;
public Message(){}
public Message(String name, String content) {
this.name = name;
this.content = content;
}
// 省略getter、setter
}
public interface MessageRepository extends JpaRepository<Message, Long> {
}
接下来通过测试用例来验证使用这两个针对不同数据源的配置进行数据操作。
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(Application.class)
public class ApplicationTests {
@Autowired
private UserRepository userRepository;
@Autowired
private MessageRepository messageRepository;
@Test
public void test() throws Exception {
userRepository.save(new User("aaa", 10));
userRepository.save(new User("bbb", 20));
userRepository.save(new User("ccc", 30));
userRepository.save(new User("ddd", 40));
userRepository.save(new User("eee", 50));
Assert.assertEquals(5, userRepository.findAll().size());
messageRepository.save(new Message("o1", "aaaaaaaaaa"));
messageRepository.save(new Message("o2", "bbbbbbbbbb"));
messageRepository.save(new Message("o3", "cccccccccc"));
Assert.assertEquals(3, messageRepository.findAll().size());
}
}
spring boot 多数据源配置与使用的更多相关文章
- Spring Boot多数据源配置(二)MongoDB
在Spring Boot多数据源配置(一)durid.mysql.jpa 整合中已经讲过了Spring Boot如何配置mysql多数据源.本篇文章讲一下Spring Boot如何配置mongoDB多 ...
- spring boot多数据源配置(mysql,redis,mongodb)实战
使用Spring Boot Starter提升效率 虽然不同的starter实现起来各有差异,但是他们基本上都会使用到两个相同的内容:ConfigurationProperties和AutoConfi ...
- spring boot(12)-数据源配置原理
本篇讲的不仅是数据源配置,这也是spring boot实现自动配置的一部分.要理解数据源的配置原理,首先要理解第十篇tomcat连接池的配置 数据源配置源码 这里截取org.springframewo ...
- 三、Spring Boot 多数据源配置
下面一个Java类是已经写好的根据配置文件动态创建多dataSource的代码,其原理也很简单,就是读取配置文件,根据配置文件中配置的数据源数量,动态创建dataSource并注册到Spring中. ...
- Spring Boot Druid数据源配置
package com.hgvip.config; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.druid.su ...
- 21. Spring Boot Druid 数据源配置解析
1.数据源配置属性类源码 package org.springframework.boot.autoconfigure.jdbc; @ConfigurationProperties( prefix = ...
- Spring Boot多数据源配置与使用
在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.properties文件中配置连接参数即可.但是往往随着业务量发展,我们通常会进行数据库拆分或是引入其他数据库 ...
- Spring Boot (14) 数据源配置原理
数据源配置源码 这里截取org.springframework.boot.autoconfigure.jdbc.DataSourceConfiguration的部分源码,主要介绍Tomcat和Hika ...
- Spring Boot多数据源配置(一)durid、mysql、jpa整合
目前在做一个统计项目.需要多数据源整合,其中包括mysql和mongo.本节先讲mysql.durid.jpa与spring-boot的整合. 引入Durid包 <dependency> ...
随机推荐
- size_t和unsigned int区别
size_t和unsigned int有所不同,size_t的取值range是目标平台下最大可能的数组尺寸,一些平台下size_t的范围小于int的正数范围,又或者大于unsigned int.最典型 ...
- oracle 之 安装后pl/sql登录报ora-12154
这个问题一开始困扰了很久. 查的资料是复制一小段代码到tnsnames.ora中 SID名 = (DESCRIPTION = (ADDRESS = (PROTOCOL = TCP)(HOST = ...
- C# 各种控件实现可拖动和调整大小
http://www.360doc.com/content/18/0516/12/55659281_754382494.shtml using System; using System.Collect ...
- [implements] - 一个接口的使用
4种货物,如何使用一个接口实现CRUD: package com.tansuo365.test1.service.goods; import com.tansuo365.test1.entity.Go ...
- redis简介(未完成)
redis是一个用c语言开发的一个开源的高性能键值对(key-value)数据库,基本类型: 1)字符串型 string 2)字符串列表 lists 3)字符串集合 sets 4)有序字符串集合 so ...
- python 正则表达式规则收集
python正则表达式基本元字符 . 通配符,匹配所有字符 ^abc 匹配以abc开始的字符串 abc$ 匹配以abc结尾的字符串 [abc] 匹配字符集合 [A-Z0-9] 匹配字符范围 ...
- arcgis 属性表字段值计算
1 如果你用VBSCRIPT的代码,那就在对应的选择项目处选择下,如果是PYTHON代码,就在另外一点点一下.如果弄混了,显然代码会报错. 2 VBSCRIPT里面的函数非常少,但是你可以去利用这些函 ...
- NGUI实现UITexture的UV滚动
材质上使用的贴图: 效果:实现该纹理在屏幕上的滚动 代码: using System.Collections; using System.Collections.Generic; using Unit ...
- ThinkPHP的数据操作
查询: 具体数据的操作方法使用: 1. where()条件 $model->where(条件值); //条件值就是sql语句where后边的结果值 2. limit() 限制条数 $ ...
- Go语言学习之5 进阶-排序、链表、二叉树、接口
本节主要内容: 1. 结构体和方法2. 接口 1. 结构体和方法 (1). 用来自定义复杂数据结构 (2). struct里面可以包含多个字段(属性) (3). struct类型可以定 ...