You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
database/hibernate/src/main/java/config/HibernateConfig.java

170 lines
6.5 KiB

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<Class, TableInfo> tableNotes = new HashMap<>();
public static TableInfo getTableNote(Class c) {
return tableNotes.get(c);
}
private static final Map<Class<? extends Annotation>, SessionFactory> map = new HashMap<>();
public static SessionFactory get(Class<? extends Annotation> 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<DataSourceModel> dataSourceModels;
try {
dataSourceModels = JSON.parseObject(FileUtils.readFileToString(ResourceUtils.getFile(CONFIG_NAME), "UTF-8"), new TypeReference<List<DataSourceModel>>() {
});
} 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();
}
}