package com.primeton.dgs.kernel.core.dao.jpa; import com.primeton.dgs.kernel.core.util.MetadataWebContext; import com.primeton.dgs.kernel.core.web.springframework.DatabaseRecognizer; import org.apache.commons.lang.StringUtils; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContextException; import org.springframework.core.io.Resource; import org.springframework.core.io.support.PathMatchingResourcePatternResolver; import org.springframework.core.io.support.ResourcePatternResolver; import org.springframework.orm.jpa.JpaVendorAdapter; import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean; import org.springframework.orm.jpa.vendor.Database; import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter; import javax.persistence.PersistenceException; import javax.sql.DataSource; import java.io.InputStream; import java.sql.Connection; import java.sql.DatabaseMetaData; import java.sql.SQLException; import java.util.Arrays; import java.util.Map; import java.util.Properties; /** * * JPA 配置 * *
 *
 * Created by zhaopx.
 * User: zhaopx
 * Date: 2020/9/1
 * Time: 17:44
 *
 * 
* * @author zhaopx */ public class JpaContainerEntityManagerFactoryBean extends LocalContainerEntityManagerFactoryBean implements InitializingBean { private DatabaseRecognizer databaseRecognizer; @Override public void afterPropertiesSet() throws PersistenceException { // 扫描配置文件 // 首先根据数据库选择配置文件 String databaseName = MetadataWebContext.getInstance().getDatabaseName(); Properties props = new Properties(); String configFile = "classpath*:".concat("/spring/hibernate_").concat(databaseName.toLowerCase()).concat("_local.properties"); try { ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver(); Resource[] resources = resolver.getResources(configFile); for (Resource resource : resources) { try(InputStream inputStream = resource.getInputStream()) { Properties tmp = new Properties(); tmp.load(inputStream); props.putAll(tmp); } } } catch (Exception e) { logger.error("无法读取配置文件: " + configFile, e); } if(!props.isEmpty()) { for (Map.Entry entry : props.entrySet()) { getJpaPropertyMap().put((String) entry.getKey(), entry.getValue()); } } Database database; try { database = Database.valueOf(databaseName.toUpperCase()); } catch (Exception e) { logger.error("unkown db " + databaseName + " use Database.DEFAULT, please set spring bean databaseRecognizer key-value, to match " + Arrays.asList(Database.values())); database = Database.DEFAULT; } final HibernateJpaVendorAdapter jpaVendorAdapter = new HibernateJpaVendorAdapter(); jpaVendorAdapter.setDatabasePlatform((String) getJpaPropertyMap().get("hibernate.dialect")); jpaVendorAdapter.setDatabase(database); jpaVendorAdapter.setGenerateDdl(false); jpaVendorAdapter.setShowSql(true); setJpaVendorAdapter(jpaVendorAdapter); super.afterPropertiesSet(); } @Override public void setDataSource(DataSource dataSource) { super.setDataSource(dataSource); // DB Type if(StringUtils.isBlank(MetadataWebContext.getInstance().getDatabaseName())) { try (Connection conn = dataSource.getConnection()) { DatabaseMetaData meta = conn.getMetaData(); String databaseName = meta.getDatabaseProductName(); String productVersion = meta.getDatabaseProductVersion(); if (logger.isInfoEnabled()) { logger.info("Current Database is " + databaseName + ", Version is " + productVersion); } databaseName = recognizeDatabaseName(databaseName, productVersion); // 将数据库名缓存起来 MetadataWebContext.getInstance().setDatabaseName(databaseName); } catch (SQLException e) { String s = "Cannot determine the database brand name for loading ApplicationContext"; logger.error(s, e); throw new ApplicationContextException(s, e); } } } /** * 识别数据库名称,已经配置在spring/corebean/context-base.xml文件中 * @param databaseName 从数据库连接获取的数据库名称 * @param productVersion 数据库版本 * @return 转换成系统需要的名称 */ private String recognizeDatabaseName(String databaseName, String productVersion) { return databaseRecognizer.getDatabaseName(databaseName); } public void setDatabaseRecognizer(DatabaseRecognizer databaseRecognizer) { this.databaseRecognizer = databaseRecognizer; } }