gpt4 book ai didi

详解spring boot实现多数据源代码实战

转载 作者:qq735679552 更新时间:2022-09-28 22:32:09 25 4
gpt4 key购买 nike

CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.

这篇CFSDN的博客文章详解spring boot实现多数据源代码实战由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.

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

多数据源配置 。

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@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配置如下:

?
1
2
3
4
5
6
7
8
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.

?
1
2
3
4
5
6
7
8
9
10
@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.

?
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
@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区分主数据源.

新增对第二数据源的JPA配置,内容与第一数据源类似,具体如下:

?
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
28
29
30
31
32
@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接口 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
@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接口 。

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
@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> {
}

接下来通过测试用例来验证使用这两个针对不同数据源的配置进行数据操作.

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
@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.cnn6.net/html/java/2017723/202385.html 。

最后此篇关于详解spring boot实现多数据源代码实战的文章就讲到这里了,如果你想了解更多关于详解spring boot实现多数据源代码实战的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com