恢复hibernate规约配置

This commit is contained in:
2019-03-30 19:23:07 +08:00
parent e5337bd1fb
commit a8c366c5b5
4 changed files with 184 additions and 7 deletions

14
README.md Normal file
View File

@@ -0,0 +1,14 @@
## SpringBoot 2.x Configure Two DataSources Demo Project
SpringBoot 2.x Configure Two DataSources (base version 2.1.3)
You should configure your own database connection address, the connection address in the project has expired!
Study record[SpringBoot2.x Data JPA 多数据源爬坑](https://blog.fjy8018.top/index.php/archives/202/)
## SpringBoot 2.x 多数据源配置样例工程
SpringBoot 2.x 多数据源配置样例工程基于SpringBoot 2.1.3版本有效
注意配置自己的数据库连接地址,工程内的连接地址已经失效
爬坑过程:[SpringBoot2.x Data JPA 多数据源爬坑](https://blog.fjy8018.top/index.php/archives/202/)

View File

@@ -1,5 +0,0 @@
## SpringBoot 2.x Configure Two DataSources Demo Project
SpringBoot 2.x Configure Two DataSources (base version 2.1.3)
You should configure your own database connection address, the connection address in the project has expired!
注意配置自己的数据库连接地址,工程内的连接地址已经失效

View File

@@ -1,23 +1,45 @@
package top.fjy8018.jpadatasource.config; package top.fjy8018.jpadatasource.config;
import com.zaxxer.hikari.HikariDataSource; import com.zaxxer.hikari.HikariDataSource;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
import org.hibernate.boot.model.naming.PhysicalNamingStrategy;
import org.hibernate.cfg.AvailableSettings;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties; import org.springframework.boot.autoconfigure.jdbc.DataSourceProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateProperties;
import org.springframework.boot.autoconfigure.orm.jpa.HibernatePropertiesCustomizer;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateSettings;
import org.springframework.boot.autoconfigure.orm.jpa.JpaProperties;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.jdbc.EmbeddedDatabaseConnection;
import org.springframework.boot.jdbc.SchemaManagement;
import org.springframework.boot.jdbc.SchemaManagementProvider;
import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder; import org.springframework.boot.orm.jpa.EntityManagerFactoryBuilder;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary; import org.springframework.context.annotation.Primary;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories; import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.orm.hibernate5.SpringBeanContainer;
import org.springframework.orm.jpa.JpaTransactionManager; import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager; import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.util.ClassUtils;
import top.fjy8018.jpadatasource.entity.backup.Order; import top.fjy8018.jpadatasource.entity.backup.Order;
import top.fjy8018.jpadatasource.entity.primary.Product; import top.fjy8018.jpadatasource.entity.primary.Product;
import top.fjy8018.jpadatasource.repository.backup.OrderRepository; import top.fjy8018.jpadatasource.repository.backup.OrderRepository;
import top.fjy8018.jpadatasource.repository.primary.ProductRepository; import top.fjy8018.jpadatasource.repository.primary.ProductRepository;
import javax.sql.DataSource; import javax.sql.DataSource;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.StreamSupport;
/** /**
* @author F嘉阳 * @author F嘉阳
@@ -25,6 +47,32 @@ import javax.sql.DataSource;
*/ */
@Configuration @Configuration
public class DataAccessConfig { public class DataAccessConfig {
private final ObjectProvider<SchemaManagementProvider> providers;
private final HibernateProperties hibernateProperties;
private final JpaProperties properties;
private final ObjectProvider<PhysicalNamingStrategy> physicalNamingStrategy;
private final ObjectProvider<ImplicitNamingStrategy> implicitNamingStrategy;
private final ConfigurableListableBeanFactory beanFactory;
private final ObjectProvider<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers;
@Autowired
public DataAccessConfig(ObjectProvider<SchemaManagementProvider> providers, HibernateProperties hibernateProperties, JpaProperties properties, ObjectProvider<PhysicalNamingStrategy> physicalNamingStrategy, ObjectProvider<ImplicitNamingStrategy> implicitNamingStrategy, ConfigurableListableBeanFactory beanFactory, ObjectProvider<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers) {
this.providers = providers;
this.hibernateProperties = hibernateProperties;
this.properties = properties;
this.physicalNamingStrategy = physicalNamingStrategy;
this.implicitNamingStrategy = implicitNamingStrategy;
this.beanFactory = beanFactory;
this.hibernatePropertiesCustomizers = hibernatePropertiesCustomizers;
}
@Bean @Bean
@Primary @Primary
@ConfigurationProperties("spring.datasource.first") @ConfigurationProperties("spring.datasource.first")
@@ -59,6 +107,8 @@ public class DataAccessConfig {
EntityManagerFactoryBuilder builder, @Qualifier("firstDataSource") DataSource dataSource) { EntityManagerFactoryBuilder builder, @Qualifier("firstDataSource") DataSource dataSource) {
return builder return builder
.dataSource(dataSource) .dataSource(dataSource)
// 加入规约配置
.properties(getVendorProperties(dataSource))
.packages(Product.class) .packages(Product.class)
.persistenceUnit("first") .persistenceUnit("first")
.build(); .build();
@@ -69,6 +119,7 @@ public class DataAccessConfig {
EntityManagerFactoryBuilder builder, @Qualifier("secondDataSource") DataSource dataSource) { EntityManagerFactoryBuilder builder, @Qualifier("secondDataSource") DataSource dataSource) {
return builder return builder
.dataSource(dataSource) .dataSource(dataSource)
.properties(getVendorProperties(dataSource))
.packages(Order.class) .packages(Order.class)
.persistenceUnit("second") .persistenceUnit("second")
.build(); .build();
@@ -96,5 +147,123 @@ public class DataAccessConfig {
entityManagerFactoryRef = "secondEntityManagerFactory", transactionManagerRef = "backupTransactionManager") entityManagerFactoryRef = "secondEntityManagerFactory", transactionManagerRef = "backupTransactionManager")
public class secondConfiguration { public class secondConfiguration {
} }
/**
* 获取配置文件信息
*
* @param dataSource
* @return
*/
private Map<String, Object> getVendorProperties(DataSource dataSource) {
List<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers = determineHibernatePropertiesCustomizers(
physicalNamingStrategy.getIfAvailable(),
implicitNamingStrategy.getIfAvailable(), beanFactory,
this.hibernatePropertiesCustomizers.orderedStream()
.collect(Collectors.toList()));
Supplier<String> defaultDdlMode = () -> new HibernateDefaultDdlAutoProvider(providers)
.getDefaultDdlAuto(dataSource);
return new LinkedHashMap<>(this.hibernateProperties.determineHibernateProperties(
properties.getProperties(),
new HibernateSettings().ddlAuto(defaultDdlMode)
.hibernatePropertiesCustomizers(
hibernatePropertiesCustomizers)));
}
/**
* 命名策略自动判断
*
* @param physicalNamingStrategy
* @param implicitNamingStrategy
* @param beanFactory
* @param hibernatePropertiesCustomizers
* @return
*/
private List<HibernatePropertiesCustomizer> determineHibernatePropertiesCustomizers(
PhysicalNamingStrategy physicalNamingStrategy,
ImplicitNamingStrategy implicitNamingStrategy,
ConfigurableListableBeanFactory beanFactory,
List<HibernatePropertiesCustomizer> hibernatePropertiesCustomizers) {
List<HibernatePropertiesCustomizer> customizers = new ArrayList<>();
if (ClassUtils.isPresent(
"org.hibernate.resource.beans.container.spi.BeanContainer",
getClass().getClassLoader())) {
customizers
.add((properties) -> properties.put(AvailableSettings.BEAN_CONTAINER,
new SpringBeanContainer(beanFactory)));
}
if (physicalNamingStrategy != null || implicitNamingStrategy != null) {
customizers.add(new NamingStrategiesHibernatePropertiesCustomizer(
physicalNamingStrategy, implicitNamingStrategy));
}
customizers.addAll(hibernatePropertiesCustomizers);
return customizers;
}
/**
* 自动进行建表操作
*/
class HibernateDefaultDdlAutoProvider implements SchemaManagementProvider {
private final Iterable<SchemaManagementProvider> providers;
HibernateDefaultDdlAutoProvider(Iterable<SchemaManagementProvider> providers) {
this.providers = providers;
}
public String getDefaultDdlAuto(DataSource dataSource) {
if (!EmbeddedDatabaseConnection.isEmbedded(dataSource)) {
return "none";
}
SchemaManagement schemaManagement = getSchemaManagement(dataSource);
if (SchemaManagement.MANAGED.equals(schemaManagement)) {
return "none";
}
return "create-drop";
}
@Override
public SchemaManagement getSchemaManagement(DataSource dataSource) {
return StreamSupport.stream(this.providers.spliterator(), false)
.map((provider) -> provider.getSchemaManagement(dataSource))
.filter(SchemaManagement.MANAGED::equals).findFirst()
.orElse(SchemaManagement.UNMANAGED);
}
}
private static class NamingStrategiesHibernatePropertiesCustomizer
implements HibernatePropertiesCustomizer {
private final PhysicalNamingStrategy physicalNamingStrategy;
private final ImplicitNamingStrategy implicitNamingStrategy;
NamingStrategiesHibernatePropertiesCustomizer(
PhysicalNamingStrategy physicalNamingStrategy,
ImplicitNamingStrategy implicitNamingStrategy) {
this.physicalNamingStrategy = physicalNamingStrategy;
this.implicitNamingStrategy = implicitNamingStrategy;
}
/**
* 数据库命名映射策略
*
* @param hibernateProperties the JPA vendor properties to customize
*/
@Override
public void customize(Map<String, Object> hibernateProperties) {
if (this.physicalNamingStrategy != null) {
hibernateProperties.put("hibernate.physical_naming_strategy",
this.physicalNamingStrategy);
}
if (this.implicitNamingStrategy != null) {
hibernateProperties.put("hibernate.implicit_naming_strategy",
this.implicitNamingStrategy);
}
}
}
} }

View File

@@ -23,5 +23,4 @@ spring:
properties: properties:
hibernate: hibernate:
format_sql: true format_sql: true
use_sql_comments: true use_sql_comments: true
generate-ddl: true