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);
总结
以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对毛票票的支持。