当前位置:   article > 正文

Spring JPA多数据库访问_springjpa跨数据库兼容方法

springjpa跨数据库兼容方法

转一篇关于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.


声明:本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号