package config; import annotation.TableInfo; import com.alibaba.druid.pool.DruidDataSource; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.TypeReference; import model.DataSourceModel; import org.apache.commons.io.FileUtils; import org.apache.commons.lang3.StringUtils; import org.hibernate.SessionFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.support.DefaultListableBeanFactory; import org.springframework.core.type.filter.AnnotationTypeFilter; import org.springframework.orm.hibernate5.HibernateTemplate; import org.springframework.orm.hibernate5.HibernateTransactionManager; import org.springframework.orm.hibernate5.LocalSessionFactoryBean; import org.springframework.util.ResourceUtils; import javax.sql.DataSource; import java.io.IOException; import java.lang.annotation.Annotation; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Properties; /** * Created by reborn on 2017/7/28. */ public class HibernateConfig extends InitConfig { private static final String CONFIG_NAME = "classpath:database.json"; @Autowired private DefaultListableBeanFactory beanFactory; private static final Map tableNotes = new HashMap<>(); public static TableInfo getTableNote(Class c) { return tableNotes.get(c); } private static final Map, SessionFactory> map = new HashMap<>(); public static SessionFactory get(Class c) { return map.get(c); } /** * 注册数据源 * * @param dbName 数据库名 * @param dbPort 端口 * @param username 用户名 * @param password 密码 * @param type 数据库类型 * @return */ private DruidDataSource dataSource(String dbHost, String dbName, int dbPort, String username, String password, DBType type) { DruidDataSource dataSource = new DruidDataSource(); dataSource.setUsername(username); dataSource.setPassword(password); String url = ""; switch (type) { case mysql57: url = type.getUrl(dbHost, dbPort, dbName); dataSource.setUrl(url); dataSource.setDriverClassName(type.getDriver().getName()); break; } LOG.info("数据源初始化\nurl=" + url + "\nusername=" + username + "\npassword=" + password); return dataSource; } private DruidDataSource dataSource(DataSourceModel dataSourceModel) { return dataSource(dataSourceModel.getHost(), dataSourceModel.getDbName(), dataSourceModel.getPort(), dataSourceModel.getUsername(), dataSourceModel.getPassword(), dataSourceModel.getDbType()); } /** * 初始化数据源 * * @param dataSourceModel * @return */ private HibernateTemplate initDB(DataSourceModel dataSourceModel) throws IOException { DruidDataSource dataSource = dataSource(dataSourceModel); SessionFactory sessionFactory = initSessionFactory(dataSource, (LocalSessionFactoryBean bean) -> { //按照注解标记从指定包扫描实体类,并且注册到session工厂 bean.setPackagesToScan(dataSourceModel.getPackagesToScan()); bean.setEntityTypeFilters(new AnnotationTypeFilter(dataSourceModel.getAnnotation())); }, dataSourceModel.getDbName(), dataSourceModel.getDbType().getDialect().getName()); beanFactory.registerSingleton(dataSourceModel.getSessionFactoryBean(), sessionFactory); if (sessionFactory != null) { HibernateTransactionManager hibernateTransactionManager = new HibernateTransactionManager(); hibernateTransactionManager.setSessionFactory(sessionFactory); hibernateTransactionManager.setDataSource(dataSource); hibernateTransactionManager.afterPropertiesSet(); //添加事务管理器 beanFactory.registerSingleton(dataSourceModel.getTransactionManagerBean(), hibernateTransactionManager); return new HibernateTemplate(sessionFactory); } else { throw new RuntimeException("sessionFactory is Null"); } } /** * 初始化数据源,session工厂 */ private void init() { //从根数据源读取其他数据源信息,并初始化 List dataSourceModels; try { dataSourceModels = JSON.parseObject(FileUtils.readFileToString(ResourceUtils.getFile(CONFIG_NAME), "UTF-8"), new TypeReference>() { }); } catch (IOException e) { LOG.error("解析数据库配置失败"); throw new RuntimeException(e); } if (dataSourceModels.size() == 0) { throw new RuntimeException("没有配置数据源,初始化失败"); } dataSourceModels.forEach(dataSourceModel -> { if (map.containsKey(dataSourceModel.getAnnotation())) { throw new RuntimeException("数据库配置无效,注解" + dataSourceModel.getAnnotation() + "已重复"); } HibernateTemplate hibernateTemplate; try { hibernateTemplate = initDB(dataSourceModel); beanFactory.registerSingleton(dataSourceModel.getHibernateBean(), hibernateTemplate); map.put(dataSourceModel.getAnnotation(), hibernateTemplate.getSessionFactory()); } catch (IOException e) { LOG.error("无法获取HibernateTemplate"); throw new RuntimeException(e); } }); } /** * 初始化session工厂 * * @param dataSource * @param config * @return */ private SessionFactory initSessionFactory(DataSource dataSource, SessionFactoryConfig config, String defaultSchema, String dialect) throws IOException { LocalSessionFactoryBean bean = new LocalSessionFactoryBean(); Properties properties = new Properties(); properties.setProperty("hibernate.dialect", dialect); properties.setProperty("hibernate.format_sql", "true"); if (StringUtils.isNotEmpty(defaultSchema)) { properties.setProperty("hibernate.default_schema", defaultSchema); } bean.setHibernateProperties(properties); bean.setDataSource(dataSource); config.call(bean); bean.afterPropertiesSet(); return bean.getObject(); } @Override public void afterPropertiesSet() throws Exception { super.afterPropertiesSet(); init(); } }