在实际项目中往往会使用2个数据源,这个时候就需要做额外的配置了。下面的配置在2.0.1.RELEASE 测试通过
1、配置文件
配置两个数据源
spring.datasource.url=jdbc:mysql://localhost:13306/first?useUnicode=true&characterEncoding=utf-8&useSSL=false
spring.datasource.username=root
spring.datasource.password=
spring.datasource.driverClassName=com.mysql.jdbc.Driver
spring.seconddatasource.url=jdbc:mysql://localhost:3306/second?useUnicode\=true&characterEncoding=utf-8&useSSL=false
spring.seconddatasource.driverClassName=com.mysql.jdbc.Driver
spring.seconddatasource.username=root
spring.seconddatasource.password=
2、entity
创建两个简单的entity,它们分别对应不同的数据库。
先看第一个entity,user
package com.example.first.entity;
@Entity
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
private String email;
private int age;
}
第二个entity, product
package com.example.second.entity;
@Entity
public class Product {
@Id
private Long id;
private String name;
private double price;
}
注意:这两个enty位于不同的包里面。
3、Repository
创建两个对应的Repository,注意他们也位于不同的包里
package com.example.first.dao;
public interface UserRepository
extends JpaRepository<User, Long> { }
package com.example.second.dao;
public interface ProductRepository
extends JpaRepository<Product, Long> { }
4、java 配置
有两个数据源,需要两个配置文件,分别配置下面这几个Bean
DataSource
EntityManagerFactory
TransactionManager
首先配置第一个数据源,我把它作为主数据源,注意,它们都使用了@Prime注解
@Configuration
@EnableJpaRepositories(basePackages = "com.example.first.dao",
entityManagerFactoryRef = "firstEntityManager",
transactionManagerRef = "firstTransactionManager")
public class FirstDataSourceConfig {
@Bean
@Primary
public LocalContainerEntityManagerFactoryBean firstEntityManager(EntityManagerFactoryBuilder builder) {
Map<String, String> properties = new HashMap<>();
properties.put("hibernate.implicit_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
properties.put("hibernate.physical_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
return builder
.dataSource(firstDataSource())
.packages("com.example.user.entity")
.persistenceUnit("first")
.properties(properties)
.build();
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSourceProperties firstDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@Primary
@ConfigurationProperties("spring.datasource")
public DataSource firstDataSource() {
return primaryDataSourceProperties().initializeDataSourceBuilder().build();
}
@Primary
@Bean(name = "firstTransactionManager")
public PlatformTransactionManager firstTransactionManager(@Qualifier("firstEntityManager")
EntityManagerFactory firstEntityManagerFactory) {
return new JpaTransactionManager(firstEntityManagerFactory);
}
}
接下来配置第二个数据源,和第一个完全一致,除了没有@Prime注解
@Configuration
@EnableJpaRepositories(
basePackages = "com.example.second.dao",
entityManagerFactoryRef = "secondEntityManager",
transactionManagerRef = "secondTransactionManager"
)
public class SecondDataSourceConfig {
@Bean
public LocalContainerEntityManagerFactoryBean secondEntityManager(EntityManagerFactoryBuilder builder) {
Map<String, String> properties = new HashMap<>();
properties.put("hibernate.implicit_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy");
properties.put("hibernate.physical_naming_strategy",
"org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy");
return builder
.dataSource(secondDataSource())
.packages("com.example.second.entity")
.persistenceUnit("second")
.properties(properties)
.build();
}
@Bean
@ConfigurationProperties("spring.seconddatasource")
public DataSourceProperties secondDataSourceProperties() {
return new DataSourceProperties();
}
@Bean
@ConfigurationProperties("spring.seconddatasource")
public DataSource secondDataSource() {
return secondDataSourceProperties().initializeDataSourceBuilder().build();
}
@Bean(name = "secondTransactionManager")
public PlatformTransactionManager secondTransactionManager(@Qualifier("secondEntityManager")
EntityManagerFactory secondEntityManagerFactory) {
return new JpaTransactionManager(secondEntityManagerFactory);
}
}
5、使用
和单数据源的jpa使用方式基本一致。当使用事务注解是,第一个数据源的注解可以直接使用@Transactional,第二个为了区分必须使用@Transactional(value="secondTransactionManager")。可以在一个事务中调用另外一个数据源的事务。
2.0.1.RELEASE