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())); } }