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 配置多數據源的問題就是小編分享給大家的全部內容了,希望能給大家一個參考,也希望大家多多支持服務器之家。