多数据源配置

创建一个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()); } }

原文地址:

http://www.spring4all.com/article/253

最新文章

  1. geotrellis使用(十六)使用缓冲区分析的方式解决投影变换中边缘数据值计算的问题
  2. 几款开源的hybird移动app框架分析
  3. Windows Phone 十六、HttpClient
  4. Java Garbage Collection基础详解------Java 垃圾回收机制技术详解
  5. Framework7--Test
  6. DIOCP之数据接收事件
  7. 模拟MessageBox
  8. 大型网站系统架构实践(五)深入探讨web应用高可用方案
  9. hdu---(1800)Flying to the Mars(trie树)
  10. OnCreate
  11. 浅谈 js 正则字面量 与 new RegExp 执行效率
  12. jQuery全屏插件Textarea Fullscreen
  13. 登录SQL注入
  14. Groovy Script in SoapUI REST Testing
  15. 201521123051 《Java程序设计》第4周学习总结
  16. laravel 邮件配置
  17. 基于alpine制作php镜像
  18. centos6.5安装zabbix3.2
  19. Windows文件共享自动失效解决办法
  20. 1--常用linux命令

热门文章

  1. java零基础之--JDK安装篇
  2. MySQL审计audit
  3. 利用github给国外文件下载加速
  4. 【C++】《C++ Primer 》第九章
  5. 浅谈JVM垃圾回收
  6. version can neither be null, empty nor blank
  7. selenium爬虫 | 爬取疫情实时动态(二)
  8. 在IDEA中通过Module管理多个项目
  9. 【Linux】rsync模板配置问题
  10. OpenID协议