SpringDataJpa——配置多数据源

SpringBoot v2.0.5.RELEASE

SpringDataJPA 2.0.10RELEASE

Hibernate-Core:5.2.17

JPA参数详解

JPA配置详解之jpaProperties

问题

1.Spring Data Jpa 自定义 Repository EntityManager is null

这个问题是啊我在查询资料过程中搜到,本身我并未遇到,在此记录以下

原文链接:https://blog.csdn.net/woxinqidai/article/details/78468540
新版本中去除了 @PersistenceContext 注解, 无法自动进行注入, 应该是新版本为了支持微服务, 表分库策略,
可以使用多个数据源, 多个EntityManager, 故移除自动注入, 改为手动注入:

@Autowired
public CustomerRepositoryImpl(JpaContext context){
super(Customer.class);
setEntityManager(context.getEntityManagerByManagedType(Follow.class));
}

yml配置

spring:
  datasource:
    # 第一个数据源
    primary:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbcUrl: jdbc:mysql://localhost:3306/primary?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2b8
      username: root
      password: 123456
    # 第二数据源
    secondary:
      driver-class-name: com.mysql.cj.jdbc.Driver
      jdbcUrl: jdbc:mysql://localhost:3306/secondary?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&serverTimezone=GMT%2b8
      username: root
      password: 123456

JPA

JpaProperties报错的问题

初始化数据源

@Configuration
@Slf4j
public class DataSourceConfig {


    @Primary
    @Bean(name = "masterDataSourceProperties")
    @Qualifier(value = "masterDataSourceProperties")
    @ConfigurationProperties(prefix = "spring.datasource.master")
    public DataSourceProperties masterDataSourceProperties(){
        return new DataSourceProperties();
    }

    @Primary
    @Bean(name = "masterDataSource")
    @Qualifier(value = "masterDataSource")
    public DataSource masterDataSource(){
        log.info("创建master数据源");
        return masterDataSourceProperties().initializeDataSourceBuilder().build();
    }

    @Bean(name = "salveDataSourceProperties")
    @Qualifier(value = "salveDataSourceProperties")
    @ConfigurationProperties(prefix = "spring.datasource.salve")
    public DataSourceProperties salveDataSourceProperties(){
        return new DataSourceProperties();
    }

    @Bean(name = "salveDataSource")
    @Qualifier(value = "salveDataSource")
    public DataSource salveDataSource(){
        log.info("创建slave数据源");
        return salveDataSourceProperties().initializeDataSourceBuilder().build();
    }

}

master 和slave各自的JPA详细配置

@Configuration
@Component
@ComponentScan({"com.test.config"})
@EnableTransactionManagement
@EnableJpaRepositories(
        //默认关闭事务,启动类上的注释掉了,在这里补充上
        enableDefaultTransactions = false,
        entityManagerFactoryRef = "masterEntityManagerFactoryBean",  //配置实体管理器连接工厂
        transactionManagerRef = "masterTransactionManager", //配置事务管理器
        basePackages = {"com.test.repository"
        }, //repository位置
        //排除使用salve库的接口
        excludeFilters = {
                @ComponentScan.Filter(type = FilterType.ASSIGNABLE_TYPE, classes = {
                        slaveTestRepository.class
                })
        }
        ) 
public class MasterDataSourceConfig {


    @Autowired
    @Qualifier(value = "masterDataSource")
    private DataSource masterDataSource;

    @Autowired
    private JpaProperties jpaProperties;


    //配置entityManager实体
    @Primary
    @Bean(name = "masterEntityManager")
    public EntityManager entityManager(EntityManagerFactoryBuilder builder) {
        return Objects.requireNonNull(entityManagerFactoryBeanMaster(builder).getObject()).createEntityManager();
    }

    @Primary
    @Bean(name = "masterEntityManagerFactoryBean")
    public LocalContainerEntityManagerFactoryBean entityManagerFactoryBeanMaster(EntityManagerFactoryBuilder builder) {
        return builder.dataSource(masterDataSource)  //设置数据源
                .properties(getVendorProperties())  // hibernate配置
                .properties(jpaProperties.getProperties())//jpa配置
                .persistenceUnit("masterPersistenceUnit")   //设置持久化单元名,用于@PersistenceContext注解获取EntityManager时指定数据源
                .packages("com.test.entity",
                )   //设置实体类所在位置
                .build();

    }

    @Primary
    @Bean(name = "masterTransactionManager")
    public PlatformTransactionManager transactionManager(EntityManagerFactoryBuilder builder) {
        return new JpaTransactionManager(Objects.requireNonNull(entityManagerFactoryBeanMaster(builder).getObject()));
    }

    //jpa配置信息
    public Map<String, String> getProperties() {
        HashMap<String, String> map = Maps.newHashMap();
        map.put("show-sql", "true");
        map.put("hibernate.ddl-auto", "none");
        map.put("hibernate.naming-strategy", "org.hibernate.cfg.ImprovedNamingStrategy");
        map.put("hibernate.dialect", "org.hibernate.dialect.MySQL55Dialect");
        return map;
    }


