Spring Data Jpa 整合篇

Spring Data Jpa 整合篇

  • application.properties 配置文件

两个数据源配置

# 数据源一
spring.datasource.primary.jdbc-url=jdbc:mysql://localhost:3306/test1
spring.datasource.primary.username=root
spring.datasource.primary.password=123456
spring.datasource.primary.driver-class-name=com.mysql.cj.jdbc.Driver
# 数据源二
spring.datasource.secondary.jdbc-url=jdbc:mysql://localhost:3306/test2
spring.datasource.secondary.username=root
spring.datasource.secondary.password=123456
spring.datasource.secondary.driver-class-name=com.mysql.cj.jdbc.Driver
  • 数据源配置类

@Configuration
public class DataSourceConfiguration {

    @Primary
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.primary")
    public DataSource primaryDataSource() {
        return DataSourceBuilder.create().build();
    }

    @Bean
    @ConfigurationProperties(prefix = "spring.datasource.secondary")
    public DataSource secondaryDataSource() {
        return DataSourceBuilder.create().build();
    }

}
  • 单独配置数据源,对应哪个实体类和Mapper

    • 主数据源

      主数据源多了这个注解@Primary

      @Configuration
      @EnableTransactionManagement
      @EnableJpaRepositories(
              entityManagerFactoryRef="entityManagerFactoryPrimary",
              transactionManagerRef="transactionManagerPrimary",
              basePackages= { "com.didispace.chapter38.p" }) //设置Mapper所在位置
      public class PrimaryConfig {
      
          @Autowired
          @Qualifier("primaryDataSource")
          private DataSource primaryDataSource;
      
          @Autowired
          private JpaProperties jpaProperties;
          @Autowired
          private HibernateProperties hibernateProperties;
      
          private Map<String, Object> getVendorProperties() {
              return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
          }
      
          @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)
                      .packages("com.didispace.chapter38.p") //设置实体类所在位置
                      .persistenceUnit("primaryPersistenceUnit")
                      .properties(getVendorProperties())
                      .build();
          }
      
          @Primary
          @Bean(name = "transactionManagerPrimary")
          public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) {
              return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject());
          }
      
      }
      
    • 第二数据源

      @Configuration
      @EnableTransactionManagement
      @EnableJpaRepositories(
              entityManagerFactoryRef="entityManagerFactorySecondary",
              transactionManagerRef="transactionManagerSecondary",
              basePackages= { "com.didispace.chapter38.s" }) //设置Mapper所在位置
      public class SecondaryConfig {
      
          @Autowired
          @Qualifier("secondaryDataSource")
          private DataSource secondaryDataSource;
      
          @Autowired
          private JpaProperties jpaProperties;
          @Autowired
          private HibernateProperties hibernateProperties;
      
          private Map<String, Object> getVendorProperties() {
              return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
          }
      
          @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)
                      .packages("com.didispace.chapter38.s") //设置实体类所在位置
                      .persistenceUnit("secondaryPersistenceUnit")
                      .properties(getVendorProperties())
                      .build();
          }
      
          @Bean(name = "transactionManagerSecondary")
          PlatformTransactionManager transactionManagerSecondary(EntityManagerFactoryBuilder builder) {
              return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject());
          }
      
      }
      
  • 注意事项

  • 在使用JPA的时候,需要为不同的数据源创建不同的package来存放对应的Entity和Repository,以便于配置类的分区扫描

  • 类名上的注解@EnableJpaRepositories中指定Repository的所在位置

  • LocalContainerEntityManagerFactoryBean创建的时候,指定Entity所在的位置

  • 其他主要注意在互相注入时候,不同数据源不同配置的命名,基本就没有什么大问题了

Mabatis 整合篇

  • application.properties 和 数据源配置类 同上面的JPA

  • 单独配置数据源不同

    • 主数据源

      @Configuration
      @MapperScan(
              basePackages = "com.didispace.chapter39.p",
              sqlSessionFactoryRef = "sqlSessionFactoryPrimary",
              sqlSessionTemplateRef = "sqlSessionTemplatePrimary")
      public class PrimaryConfig {
      
          private DataSource primaryDataSource;
      
          public PrimaryConfig(@Qualifier("primaryDataSource") DataSource primaryDataSource) {
              this.primaryDataSource = primaryDataSource;
          }
      
          @Bean
          public SqlSessionFactory sqlSessionFactoryPrimary() throws Exception {
              SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
              bean.setDataSource(primaryDataSource);
              return bean.getObject();
          }
      
          @Bean
          public SqlSessionTemplate sqlSessionTemplatePrimary() throws Exception {
              return new SqlSessionTemplate(sqlSessionFactoryPrimary());
          }
      
      }
      
    • 第二数据源

      @Configuration
      @MapperScan(
              basePackages = "com.didispace.chapter39.s",
              sqlSessionFactoryRef = "sqlSessionFactorySecondary",
              sqlSessionTemplateRef = "sqlSessionTemplateSecondary")
      public class SecondaryConfig {
      
          private DataSource secondaryDataSource;
      
          public SecondaryConfig(@Qualifier("secondaryDataSource") DataSource secondaryDataSource) {
              this.secondaryDataSource = secondaryDataSource;
          }
      
          @Bean
          public SqlSessionFactory sqlSessionFactorySecondary() throws Exception {
              SqlSessionFactoryBean bean = new SqlSessionFactoryBean();
              bean.setDataSource(secondaryDataSource);
              return bean.getObject();
          }
      
          @Bean
          public SqlSessionTemplate sqlSessionTemplateSecondary() throws Exception {
              return new SqlSessionTemplate(sqlSessionFactorySecondary());
          }
      
      }
      
  • 注意事项

    1. 配置类上使用@MapperScan注解来指定当前数据源下定义的Entity和Mapper的包路径;另外需要指定sqlSessionFactory和sqlSessionTemplate,这两个具体实现在该配置类中类中初始化。

    2. 配置类的构造函数中,通过@Qualifier注解来指定具体要用哪个数据源,其名字对应在DataSourceConfiguration配置类中的数据源定义的函数名。

    3. 配置类中定义SqlSessionFactory和SqlSessionTemplate的实现,注意具体使用的数据源正确(如果使用这里的演示代码,只要第二步没问题就不需要修改)。