之前在介绍使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源。在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.properties文件中配置连接参数即可。但是往往随着业务量发展,我们通常会进行数据库拆分或是引入其他数据库,从而我们需要配置多个数据源,下面基于之前的JdbcTemplate和Spring-data-jpa例子分别介绍两种多数据源的配置方式。

多数据源配置

创建一个Spring配置类,定义两个DataSource用来读取application.properties中的不同配置。如下例子中,主数据源配置为spring.datasource.primary开头的配置,第二数据源配置为spring.datasource.secondary开头的配置。

@Configurationpublic 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/test1spring.datasource.primary.username=rootspring.datasource.primary.password=rootspring.datasource.primary.driver-class-name=com.mysql.jdbc.Driver

spring.datasource.secondary.url=jdbc:mysql://localhost:3306/test2spring.datasource.secondary.username=rootspring.datasource.secondary.password=rootspring.datasource.secondary.driver-class-name=com.mysql.jdbc.Driver

JdbcTemplate支持

对JdbcTemplate的支持比较简单,只需要为其注入对应的datasource即可,如下例子,在创建JdbcTemplate的时候分别注入名为primaryDataSourcesecondaryDataSource的数据源来区分不同的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目录:

  • Github:https://github.com/dyc87112/SpringBoot-Learning
  • Gitee:https://gitee.com/didispace/SpringBoot-Learning

如果您觉得本文不错,欢迎Star支持,您的关注是我坚持的动力!

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接口
@Entitypublic 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接口
@Entitypublic 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目录:

  • Github:https://github.com/dyc87112/SpringBoot-Learning
  • Gitee:https://gitee.com/didispace/SpringBoot-Learning

如果您觉得本文不错,欢迎Star支持,您的关注是我坚持的动力!


Spring Boot多数据源配置与使用相关推荐

  1. spring boot多数据源配置示例

    spring boot多数据源配置 1.application.properties spring.datasource.url = jdbc\:oracle\:thin\:@192.168.3.88 ...

  2. spring boot多数据源配置(mysql,redis,mongodb)实战

    使用Spring Boot Starter提升效率 虽然不同的starter实现起来各有差异,但是他们基本上都会使用到两个相同的内容:ConfigurationProperties和AutoConfi ...

  3. 企业分布式微服务云SpringCloud SpringBoot mybatis (九)Spring Boot多数据源配置与使用(JdbcTemplate支持)...

    之前在介绍使用JdbcTemplate和Spring-data-jpa时,都使用了单数据源.在单数据源的情况下,Spring Boot的配置非常简单,只需要在application.propertie ...

  4. Spring Boot多数据源配置并通过注解实现动态切换数据源

    文章目录 1. AbstractRoutingDataSource类介绍 2. ThreadLocal类介绍 3. 环境准备 3.1 数据库准备 3.2 项目创建 4. 具体实现 4.1 定义数据源枚 ...

  5. 企业分布式微服务云SpringCloud SpringBoot mybatis (十)Spring Boot多数据源配置与使用Spring-data-jpa支持...

    Spring-data-jpa支持 对于数据源的配置可以沿用上例中DataSourceConfig的实现. 新增对第一数据源的JPA配置,注意两处注释的地方,用于指定数据源对应的Entity实体和Re ...

  6. Spring Boot使用spring-data-jpa配置Mysql多数据源

    转载请注明出处 :Spring Boot使用spring-data-jpa配置Mysql多数据源 我们在之前的文章中已经学习了Spring Boot中使用mysql数据库 在单数据源的情况下,Spri ...

  7. 自定义spring boot的自动配置

    文章目录 添加Maven依赖 创建自定义 Auto-Configuration 添加Class Conditions 添加 bean Conditions Property Conditions Re ...

  8. boot jndi数据源 spring_spring boot多数据源配置(mysql,redis,mongodb)实战

    使用Spring Boot Starter提升效率 虽然不同的starter实现起来各有差异,但是他们基本上都会使用到两个相同的内容:ConfigurationProperties和AutoConfi ...

  9. Spring Boot 多数据源(读写分离)入门

    转载自  芋道 Spring Boot 多数据源(读写分离)入门 1. 概述 在项目中,我们可能会碰到需要多数据源的场景.例如说: 读写分离:数据库主节点压力比较大,需要增加从节点提供读操作,以减少压 ...

最新文章

  1. 只需2小时,成本不到7块,你我皆可制作的3D机器人
  2. Ubuntu 18.04 搭建 gitlab服务器记录
  3. 9 10次c语言上机作业答案,C语言第五次上机作业参考答案
  4. 使用 VSCode 编写 .NET Core 项目之初体验
  5. springcloud Hystrix Dashboard微服务监控
  6. JAVA企业级快速开发平台,JEECG 3.7.3 新春版本发布
  7. python 多列对齐_python – 如何连接两个数据帧并在这样的特定列上对齐?
  8. I.MX6 wm8962 0-001a: DC servo timed out
  9. 20最佳代码审查工具-专门为开发人员准备
  10. 快速切换npm源的开源工具--nrm
  11. xgboost兼具线性规模求解器和树学习算法,GBDT 方法只利用了一阶的导数信息,Xgboost 则是对损失函 数做了二阶的泰勒展开,并在目标函数之外加入了正 则项,整体求最优解,用于权衡目标函数的
  12. 毕业论文Word排版专题
  13. Win11怎么添加pdf虚拟打印机
  14. 病毒分析--WannaCry分析--1
  15. modalpopup控件使用时的pannel设置问题
  16. Unity编辑器扩展——在Editor下动态添加监听事件
  17. 孤岛双馈风电机组数学模型matlab,大型变速双馈风电机组动态稳定性仿真分析
  18. 世界地图的制作(总体概念设计)
  19. 身份证识别SDK——混合非原生调用
  20. web端自动化测试框架之selenium4从入门到项目实战-3- unittest使用

热门文章

  1. Qt 图形特效(Graphics Effect)介绍
  2. EBS业务学习之应收管理
  3. 实战 SQL Server 2008 数据库误删除数据的恢复 (转)
  4. windows服务编程 注册InstallUtil.exe
  5. 二分法查找(Java)
  6. C/C++二维数组名和二级指针的联系与区别
  7. gitlab 如何关闭force push
  8. linux c语言内核函数,2014-1-5_linux内核学习(1)_C语言基础
  9. isfull mysql_MySQL数据库之MySQL 出现 The table is full 的解决方法
  10. 智慧交通day03-车道线检测实现02-1:相机校正