转自:https://www.jianshu.com/p/34730e595a8c

之前在介绍使用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)); } }

完整示例:Chapter3-2-3

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()); } }

完整示例:Chapter3-2-4

springboot多数据源的配置与使用的更多相关文章

  1. springboot连接数据源,配置数据库

    Spring官方DriverManagerDataSource的配置 修改yml #配置数据源的属性 spring: datasource: driver-class-name: com.mysql. ...

  2. SpringBoot数据源相关配置

    数据源配置 单数据源 配置步骤 引入依赖:H2数据库驱动.JDBC依赖.acturator(运维).web模块(用于测试).lambok(使用@Slf4j打印日志). 直接配置所需的Bean,注入容器 ...

  3. SpringBoot系列七:SpringBoot 整合 MyBatis(配置 druid 数据源、配置 MyBatis、事务控制、druid 监控)

    1.概念:SpringBoot 整合 MyBatis 2.背景 SpringBoot 得到最终效果是一个简化到极致的 WEB 开发,但是只要牵扯到 WEB 开发,就绝对不可能缺少数据层操作,所有的开发 ...

  4. Springboot spring data jpa 多数据源的配置01

    Springboot spring data jpa 多数据源的配置 (说明:这只是引入了多个数据源,他们各自管理各自的事务,并没有实现统一的事务控制) 例: user数据库   global 数据库 ...

  5. 接管SpringBoot对Activiti的数据源自动配置

    SpringBoot的自动配置真的让人又爱又恨,但还是爱更多一点. SpringBoot想要帮我们自动配置好一切,但是有时候配置的却并不是我们需要的,甚至有时候会默默的坑我们. 我的项目是一个多数据源 ...

  6. Spring-Boot 多数据源配置+动态数据源切换+多数据源事物配置实现主从数据库存储分离

    一.基础介绍 多数据源字面意思,比如说二个数据库,甚至不同类型的数据库.在用SpringBoot开发项目时,随着业务量的扩大,我们通常会进行数据库拆分或是引入其他数据库,从而我们需要配置多个数据源. ...

  7. Springboot 多数据源配置,结合tk-mybatis

    一.前言 作为一个资深的CRUD工程师,我们在实际使用springboot开发项目的时候,难免会遇到同时使用多个数据库的情况,比如前脚刚查询mysql,后脚就要查询sqlserver. 这时,我们很直 ...

  8. springboot+mybatis +yml文件配置多数据源

    记录一下java开发中多数据源的配置过程, 参考博客:https://blog.csdn.net/weinichendian/article/details/72903757,我在这里进行了整理,使用 ...

  9. springboot情操陶冶-web配置(六)

    本文则针对数据库的连接配置作下简单的分析,方便笔者理解以及后续的查阅 栗子当先 以我们经常用的mybatis数据库持久框架来操作mysql服务为例 环境依赖 1.JDK v1.8+ 2.springb ...

随机推荐

  1. java 记录

    1.spring ide 的安装图解 https://blog.csdn.net/u012369373/article/details/55097380 2.ssm框架配置内容 http://www. ...

  2. 九、cent OS下tomcat改变日志目录

    修改catalina.out的目录bin目录下修改catalina.sh:CATALINA_OUT="$CATALINA_BASE"/logs/catalina.out  此行内的 ...

  3. DataTables固定表格宽度(设置横向滚动条)

    当表格的列比较多的时候,可能就需要固定表格的宽度了,默认的100%宽已经不适应了.默认的100%宽要实现改变窗口大小也100%的话,在table元素上添加width="100%", ...

  4. Oracle中实现find_in_set

    CREATE OR REPLACE FUNCTION FIND_IN_SET(piv_str1 varchar2, piv_str2 varchar2, p_sep varchar2 := ',') ...

  5. LeetCode Find Peak Element [TBD]

    说要写成对数时间复杂度,算了想不出来,写个O(n)的水了 class Solution { public: int findPeakElement(const vector<int> &a ...

  6. mysql 笔记3

    --建库create database dsdb DEFAULT CHARACTER set utf8 collate utf8_general_ci;/*删除数据库drop DATABASE 数据库 ...

  7. java TreeSet 实现存自定义不可重复数据

    本文主要是介绍一下java集合中的比较重要的Set接口下的可实现类TreeSet TreeSet类,底层用二叉树的数据结构 * 集合中以有序的方式插入和抽取元素. * 添加到TreeSet中的元素必须 ...

  8. electron之20190320

    一.sudo npm i electron -g一直失败 最终解决办法:使用了sudo cnpm i electron -g安装成功 原因不详 二.打包问题 1.使用electron-packager ...

  9. Google自写插件详解

    谷歌插件详解,跳转至个人主页查看. GoogleExtension

  10. cookie结合js 实现记住的拖拽

    哈喽!!!我胡汉三又回来啦!!!有木有记挂挪啊!咱们今天说一个 cookie结合JS的小案例哦! 话不多说直接上代码: <!DOCTYPE html> <html> <h ...