spring boot 已经支持多数据源配置了,无需网上好多那些编写什么类的,特别麻烦,看看如下解决方案,官方的,放心!
1.首先定义数据源配置
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
|
#=====================multiple database config============================
#ds1
first.datasource.url=jdbc:mysql: //localhost/test?characterEncoding=utf8&useSSL=true
first.datasource.username=root
first.datasource.password= 123456
first.datasource.driver- class -name=com.mysql.jdbc.Driver
first.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
first.datasource.max-wait= 10000
first.datasource.max-active= 200
first.datasource.test-on-borrow= true
first.datasource.initial-size= 10
#ds2
second.datasource.url=jdbc:mysql: //localhost/test2?characterEncoding=utf8&useSSL=true
second.datasource.username=root
second.datasource.password= 123456
second.datasource.driver- class -name=com.mysql.jdbc.Driver
second.datasource.type=org.apache.tomcat.jdbc.pool.DataSource
second.datasource.max-wait= 10000
second.datasource.max-active= 200
second.datasource.test-on-borrow= true
second.datasource.initial-size= 10
#=====================jpa config================================
#实体类维护数据库表结构的具体行为:update/create/create-drop/validate/none
spring.jpa.hibernate.ddl-auto=none
#打印sql语句
spring.jpa.show-sql= true
#格式化输出的json字符串
spring.jackson.serialization.indent_output= true
|
2.配置ds1的相关注入对象和启用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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
|
/**
* Created by hdwang on 2017-06-16.
* 第一个数据源配置
* If you are using Spring Data, you need to configure @EnableJpaRepositories
*/
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories (basePackages = "com.hdwang.dao.datajpa.firstDs" ,entityManagerFactoryRef = "firstEntityManagerFactory" ,transactionManagerRef= "firstTransactionManager" )
public class FirstDsConfig {
/**
* 数据源配置对象
* Primary 表示默认的对象,Autowire可注入,不是默认的得明确名称注入
* @return
*/
@Bean
@Primary
@ConfigurationProperties ( "first.datasource" )
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
/**
* 数据源对象
* @return
*/
@Bean
@Primary
@ConfigurationProperties ( "first.datasource" )
public DataSource firstDataSource() {
return firstDataSourceProperties().initializeDataSourceBuilder().build();
}
/**
* 实体管理对象
* @param builder 由spring注入这个对象,首先根据type注入(多个就取声明@Primary的对象),否则根据name注入
* @return
*/
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean firstEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(firstDataSource())
.packages( "com.hdwang.entity.dbFirst" )
.persistenceUnit( "firstDs" )
.build();
}
/**
* 事务管理对象
* @return
*/
@Bean (name = "firstTransactionManager" )
@Primary
public PlatformTransactionManager transactionManager(EntityManagerFactory emf){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(emf);
return transactionManager;
}
@Bean
@Primary
public JdbcTemplate jdbcTemplate(){
return new JdbcTemplate(firstDataSource());
}
@Bean
@Primary
public TransactionTemplate transactionTemplate(PlatformTransactionManager platformTransactionManager){
return new TransactionTemplate(platformTransactionManager);
}
}
|
相关知识点:
1.使用@Bean可以创建一个bean对象交给spring容器管理
2.@Bean创建的bean对象的名称默认为方法名,也可以指定
3.@Bean方法参数表示,接收一个bean对象,默认按照type类型接收注入的对象,若要修改为byName方式,可以使用@Qualifier注解注入准确的对象
4.@Primary表示该bean为此类型的默认bean,在其他地方引用的时候用@Autowired即可按照类型注入,不受同类型多个对象影响
5.EnableJpaRepositories表示启用spring data jpa的支持,也就是jpa的新使用方式,注意basePackages指的事 @Repository接口的所在包位置,可配置多个
其他注解就不清楚了!
2.配置ds2的相关注入对象和启用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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
|
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories (basePackages = "com.hdwang.dao.datajpa.secondDs" , entityManagerFactoryRef = "secondEntityManagerFactory" ,transactionManagerRef = "secondTransactionManager" )
public class SecondDsConfig {
@Bean
@ConfigurationProperties ( "second.datasource" )
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties ( "second.datasource" )
public DataSource secondDataSource() {
return secondDataSourceProperties().initializeDataSourceBuilder().build();
}
/**
* 实体管理对象
* @param builder 由spring注入这个对象,首先根据type注入(多个就取声明@Primary的对象),否则根据name注入
* @return
*/
@Bean
public LocalContainerEntityManagerFactoryBean secondEntityManagerFactory(
EntityManagerFactoryBuilder builder) {
return builder
.dataSource(secondDataSource())
.packages( "com.hdwang.entity.dbSecond" )
.persistenceUnit( "secondDs" )
.build();
}
/**
* 事物管理对象
* @param secondEntityManagerFactory 实体管理工厂对象(按照名称注入)
* @return 平台事物管理器
*/
@Bean (name = "secondTransactionManager" )
public PlatformTransactionManager transactionManager( @Qualifier ( "secondEntityManagerFactory" )LocalContainerEntityManagerFactoryBean secondEntityManagerFactory){
JpaTransactionManager transactionManager = new JpaTransactionManager();
transactionManager.setEntityManagerFactory(secondEntityManagerFactory.getObject());
return transactionManager;
}
@Bean (name= "jdbcTemplate2" )
public JdbcTemplate jdbcTemplate(){
return new JdbcTemplate(secondDataSource());
}
@Bean (name = "transactionTemplate2" )
public TransactionTemplate transactionTemplate( @Qualifier ( "secondTransactionManager" )PlatformTransactionManager transactionManager){
return new TransactionTemplate(transactionManager);
}
}
|
3.Repository数据持久层
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package com.hdwang.dao.datajpa.firstDs;
@Repository
public interface UserRepository extends JpaRepository<User, Integer> {
/**
* spring data jpa 会自动注入实现(根据方法命名规范)
* @return
*/
User findByNumber(String number);
@Modifying
@Query ( "delete from User u where u.id = :id" )
void deleteUser( @Param ( "id" ) int id);
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
package com.hdwang.dao.datajpa.secondDs;
@Repository
public interface OrderRepository extends JpaRepository<Order, Integer> {
/**
* spring data jpa 会自动注入实现(根据方法命名规范)
* @return
*/
User findByNumber(String number);
@Modifying
@Query ( "delete from Order o where o.id = :id" )
void deleteUser( @Param ( "id" ) int id);
}
|
上面两个接口分属两个数据源,在@EnableJpaRepositories配置好后,这里就可以正确操作相应的数据源了
4.Service服务层,注意事物(接口我就不贴了)
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
33
34
35
36
37
38
|
@Service
@Transactional ( "firstTransactionManager" )
public class UserServiceImpl implements UserService {
@Autowired
private UserRepository userRepository;
@Override
public User findById( int id) {
return this .userRepository.findOne(id);
}
@Override
public User findByNumber(String number) {
return this .userRepository.findByNumber(number);
}
@Override
public List<User> findAllUserByPage( int page, int size) {
Pageable pageable = new PageRequest(page, size);
Page<User> users = this .userRepository.findAll(pageable);
return users.getContent();
}
@Override
public User updateUser(User user, boolean throwEx) {
User userNew = this .userRepository.save(user);
if (throwEx){
throw new RuntimeException( "throw a ex" );
}
return userNew;
}
@Override
public void deleteUser( int id) {
this .userRepository.deleteUser(id);
}
}
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
|
@Service
@Transactional ( "secondTransactionManager" )
public class OrderServiceImpl implements OrderService {
@Autowired
private OrderRepository orderRepository;
@Override
public Order findById( int id) {
return this .orderRepository.findOne(id);
}
@Override
public Order updateOrder(Order order, boolean throwEx) {
Order orderNew = this .orderRepository.save(order);
if (throwEx){
throw new RuntimeException( "throw a ex" );
}
return orderNew;
}
}
|
知识扩展
1.如果采用传统jpa方式,@EnableJpaRepositories无需配置,配置了也无影响。实现方式如下:
ds1相关DaoImpl
@PersistenceContext
private EntityManager entityManager;
ds2相关DaoImpl
@PersistenceContext(unitName = "secondDs")
private EntityManager entityManager;
因为ds1的entityManger声明了@Primary,所以无需指明unitName,ds2必须指明。注入了准确的entityManager,就可以直接拿来操作数据库了。service层和上面一样的,@Transactional("xxxManager")指明事物管理器即可!
2.采用jdbcTemplate方式,直接注入到Service层对象即可,so easy!
@Autowired
private JdbcTemplate jdbcTemplate;
@Autowired
private TransactionTemplate transactionTemplate;
@Resource(name="jdbcTemplate2")
private JdbcTemplate jdbcTemplate2;
@Resource(name="transactionTemplate2")
private TransactionTemplate transactionTemplate2;
好了,spring boot 多数据源,完美解决! 而且三种数据库操作方法均支持,包括事物。已经经过实践证明了! 这是官方给出的最佳实践,只是官方文档没写细。导致整整坑了我几天。至此,spring boot框架的使用就告一段落了!
以上这篇解决spring boot 1.5.4 配置多数据源的问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持服务器之家。