HibernateLocalSessionFactoryBean.java 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. package com.primeton.dgs.kernel.core.dao.hibernate;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.sql.Connection;
  5. import java.sql.DatabaseMetaData;
  6. import java.sql.SQLException;
  7. import java.util.Map;
  8. import java.util.Properties;
  9. import com.primeton.dgs.kernel.core.util.MetadataWebContext;
  10. import com.primeton.dgs.kernel.core.web.springframework.DatabaseRecognizer;
  11. import org.slf4j.Logger;
  12. import org.slf4j.LoggerFactory;
  13. import org.springframework.context.ApplicationContextException;
  14. import org.springframework.core.io.Resource;
  15. import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
  16. import org.springframework.core.io.support.ResourcePatternResolver;
  17. import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
  18. import javax.sql.DataSource;
  19. /**
  20. * Hibernate 配置。
  21. *
  22. * 加载不同的 Hibernate 配置,根据 DatabaseRecognizer 返回的数据库类别,初始化不同的 Hibernate 方言
  23. *
  24. * @author zhaopx
  25. *
  26. */
  27. public class HibernateLocalSessionFactoryBean extends LocalSessionFactoryBean {
  28. private static final String PREFIX = "META-INF/hibernate/"; // 加载hibernate模型文件的路径前缀
  29. private static final String ENDFIX = "*.hbm.xml"; // 文件名的扩展后缀名
  30. private DatabaseRecognizer databaseRecognizer;
  31. // 数据库的品牌和版本
  32. private String databaseProductName;
  33. private String databaseProductVersion;
  34. private static final Logger logger = LoggerFactory.getLogger(HibernateLocalSessionFactoryBean.class);
  35. @Override
  36. public void setDataSource(DataSource dataSource) {
  37. super.setDataSource(dataSource);
  38. try(Connection conn = dataSource.getConnection()) {
  39. DatabaseMetaData meta = conn.getMetaData();
  40. String databaseName = meta.getDatabaseProductName();
  41. String productVersion = meta.getDatabaseProductVersion();
  42. if (logger.isInfoEnabled()) {
  43. logger.info("Current Database is " + databaseName + ", Version is " + productVersion);
  44. }
  45. databaseName = recognizeDatabaseName(databaseName, productVersion);
  46. databaseRecognizer.setCurrentDatabaseProductName(databaseName);
  47. databaseRecognizer.setCurrentDatabaseProductVersion(productVersion);
  48. // 将数据库名缓存起来
  49. MetadataWebContext.getInstance().setDatabaseName(databaseName);
  50. } catch (SQLException e) {
  51. String s = "Cannot determine the database brand name for loading ApplicationContext";
  52. logger.error(s, e);
  53. throw new ApplicationContextException(s, e);
  54. }
  55. }
  56. /**
  57. * 覆写该方法,将hibernate配置文件,通过读取特定类路径下的文件获取
  58. */
  59. @Override
  60. public void setMappingResources(String mappingResources[]) {
  61. try {
  62. ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  63. Resource[] resources = resolver.getResources("classpath*:".concat(PREFIX).concat(ENDFIX));
  64. String[] resourceStrings = new String[resources.length];
  65. for(int index = 0; index < resources.length; index++){
  66. resourceStrings[index] = PREFIX.concat(resources[index].getFilename());
  67. }
  68. super.setMappingResources(resourceStrings);
  69. } catch (IOException e) {
  70. throw new IllegalStateException("无法加载 " + ENDFIX + " 文件。", e);
  71. }
  72. }
  73. @Override
  74. public void afterPropertiesSet() throws IOException {
  75. // 首先根据数据库选择配置文件
  76. String databaseName = MetadataWebContext.getInstance().getDatabaseName();
  77. Properties props = new Properties();
  78. String configFile = "classpath*:".concat("/spring/hibernate_").concat(databaseName.toLowerCase()).concat("_local.properties");
  79. try {
  80. ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
  81. Resource[] resources = resolver.getResources(configFile);
  82. for (Resource resource : resources) {
  83. logger.info("found hibernate local file: {}", resource.getURL());
  84. try(InputStream inputStream = resource.getInputStream()) {
  85. Properties tmp = new Properties();
  86. tmp.load(inputStream);
  87. props.putAll(tmp);
  88. }
  89. }
  90. } catch (Exception e) {
  91. logger.error("无法读取配置文件: " + configFile, e);
  92. }
  93. if(!props.isEmpty()) {
  94. for (Map.Entry<Object, Object> entry : props.entrySet()) {
  95. getHibernateProperties().put(entry.getKey(), entry.getValue());
  96. }
  97. }
  98. logger.info("hibernate properties print as ");
  99. for (Map.Entry<Object, Object> entry : getHibernateProperties().entrySet()) {
  100. logger.info("{}: {}", entry.getKey(), entry.getValue());
  101. }
  102. super.afterPropertiesSet();
  103. }
  104. /**
  105. * 识别数据库名称,已经配置在spring/corebean/context-base.xml文件中
  106. * @param databaseName 从数据库连接获取的数据库名称
  107. * @param productVersion 数据库版本
  108. * @return 转换成系统需要的名称
  109. */
  110. private String recognizeDatabaseName(String databaseName, String productVersion) {
  111. this.databaseProductName = databaseName;
  112. this.databaseProductVersion = productVersion;
  113. return databaseRecognizer.getDatabaseName(databaseName);
  114. }
  115. public void setDatabaseRecognizer(DatabaseRecognizer databaseRecognizer) {
  116. this.databaseRecognizer = databaseRecognizer;
  117. }
  118. public String getDatabaseProductName() {
  119. return databaseProductName;
  120. }
  121. public String getDatabaseProductVersion() {
  122. return databaseProductVersion;
  123. }
  124. }