Spring Boot+Jpa多数据源配置的完整步骤
关于
有时候,随着业务的发展,项目关联的数据来源会变得越来越复杂,使用的数据库会比较分散,这个时候就会采用多数据源的方式来获取数据。另外,多数据源也有其他好处,例如分布式数据库的读写分离,集成多种数据库等等。
下面分享我在实际项目中配置多数据源的案例。话不多说了,来一起看看详细的介绍吧
步骤
1.application.yml文件中,配置数据库源。这里primary是主库,secondary是从库。
server: port:8089 #多数据源配置 #primary spring: primary: datasource: url:jdbc:mysql://127.0.0.1:3306/database1?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai username:root password:****** driver-class-name:com.mysql.jdbc.Driver #secondary secondary: datasource: url:jdbc:mysql://127.0.0.1:3306/database1?autoReconnect=true&useUnicode=true&characterEncoding=UTF-8&useSSL=false&useLegacyDatetimeCode=false&serverTimezone=Asia/Shanghai username:root password:****** driver-class-name:com.mysql.jdbc.Driver jpa: hibernate: primary-dialect:org.hibernate.dialect.MySQL5Dialect secondary-dialect:org.hibernate.dialect.MySQL5Dialect open-in-view:true show-sql:true
2.创建一个Spring配置类,其中spring.primary.datasource的路径参考yml文件的配置。
@Configuration
publicclassDataSourceConfig{
@Bean(name="primaryDataSource")
@Qualifier("primaryDataSource")
@ConfigurationProperties(prefix="spring.primary.datasource")
publicDataSourceprimaryDataSource(){
returnDataSourceBuilder.create().build();
}
@Bean(name="secondaryDataSource")
@Qualifier("secondaryDataSource")
@Primary
@ConfigurationProperties(prefix="spring.secondary.datasource")
publicDataSourcesecondaryDataSource(){
returnDataSourceBuilder.create().build();
}
}
3.分别创建主库、从库的配置类。
注意:entity包和dao包的配置,以及@Primary注解指定主库。
主库配置类:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactoryPrimary",
transactionManagerRef="transactionManagerPrimary",
basePackages={"com.infinitus.yunxiao_data.dao.primary"})//设置Repository所在位置
publicclassPrimaryConfig{
@Autowired
privateJpaPropertiesjpaProperties;
@Autowired
@Qualifier("primaryDataSource")
privateDataSourceprimaryDataSource;
@Primary
@Bean(name="entityManagerPrimary")
publicEntityManagerentityManager(EntityManagerFactoryBuilderbuilder){
returnentityManagerFactoryPrimary(builder).getObject().createEntityManager();
}
@Primary
@Bean(name="entityManagerFactoryPrimary")
publicLocalContainerEntityManagerFactoryBeanentityManagerFactoryPrimary(EntityManagerFactoryBuilderbuilder){
returnbuilder
.dataSource(primaryDataSource)
.properties(getVendorProperties(primaryDataSource))
.packages("com.infinitus.yunxiao_data.entity.primary")//设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
privateMapgetVendorProperties(DataSourcedataSource){
returnjpaProperties.getHibernateProperties(dataSource);
}
@Primary
@Bean(name="transactionManagerPrimary")
publicPlatformTransactionManagertransactionManagerPrimary(EntityManagerFactoryBuilderbuilder){
returnnewJpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
}
}
从库的配置类:
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef="entityManagerFactorySecondary",
transactionManagerRef="transactionManagerSecondary",
basePackages={"com.infinitus.yunxiao_data.dao.secondary"})//设置Repository所在位置
publicclassSecondaryConfig{
@Autowired
privateJpaPropertiesjpaProperties;
@Autowired
@Qualifier("secondaryDataSource")
privateDataSourcesecondaryDataSource;
@Bean(name="entityManagerSecondary")
publicEntityManagerentityManager(EntityManagerFactoryBuilderbuilder){
returnentityManagerFactorySecondary(builder).getObject().createEntityManager();
}
@Bean(name="entityManagerFactorySecondary")
publicLocalContainerEntityManagerFactoryBeanentityManagerFactorySecondary(EntityManagerFactoryBuilderbuilder){
returnbuilder
.dataSource(secondaryDataSource)
.properties(getVendorProperties(secondaryDataSource))
.packages("com.infinitus.yunxiao_data.entity.secondary")//设置实体类所在位置
.persistenceUnit("primaryPersistenceUnit")
.build();
}
privateMapgetVendorProperties(DataSourcedataSource){
returnjpaProperties.getHibernateProperties(dataSource);
}
@Bean(name="transactionManagerSecondary")
PlatformTransactionManagertransactionManagerSecondary(EntityManagerFactoryBuilderbuilder){
returnnewJpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
}
}
4.分别创建主、从库dao类。
主dao:
@Repository publicinterfacePrimaryRepositoryextendsJpaRepository{ @Query(value="SELECTpFROMPrimaryEntityp") List queryList(); }
从dao:
@Repository publicinterfaceSecondaryRepositoryextendsJpaRepository{ @Query(value="SELECTpFROMSecondaryEntityp") List queryList(); }
5.分别创建主、从库entity类。
主entity:
@Entity @Table(name="holiday_scheme") @EntityListeners(AuditingEntityListener.class) publicclassPrimaryEntityextendsAbstractPersistable{ @Column(name="date") publicStringdate; @Column(name="hour") publicStringhour; @Column(name="holiday") publicStringholiday; @Column(name="holiday_explain") publicStringholiday_explain; publicStringgetDate(){ returndate; } publicvoidsetDate(Stringdate){ this.date=date; } publicStringgetHour(){ returnhour; } publicvoidsetHour(Stringhour){ this.hour=hour; } publicStringgetHoliday(){ returnholiday; } publicvoidsetHoliday(Stringholiday){ this.holiday=holiday; } publicStringgetHoliday_explain(){ returnholiday_explain; } publicvoidsetHoliday_explain(Stringholiday_explain){ this.holiday_explain=holiday_explain; } @Override publicStringtoString(){ return"PrimaryEntity{"+ "date='"+date+'\''+ ",hour='"+hour+'\''+ ",holiday='"+holiday+'\''+ ",holiday_explain='"+holiday_explain+'\''+ '}'; } }
从entity:
@Entity @Table(name="active_dashboards") @EntityListeners(AuditingEntityListener.class) publicclassSecondaryEntityextendsAbstractPersistable{ @Column(name="dashboard_id") publicStringdashboard_id; @Column(name="user_id") publicStringuser_id; @Column(name="order_index") publicStringorder_index; publicStringgetDashboard_id(){ returndashboard_id; } publicvoidsetDashboard_id(Stringdashboard_id){ this.dashboard_id=dashboard_id; } publicStringgetUser_id(){ returnuser_id; } publicvoidsetUser_id(Stringuser_id){ this.user_id=user_id; } publicStringgetOrder_index(){ returnorder_index; } publicvoidsetOrder_index(Stringorder_index){ this.order_index=order_index; } @Override publicStringtoString(){ return"SecondaryEntity{"+ "dashboard_id='"+dashboard_id+'\''+ ",user_id='"+user_id+'\''+ ",order_index='"+order_index+'\''+ '}'; } }
6.controller请求获取不同数据库的数据。
@RestController
@RequestMapping("/database")
publicclassMailController{
privatefinalLoggerlogger=LoggerFactory.getLogger(this.getClass());
@Autowired
PrimaryRepositoryprimaryRepository;
@Autowired
SecondaryRepositorysecondaryRepository;
@RequestMapping("/primary")
@ResponseBody
publicStringprimary(){
returnprimaryRepository.queryList().toString();
}
@RequestMapping("/secondary")
@ResponseBody
publicStringsecondary(){
returnsecondaryRepository.queryList().toString();
}
}
注意
下面提两个在配置多数据源时遇到的坑点,一不注意就掉坑了。
1.Application类不需要配置@EnableJpaRepositories注解,会报如下错误。
Acomponentrequiredabeannamed'entityManagerFactory'thatcouldnotbef
2.注意检查dao类,获取数据的方法上格式是否正确,有没有某个字段是表中不存在的,避免启动异常。如下,SecondaryEntity表中是不存在job_name字段的,所以注释掉才能启动成功等。
//@Query(value="SELECTpFROMSecondaryEntitypwherep.job_name=?1") //ListqueryOdcRecord(Stringjob_name);
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。