Spring Data JPA多数据源配置(非SpringBoot项目);
用于一个在使用 Spring Data Jpa 作为ORM框架, 且项目需要使用多个数据源的情况;

一. 默认数据源配置:

  • 默认数据源配置同但数据源配置, 不做额外说明

二. 第二个数据源配置

1. 相关实体类接口创建

  • 创建第二个数据源代码存放的目录(下方称为根目录)

    Spring Data Jpa 配置多个数据源需要将素体类置于不同的包下; 为了代码结构整体, 便于维护, 故将第二个数据源相关代码全部放置于一个包下;
  • 在根目录下创建entity目录并创建对应实体类;
  • 在根目录下创建repository目录并创建对应Jpa Repository接口;
  • 在根目录下创建service目录并创建对应Service接口;
  • 在service下创建impl目录并创建对应Service接口;

2. 多数据源配置类创建:

  • 在根目录下创建config目录并创建配置类: SecondJpaConfig.java;
  • 代码编写

    
    package cn.zzzyke.datasource.second.conf;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.context.annotation.Bean;
    import org.springframework.context.annotation.Configuration;
    import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
    import org.springframework.orm.jpa.JpaTransactionManager;
    import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
    import org.springframework.orm.jpa.vendor.Database;
    import org.springframework.orm.jpa.vendor.HibernateJpaDialect;
    import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
    import org.springframework.transaction.PlatformTransactionManager;
    
    import javax.persistence.EntityManager;
    import javax.sql.DataSource;
    import java.util.HashMap;
    import java.util.Objects;
    
    /**
     * @author Zhuo
     */
    @Configuration
    @EnableJpaRepositories(entityManagerFactoryRef = "senondEntityManagerFactory", basePackages = "cn.zzzyke.datasource.second.repository")
    public class SecondJpaConfig {
    
      private final Logger log = LoggerFactory.getLogger(SecondJpaConfig.class);
    
      /**
       * 构造数据源, 注入到Spring容器中
       * @return
       */
      @Bean
      public DataSource senondDataSource() {
          // 根据项目实际情况, 配置第二个数据源
          log.info("注入数据源");
          String prefix = "datasource.third.";
          return ConfUtil.readBasicDataSource(prefix);
      }
    
      /**
       * 构造实体管理器工厂, 注入到Spring容器中
       * @return
       */
      @Bean
      public LocalContainerEntityManagerFactoryBean senondEntityManagerFactory() {
          log.info("注入实体管理器工厂");
          // 实体管理器工厂对象
          LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean();
          log.info("管理器工厂注入数据源");
          // 设置数据源
          em.setDataSource(senondDataSource());
          log.info("管理器工厂注入实体包路径");
          // 设置实体包路径
          em.setPackagesToScan("cn.zzzyke.datasource.second.entity");
          // 供应商适配器: 注入数据库类型
          HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
          // 设置数据库类型: SQL_SERVER
          vendorAdapter.setDatabase(Database.SQL_SERVER);
          // 设置是否打印SQL语句
          vendorAdapter.setShowSql(false);
          // 设置是否自动执行DDL语句: 如建表, 删表, 修改字段等
          vendorAdapter.setGenerateDdl(false);
          // 设置数据库方言: SQLServer2012Dialect
          // 使用 SQLServer2012Dialect 会抛出异常:, 原因未知
          vendorAdapter.setDatabasePlatform("org.hibernate.dialect.SQLServerDialect");
          // 读取并打印当前JPA方言
          HibernateJpaDialect jpaDialect = vendorAdapter.getJpaDialect();
          log.info("当前数据库类型:{}", jpaDialect);
          log.info("管理器工厂注入HibernateJpaVendorAdapter");
          // 设置供应商适配器
          em.setJpaVendorAdapter(vendorAdapter);
          log.info("生成管理器工厂配置");
          // 生成管理器工厂配置, 此配置会和供应商适配器中的配置合并
          HashMap<String, Object> properties = new HashMap<>(8);
          properties.put("hibernate.hbm2ddl.auto", "none");
          properties.put("hibernate.show_sql", "false");
          properties.put("hibernate.format_sql", "true");
          properties.put("hibernate.enable_lazy_load_no_trans", "true");
          properties.put("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
          properties.put("spring.jpa.properties.hibernate.dialect", "org.hibernate.dialect.SQLServerDialect");
          properties.forEach((k, v) -> { log.info("管理器工厂配置: {} -> {}", k, v); });
          log.info("管理器工厂注入配置参数");
          em.setJpaPropertyMap(properties);
          log.info("返回管理器工厂对象");
          return em;
      }
    
      /**
       * 构造实体类管理器, 注入到Spring容器中
       * @return
       */
      @Bean
      public EntityManager senondEntityManager() {
          log.info("注入实体管理器");
          return Objects.requireNonNull(senondEntityManagerFactory().getObject()).createEntityManager();
      }
    
      /**
       * 构造事务管理器, 注入到Spring容器中
       * @return
       */
      @Bean(name = "senondTransactionManager")
      public PlatformTransactionManager senondTransactionManager() {
          log.info("注入事务管理器");
          return new JpaTransactionManager(Objects.requireNonNull(senondEntityManagerFactory().getObject()));
      }
    
    }
    
    

3. 编写相关 Server 代码, 并启动项目测试是否配置成功;

发表评论