Spring JPA多数据库访问

转一篇关于spring-data-jpa链接多数据库的文章。转自:http://www.baeldung.com/spring-data-jpa-multiple-databases

1. Overview

In this tutorial we’ll implement a simple Spring configuration for a Spring Data JPA system with multiple databases.

2. The Entities

First – let’s create two simple entities – each living in a separate database.

Here is the first entity “User“:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
package org.baeldung.persistence.multiple.model.user;
 
@Entity
@Table (schema = "spring_jpa_user" )
public class User {
 
     @Id
     @GeneratedValue (strategy = GenerationType.AUTO)
     private int id;
 
     private String name;
 
     @Column (unique = true , nullable = false )
     private String email;
 
     private int age;
}

And the second entity – “Product“:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
package org.baeldung.persistence.multiple.model.product;
 
@Entity
@Table (schema = "spring_jpa_product" )
public class Product {
 
     @Id
     private int id;
 
     private String name;
 
     private double price;
}

As you can see, the two entities are also placed in independent packages – this will be important as we move into the configuration.

3. The JPA Repositories

Next – let’s take a look at our two JPA repositories – UserRepository:

?
1
2
3
package org.baeldung.persistence.multiple.dao.user;
 
public interface UserRepository extends JpaRepository<User, Integer> { }

And ProductRepository:

?
1
2
3
package org.baeldung.persistence.multiple.dao.product;
 
public interface ProductRepository extends JpaRepository<Product, Integer> { }

Note, again how we created these two repositories in different packages.

4. Configure JPA with Java

Next – let’s get to the actual Spring configuration. We’ll start by setting up 2 configuration classes – one for the User and the other for the Product.

In each one of this configuration classes, we’ll need to define the following:

  • User DataSource
  • User EntityManagerFactory (userEntityManager)
  • User TransactionManager (userTransactionManager)

Let’s start by looking the the User configuration:

?
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
@Configuration
@PropertySource ({ "classpath:persistence-multiple-db.properties" })
@EnableJpaRepositories (
     basePackages = "org.baeldung.persistence.multiple.dao.user" ,
     entityManagerFactoryRef = "userEntityManager" ,
     transactionManagerRef = "userTransactionManager"
)
public class UserConfig {
     @Autowired
     private Environment env;
     
     @Bean
     @Primary
     public LocalContainerEntityManagerFactoryBean userEntityManager() {
         LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
         em.setDataSource(userDataSource());
         em.setPackagesToScan( new String[] { "org.baeldung.persistence.multiple.model.user" });
 
         HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
         em.setJpaVendorAdapter(vendorAdapter);
         HashMap<String, Object> properties = new HashMap<String, Object>();
         properties.put( "hibernate.hbm2ddl.auto" , env.getProperty( "hibernate.hbm2ddl.auto" ));
         properties.put( "hibernate.dialect" , env.getProperty( "hibernate.dialect" ));
         em.setJpaPropertyMap(properties);
 
         return em;
     }
 
     @Primary
     @Bean
     public DataSource userDataSource() {
         DriverManagerDataSource dataSource = new DriverManagerDataSource();
         dataSource.setDriverClassName(env.getProperty( "jdbc.driverClassName" ));
         dataSource.setUrl(env.getProperty( "user.jdbc.url" ));
         dataSource.setUsername(env.getProperty( "jdbc.user" ));
         dataSource.setPassword(env.getProperty( "jdbc.pass" ));
 
         return dataSource;
     }
 
     @Primary
     @Bean
     public PlatformTransactionManager userTransactionManager() {
         JpaTransactionManager transactionManager = new JpaTransactionManager();
         transactionManager.setEntityManagerFactory(userEntityManager().getObject());
         return transactionManager;
     }
}

Notice how we’re using the userTransactionManager as our Primary TransactionManager– by annotating the bean definition with @Primary. That’s helpful whenever we’re going to implicitly or explicitly inject the transaction manager without specifying which one by name.

