首页 > 编程 > Java > 正文

Spring Boot+Jpa多数据源配置的完整步骤

2019-11-26 09:21:51
字体:
来源:转载
供稿:网友

关于

有时候,随着业务的发展,项目关联的数据来源会变得越来越复杂,使用的数据库会比较分散,这个时候就会采用多数据源的方式来获取数据。另外,多数据源也有其他好处,例如分布式数据库的读写分离,集成多种数据库等等。

下面分享我在实际项目中配置多数据源的案例。话不多说了,来一起看看详细的介绍吧

步骤

1.application.yml文件中,配置数据库源。这里primary是主库,secondary是从库。

server: port: 8089# 多数据源配置#primaryspring: 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文件的配置。

@Configurationpublic class DataSourceConfig { @Bean(name = "primaryDataSource") @Qualifier("primaryDataSource") @ConfigurationProperties(prefix="spring.primary.datasource") public DataSource primaryDataSource() {  return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @Qualifier("secondaryDataSource") @Primary @ConfigurationProperties(prefix="spring.secondary.datasource") public DataSource secondaryDataSource() {  return DataSourceBuilder.create().build(); }}

3.分别创建主库、从库的配置类。

注意:entity包和dao包的配置,以及@Primary注解指定主库。

主库配置类:

@Configuration@EnableTransactionManagement@EnableJpaRepositories(  entityManagerFactoryRef = "entityManagerFactoryPrimary",  transactionManagerRef = "transactionManagerPrimary",  basePackages = {"com.infinitus.yunxiao_data.dao.primary"}) //设置Repository所在位置public class PrimaryConfig { @Autowired private JpaProperties jpaProperties; @Autowired @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Primary @Bean(name = "entityManagerPrimary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) {  return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); } @Primary @Bean(name = "entityManagerFactoryPrimary") public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) {  return builder    .dataSource(primaryDataSource)    .properties(getVendorProperties(primaryDataSource))    .packages("com.infinitus.yunxiao_data.entity.primary") //设置实体类所在位置    .persistenceUnit("primaryPersistenceUnit")    .build(); } private Map getVendorProperties(DataSource dataSource) {  return jpaProperties.getHibernateProperties(dataSource); } @Primary @Bean(name = "transactionManagerPrimary") public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {  return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); }}

从库的配置类:

@Configuration@EnableTransactionManagement@EnableJpaRepositories(  entityManagerFactoryRef = "entityManagerFactorySecondary",  transactionManagerRef = "transactionManagerSecondary",  basePackages = {"com.infinitus.yunxiao_data.dao.secondary"}) //设置Repository所在位置public class SecondaryConfig { @Autowired private JpaProperties jpaProperties; @Autowired @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Bean(name = "entityManagerSecondary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) {  return entityManagerFactorySecondary(builder).getObject().createEntityManager(); } @Bean(name = "entityManagerFactorySecondary") public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) {  return builder    .dataSource(secondaryDataSource)    .properties(getVendorProperties(secondaryDataSource))    .packages("com.infinitus.yunxiao_data.entity.secondary") //设置实体类所在位置    .persistenceUnit("primaryPersistenceUnit")    .build(); } private Map getVendorProperties(DataSource dataSource) {  return jpaProperties.getHibernateProperties(dataSource); } @Bean(name = "transactionManagerSecondary") PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {  return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); }}

4.分别创建主、从库dao类。

主dao:

@Repositorypublic interface PrimaryRepository extends JpaRepository<PrimaryEntity, Long> { @Query(value = "SELECT p FROM PrimaryEntity p") List<PrimaryEntity> queryList();}

从dao:

@Repositorypublic interface SecondaryRepository extends JpaRepository<SecondaryEntity, Long> { @Query(value = "SELECT p FROM SecondaryEntity p") List<SecondaryEntity> queryList();}

5.分别创建主、从库entity类。

主entity:

@Entity@Table(name = "holiday_scheme")@EntityListeners(AuditingEntityListener.class)public class PrimaryEntity extends AbstractPersistable<Long> { @Column(name = "date") public String date; @Column(name = "hour") public String hour; @Column(name = "holiday") public String holiday; @Column(name = "holiday_explain") public String holiday_explain; public String getDate() {  return date; } public void setDate(String date) {  this.date = date; } public String getHour() {  return hour; } public void setHour(String hour) {  this.hour = hour; } public String getHoliday() {  return holiday; } public void setHoliday(String holiday) {  this.holiday = holiday; } public String getHoliday_explain() {  return holiday_explain; } public void setHoliday_explain(String holiday_explain) {  this.holiday_explain = holiday_explain; } @Override public String toString() {  return "PrimaryEntity{" +    "date='" + date + '/'' +    ", hour='" + hour + '/'' +    ", holiday='" + holiday + '/'' +    ", holiday_explain='" + holiday_explain + '/'' +    '}'; }}

从entity:

@Entity@Table(name = "active_dashboards")@EntityListeners(AuditingEntityListener.class)public class SecondaryEntity extends AbstractPersistable<Long> { @Column(name = "dashboard_id") public String dashboard_id; @Column(name = "user_id") public String user_id; @Column(name = "order_index") public String order_index; public String getDashboard_id() {  return dashboard_id; } public void setDashboard_id(String dashboard_id) {  this.dashboard_id = dashboard_id; } public String getUser_id() {  return user_id; } public void setUser_id(String user_id) {  this.user_id = user_id; } public String getOrder_index() {  return order_index; } public void setOrder_index(String order_index) {  this.order_index = order_index; } @Override public String toString() {  return "SecondaryEntity{" +    "dashboard_id='" + dashboard_id + '/'' +    ", user_id='" + user_id + '/'' +    ", order_index='" + order_index + '/'' +    '}'; }}

6.controller请求获取不同数据库的数据。

@RestController@RequestMapping("/database")public class MailController { private final Logger logger = LoggerFactory.getLogger(this.getClass()); @Autowired PrimaryRepository primaryRepository; @Autowired SecondaryRepository secondaryRepository; @RequestMapping("/primary") @ResponseBody public String primary() {  return primaryRepository.queryList().toString(); } @RequestMapping("/secondary") @ResponseBody public String secondary() {  return secondaryRepository.queryList().toString(); }}

注意

下面提两个在配置多数据源时遇到的坑点,一不注意就掉坑了。

1.Application类不需要配置@EnableJpaRepositories注解,会报如下错误。

A component required a bean named 'entityManagerFactory' that could not be f

2.注意检查dao类,获取数据的方法上格式是否正确,有没有某个字段是表中不存在的,避免启动异常。如下,SecondaryEntity表中是不存在job_name字段的,所以注释掉才能启动成功等。

//@Query(value = "SELECT p FROM SecondaryEntity p where p.job_name = ?1")//List<SecondaryEntity> queryOdcRecord(String job_name);

总结

以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对武林网的支持。

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表