恢复hibernate规约配置
This commit is contained in:
14
README.md
Normal file
14
README.md
Normal 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/)
|
||||||
@@ -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!
|
|
||||||
注意配置自己的数据库连接地址,工程内的连接地址已经失效
|
|
||||||
@@ -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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
|
||||||
Reference in New Issue
Block a user