目录
1. 多数据源使用的概述
2. 多数据源案例
2.1 数据库准备
2.2 核心代码
2.3 目录结构
2.4 案例测试
由于最近项目中需要用到多数据源,期间也遇到一些问题,所以以下作出一些总结分享。
常用的单数据源源码可以参考:springboot-jpa-demo(main分支)
以下源码会放在spring-jpa-multiple-datasources分支。
数据库使用的是postgres。
1) 当前有两个db分别是public和public2,都有一张userinfo表。
2) public.userinfo数据。
3) public2.userinfo数据。
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "pfTransactionManager",
basePackages = {"com.bas.repository"}
)
@EntityScan(
basePackages = {
"com.bas.entity"
}
)
public class DataSourceConfig {
@Bean(name = "dataSource")
@Primary
@ConfigurationProperties(prefix = "spring.primary.datasource")
public DataSource dataSource() {
return DataSourceBuilder.create().build();
}
@Bean(name = "entityManagerFactory")
@Primary
public LocalContainerEntityManagerFactoryBean entityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("dataSource") DataSource dataSource
){
return builder.dataSource(dataSource)
.packages("com.bas")
.persistenceUnit("default")
.build();
}
@Bean(name = "pfTransactionManager")
@Primary
public PlatformTransactionManager transactionManager(
@Qualifier("entityManagerFactory")EntityManagerFactory entityManagerFactory
){
return new JpaTransactionManager(entityManagerFactory);
}
}
第二个数据源和以上的大相庭径,值得注意的是包路径和bean的名称不能重复。
假设当前有俩接口分别是 /user/queryAll 和 /user/queryAll2 ,分别查询的是public.userinfo和public.userinfo2两张表的数据。
1) 查询public.userinfo。
2) 查询public2.userinfo.
注:
1) 如果 application.properties 加上了 spring.jpa.properties.hibernate.default_schema,那么第二个数据源的 spring.secondary.datasource.jdbc-url=jdbc:postgresql://127.0.0.1:5432/postgres?currentSchema=public2 配置里面的currentSchema将会失效,这个时候需要在entity上加上
@Table(name="userinfo", schema = "public2")
所以为了避免每个entity都要加,建议是去掉default_schema这个配置。
2) 配置application.properties的时候要注意主数据源配置不能是原来的 spring.datasource.url 不然会导致jdbcUrl is required with driverClassName错误。
附:
1. 如果遇到:jdbcUrl is required with driverClassName,可以参考:spring boot 2.0 报错:“jdbcUrl is required with driverClassName.” 解决办法!
2. 如果遇到:different object with the same identifier value was already associated with the session,可以参考:解决a different object with the same identifier value was already associated with the session错误
3. 如果遇到数据更新有乐观锁的问题(Row was updated or deleted by another transaction),可以从数据库中把version查出来,赋给实体对象然后再更新。
4. 注意第一个数据源(com.bas)和第二个数据源(com.secondary)配置的package路径不能有重叠,否则第二个数据源加载不了的,如第二个数据源不能是com.bas.secondary。
5. 如果遇到IllegalArgumentException: Not a managed type: class com.secondary,检查数据源configuration里面的packages路径是否正确。