Next, let’s discuss ProductConfig - where we define similar beans:

?
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
@Configuration
@PropertySource ({ "classpath:persistence-multiple-db.properties" })
@EnableJpaRepositories (
     basePackages = "org.baeldung.persistence.multiple.dao.product" ,
     entityManagerFactoryRef = "productEntityManager" ,
     transactionManagerRef = "productTransactionManager"
)
public class ProductConfig {
     @Autowired
     private Environment env;
 
     @Bean
     public LocalContainerEntityManagerFactoryBean productEntityManager() {
         LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
         em.setDataSource(productDataSource());
         em.setPackagesToScan( new String[] { "org.baeldung.persistence.multiple.model.product" });
 
         HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
         em.setJpaVendorAdapter(vendorAdapter);
         HashMap<String, Object> properties = new HashMap<String, Object>();
         properties.put( "hibernate.hbm2ddl.auto" , env.getProperty( "hibernate.hbm2ddl.auto" ));
         properties.put( "hibernate.dialect" , env.getProperty( "hibernate.dialect" ));
         em.setJpaPropertyMap(properties);
 
         return em;
     }
 
     @Bean
     public DataSource productDataSource() {
         DriverManagerDataSource dataSource = new DriverManagerDataSource();
         dataSource.setDriverClassName(env.getProperty( "jdbc.driverClassName" ));
         dataSource.setUrl(env.getProperty( "product.jdbc.url" ));
         dataSource.setUsername(env.getProperty( "jdbc.user" ));
         dataSource.setPassword(env.getProperty( "jdbc.pass" ));
 
         return dataSource;
     }
 
     @Bean
     public PlatformTransactionManager productTransactionManager() {
         JpaTransactionManager transactionManager = new JpaTransactionManager();
         transactionManager.setEntityManagerFactory(productEntityManager().getObject());
         return transactionManager;
     }
}

5. Simple Test

Finally – let’s test our configurations.

We will try a simple test by creating an instance of each entity and make sure it is created – as in the following example:

?
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
@RunWith (SpringJUnit4ClassRunner. class )
@ContextConfiguration (classes = { UserConfig. class , ProductConfig. class })
@TransactionConfiguration
public class JPAMultipleDBTest {
     @Autowired
     private UserRepository userRepository;
 
     @Autowired
     private ProductRepository productRepository;
 
     @Test
     @Transactional ( "userTransactionManager" )
     public void whenCreatingUser_thenCreated() {
         User user = new User();
         user.setName( "John" );
         user.setEmail( "john@test.com" );
         user.setAge( 20 );
         user = userRepository.save(user);
 
         assertNotNull(userRepository.findOne(user.getId()));
     }
 
     @Test
     @Transactional ( "userTransactionManager" )
     public void whenCreatingUsersWithSameEmail_thenRollback() {
         User user1 = new User();
         user1.setName( "John" );
         user1.setEmail( "john@test.com" );
         user1.setAge( 20 );
         user1 = userRepository.save(user1);
         assertNotNull(userRepository.findOne(user1.getId()));
 
         User user2 = new User();
         user2.setName( "Tom" );
         user2.setEmail( "john@test.com" );
         user2.setAge( 10 );
         try {
             user2 = userRepository.save(user2);
         } catch (DataIntegrityViolationException e) {
         }
 
         assertNull(userRepository.findOne(user2.getId()));
     }
 
     @Test
     @Transactional ( "productTransactionManager" )
     public void whenCreatingProduct_thenCreated() {
         Product product = new Product();
         product.setName( "Book" );
         product.setId( 2 );
         product.setPrice( 20 );
         product = productRepository.save(product);
 
         assertNotNull(productRepository.findOne(product.getId()));
     }
}

6. Conclusion

This article was a practical overview of how to configure your Spring Data JPA project to use multiple databases.

The full implementation of this article can be found in the github project – this is an Eclipse based project, so it should be easy to import and run as it is.


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值