    private Map<String,Object> getVendorProperties() {
        //return hibernateProperties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings());
        return jpaProperties.getHibernateProperties(new HibernateSettings());
    }

/**getVendorProperties() 函数的调试信息
 *  {hibernate.implicit_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringImplicitNamingStrategy,
 *  hibernate.format_sql=true,
 *  hibernate.hbm2ddl.auto=update,
 *  hibernate.id.new_generator_mappings=true,
 *  hibernate.physical_naming_strategy=org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy,
 *  hibernate.dialect=org.hibernate.dialect.MySQL55Dialect}
 */

}

主数据源设置如此,从数据源相同

  1. 配置实体管理器连接工厂时指定了持久化单元名,用于
  2. @PersistenceContext注解获取EntityManager时指定数据源
  3. 在我使用过程中,当类中注入了EntityManager entityManager自定义查询方法时,必须用@PersistenceContext来注入,不能用@Autowired;
    如果@PersistenceContext()未指定参数,那么这个实体管理器默认使用master数据源,指定后才会使用指定的实体管理器;
  4. 如果直接使用SpringDataJPA已经封装好的查询方法,比如findbyId()这是候会根据配置JPA配置类的扫描包配置信息使用指定数据源
  5. 启动类上不要再使用@EnableJpaRepositories,在数据源JPA配置类上使用此注解
    必须使用@Primary指定主数据源

@EnableJpaRepositories

 1 @EnableJpaRepositories(
 2     basePackages = {},
 3     basePackageClasses = {},
 4     includeFilters = {},
 5     excludeFilters = {},
 6     repositoryImplementationPostfix = "Impl",
 7     namedQueriesLocation = "",//META-INF/jpa-named-queries.properties
 8     queryLookupStrategy=QueryLookupStrategy.Key.CREATE_IF_NOT_FOUND, //QueryLookupStrategy.Key.x
 9     repositoryFactoryBeanClass=JpaRepositoryFactoryBean.class, //class
10     entityManagerFactoryRef="entityManagerFactory",
11     transactionManagerRef="transactionManager",
12     considerNestedRepositories=false, 
13     enableDefaultTransactions=true
14 )
属性缺省值描述
valuebasePackages的别名,简化basePackages
basePackages用于配置扫描Repositories所在的包。填写字符串(或字符串数组)形式的包名.
basePackageClassesbasePackages的安全替代选选项。指定一个要扫描包中的一个类或接口,将扫描所在包中的所有repository,可以考虑在每个要扫描的包中创建一个类或接口,它除了被这个属性引用外,没有其他用途。
includeFilters指定哪些类型的组件被扫描。过滤器,该过滤区采用ComponentScan的过滤器类
excludeFilters指定哪些类型的组件不被扫描。
repositoryImplementationPostfiximpl查找自定义存储库实现时要使用的后缀。默认为Impl。对于名为PersonRepository的存储库,将通过扫描PersonRepositoryImpl来查找相应的实现类。
namedQueriesLocationMETA-INF/jpa-named-queries.properties配置Spring-Data的named queries 属性文件的位置,默认META-INF/jpa-named-queries.properties。
queryLookupStrategyQueryLookupStrategy.Key.CREATE_IF_NOT_FOUND查询方法的查询策略。构建条件查询的策略,包含三种方式CREATE USE_DECLARED_QUERY,CREATE_IF_NOT_FOUND CREATE:按照接口名称自动构建查询 USE_DECLARED_QUERY:用户声明查询CREATE_IF_NOT_FOUND:先搜索用户声明的,不存在则自动构建
repositoryFactoryBeanClassJpaRepositoryFactoryBean用于每个存储库实例的FactoryBean类。默认为JpaRepositoryFactoryBean。
repositoryBaseClass配置存储库基类,以用于为该特定配置创建存储库代理。
entityManagerFactoryRefentityManagerFactory配置EntityManagerFactory bean定义的名称。默认为entityManagerFactory。
transactionManagerReftransactionManager配置PlatformTransactionManager bean定义的名称。默认为transactionManager。
considerNestedRepositoriesfalse配置是否发现嵌套的Repository接口(如定义为内部类)。默认为false
enableDefaultTransactionstrue配置Spring-Data-Jpa 的Repositories是否启用默认事务,默认为true。如果禁用,则必须在外层使用。
bootstrapModeBootstrapMode.DEFAULT配置在引导生命周期中何时初始化Repository。默认为BootstrapMode.DEFAULT,除了添加了BootstrapMode.LAZY的接口外,其他接口立即初始化。1. BootstrapMode.LAZY,Repository的bean定义被认为是懒加载注入,并且只在首次使用时初始化,即应用程序可能在没有初始化Repository的情况下完全启动 2. BootstrapMode.DEFERRED,Repository的bean定义被认为是懒加载注入,但存储库初始化在应用程序上下文引导完成时触发。
escapeCharacter配置在包含contains、startsWith或endsWith子句的派生查询中用于转义 _ 或 % 的通配符字符。

参考资料:

springboot配置文件application.properties配置JPA以及数据源
学习Spring-Data-Jpa(二十)—@EnableJpaRepositories
SpringBoot 多数据源的动态切换,你学会了吗?
springboot多数据源配置及自动切换(二)
springboot多数据源配置及切换
Spring-Boot 多数据源配置+动态数据源切换+多数据源事物配置实现主从数据库存储分离
SpringBoot多数据源配置详细教程
JAVA-SpringBoot+JPA+Druid多数据源配置完全版+有坑提示

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值