jpa多數(shù)據(jù)源時(shí)Hibernate配置自動(dòng)生成表不生效的解決
jpa配置多數(shù)據(jù)源教程很多,在Springboot2之后有一些變化,來看一下。
application.yml如下
spring: application: name: t3cc datasource: primary: jdbc-url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${DB_NAME:anbang}?useUnicode=true&characterEncoding=UTF8&serverTimezone=Hongkong username: root password: root secondary: jdbc-url: jdbc:mysql://${MYSQL_HOST:localhost}:${MYSQL_PORT:3306}/${DB_NAME:anbang1}?useUnicode=true&characterEncoding=UTF8&serverTimezone=Hongkong username: root password: root jpa: database: mysql database-platform: org.hibernate.dialect.MySQL5InnoDBDialect #不加這句則默認(rèn)為myisam引擎 hibernate: ddl-auto: update naming: physical-strategy: org.springframework.boot.orm.jpa.hibernate.SpringPhysicalNamingStrategy open-in-view: true properties: enable_lazy_load_no_trans: true show-sql: true cloud: nacos: discovery: server-addr: ${NACOS_SERVER:localhost:8848} ###############################---log---############################## logging: file: ./logback.log
yml里配置了兩個(gè)數(shù)據(jù)源,和一些jpa和Hibernate的配置。
下面是DataSource的配置
/** * @author wuweifeng wrote on 2019/3/5. */ @Configuration public class DataSourceConfig { @Primary @Bean(name = "primaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.primary") public DataSource dataSourceOrder() { return DataSourceBuilder.create().build(); } @Bean(name = "secondaryDataSource") @ConfigurationProperties(prefix = "spring.datasource.secondary") public DataSource dataSourceAuth() { return DataSourceBuilder.create().build(); } }
下面是第一個(gè)數(shù)據(jù)源的配置
package com.mm.dmp.t3cc.config; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties; import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.annotation.Resource; import javax.persistence.EntityManager; import javax.sql.DataSource; /** * @author wuweifeng wrote on 2019/3/5. */ @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef = "entityManagerFactoryPrimary", transactionManagerRef = "transactionManagerPrimary", basePackages = {"com.mm.dmp.t3cc.core.repository.one"}) public class OneConfig { @Resource @Qualifier("primaryDataSource") private DataSource primaryDataSource; @Primary @Bean(name = "entityManagerPrimary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactoryPrimary(builder).getObject().createEntityManager(); } @Resource private JpaProperties jpaProperties; @Resource private HibernateProperties properties; /** * 設(shè)置實(shí)體類所在位置 */ @Primary @Bean(name = "entityManagerFactoryPrimary") public LocalContainerEntityManagerFactoryBean entityManagerFactoryPrimary(EntityManagerFactoryBuilder builder) { LocalContainerEntityManagerFactoryBean entityManagerFactory = builder .dataSource(primaryDataSource) //.packages(classes) //設(shè)置實(shí)體類所在位置 .packages("com.mm.dmp.t3cc.core.entity.one") .persistenceUnit("primaryPersistenceUnit") //.properties(jpaProperties.getProperties()) .properties(properties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings())) .build(); return entityManagerFactory; } @Primary @Bean(name = "transactionManagerPrimary") public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactoryPrimary(builder).getObject()); } }
這里會和別人的配置不一樣,主要區(qū)別在于HibernateProperties。別人的在第61行,我注釋掉的那行,會直接使用jpaProperties.getProperties()。當(dāng)你這樣寫之后,會發(fā)現(xiàn)yml里配置的Hibernate的update自動(dòng)生成表,和命名方式并沒有生效。
原因我們可以看一下。
這里就是jpaProperties.getProperties()的地方,如果打斷點(diǎn)可以看到,只有箭頭這一個(gè)配置被加載進(jìn)去了。上面的Hibernate的ddl和naming并沒有進(jìn)去。
來看一下HibernateProperties
這里才是真正讓自動(dòng)建表生效的地方,然而并沒有加載進(jìn)去。那么就需要我們手工來添加了。
這里面有個(gè)determineHibernateProperties方法,就是來組合jpaProperties和HibernateProperties的地方。我們應(yīng)該使用這個(gè)方法來組合整個(gè)配置的map對象。
也就是在OneConfig類中,把兩個(gè)Properties都定義出來,然后組合一下,就是箭頭的地方。在debug時(shí),就可以看到Hibernate的配置也都加載進(jìn)來了。
OK,以上就是動(dòng)態(tài)數(shù)據(jù)源配置Hibernate自動(dòng)建表不生效的原因。
下面是第二個(gè)數(shù)據(jù)源的配置
package com.mm.dmp.t3cc.config; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties; import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings; import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; 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.transaction.PlatformTransactionManager; import org.springframework.transaction.annotation.EnableTransactionManagement; import javax.annotation.Resource; import javax.persistence.EntityManager; import javax.sql.DataSource; /** * @author wuweifeng wrote on 2019/3/5. */ @Configuration @EnableTransactionManagement @EnableJpaRepositories( entityManagerFactoryRef = "entityManagerFactorySecondary", transactionManagerRef = "transactionManagerSecondary", basePackages = {"com.mm.dmp.t3cc.core.repository.two"}) //設(shè)置Repository所在位置 public class TwoConfig { @Resource @Qualifier("secondaryDataSource") private DataSource secondaryDataSource; @Resource private JpaProperties jpaProperties; @Resource private HibernateProperties properties; @Bean(name = "entityManagerSecondary") public EntityManager entityManager(EntityManagerFactoryBuilder builder) { return entityManagerFactorySecondary(builder).getObject().createEntityManager(); } @Bean(name = "entityManagerFactorySecondary") public LocalContainerEntityManagerFactoryBean entityManagerFactorySecondary(EntityManagerFactoryBuilder builder) { LocalContainerEntityManagerFactoryBean entityManagerFactory = builder .dataSource(secondaryDataSource) //.packages(classes) //設(shè)置實(shí)體類所在位置 .packages("com.mm.dmp.t3cc.core.entity.two") .persistenceUnit("secondaryPersistenceUnit") .properties(properties.determineHibernateProperties(jpaProperties.getProperties(), new HibernateSettings())) .build(); return entityManagerFactory; } @Bean(name = "transactionManagerSecondary") public PlatformTransactionManager transactionManagerPrimary(EntityManagerFactoryBuilder builder) { return new JpaTransactionManager(entityManagerFactorySecondary(builder).getObject()); } }
如果你覺得這樣比較麻煩,并且還有分庫分表的需求,那么可以使用sharding jdbc來操作,移步這一篇文章
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java實(shí)現(xiàn)多線程輪流打印1-100的數(shù)字操作
這篇文章主要介紹了Java實(shí)現(xiàn)多線程輪流打印1-100的數(shù)字操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-08-08Java中遍歷數(shù)組使用foreach循環(huán)還是for循環(huán)?
這篇文章主要介紹了Java中遍歷數(shù)組使用foreach循環(huán)還是for循環(huán)?本文著重講解for語句的語法并給出使用實(shí)例,同時(shí)總結(jié)出盡量使用foreach語句遍歷數(shù)組,需要的朋友可以參考下2015-06-06java objectUtils 使用可能會出現(xiàn)的問題
這篇文章主要介紹了java objectUtils 使用可能會出現(xiàn)的問題,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-02-02java String[]字符串?dāng)?shù)組自動(dòng)排序的簡單實(shí)現(xiàn)
下面小編就為大家?guī)硪黄猨ava String[]字符串?dāng)?shù)組自動(dòng)排序的簡單實(shí)現(xiàn)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-09-09java實(shí)現(xiàn)excel和txt文件互轉(zhuǎn)
本篇文章主要介紹了java實(shí)現(xiàn)excel和txt文件互轉(zhuǎn)的相關(guān)知識。具有很好的參考價(jià)值。下面跟著小編一起來看下吧2017-04-04關(guān)于SpringMVC在Controller層方法的參數(shù)解析詳解
在SpringMVC中,控制器Controller負(fù)責(zé)處理由DispatcherServlet分發(fā)的請求,下面這篇文章主要給大家介紹了關(guān)于SpringMVC在Controller層方法的參數(shù)解析的相關(guān)資料,需要的朋友可以參考下2021-12-12Java 使用keytool創(chuàng)建CA證書的操作
這篇文章主要介紹了Java 使用keytool創(chuàng)建CA證書的操作,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01java原生序列化和Kryo序列化性能實(shí)例對比分析
這篇文章主要介紹了java原生序列化和Kryo序列化性能實(shí)例對比分析,涉及Java和kryo序列化和反序列化相關(guān)實(shí)例,小編覺得很不錯(cuò),這里分享給大家,希望給大家一個(gè)參考。2017-10-10Java @PostMapping和@GetMapping方法使用詳解
這篇文章主要介紹了Java @PostMapping和@GetMapping方法使用,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-03-03