亲宝软件园·资讯

展开

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

Hans 人气:1

关于

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

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

步骤

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
public 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:

@Repository
public interface PrimaryRepository extends JpaRepository<PrimaryEntity, Long> {

 @Query(value = "SELECT p FROM PrimaryEntity p")
 List<PrimaryEntity> queryList();

}

从dao:

@Repository
public 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);

总结

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

加载全部内容

相关教程
猜你喜欢
用户评论