hibernate动态多数据源
Posted 姚__
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了hibernate动态多数据源相关的知识,希望对你有一定的参考价值。
hibernate动态多数据源包括自动建表
网上搜了不少,只有多数据源的配置,但最主要的自动建表没有,我研究清楚记录下
hibernate 动态多数据源配置
hibernate的xml配置文件,设置多个数据源
<bean id="dataSourceOne" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${hibernate.connection.url}" />
<property name="username"><value>${hibernate.connection.username}</value></property>
<property name="password" value="${hibernate.connection.password}" />
<property name="filters"><value>stat</value></property>
<property name="maxActive"><value>100</value></property>
<property name="initialSize"><value>1</value></property>
<property name="maxWait"><value>60000</value></property>
<property name="minIdle"><value>1</value></property>
<property name="timeBetweenEvictionRunsMillis"><value>60000</value></property>
<property name="minEvictableIdleTimeMillis"><value>300000</value></property>
<property name="validationQuery"><value>SELECT 'x'</value></property>
<property name="testWhileIdle"><value>true</value></property>
<property name="testOnBorrow"><value>false</value></property>
<property name="testOnReturn"><value>false</value></property>
<property name="poolPreparedStatements"><value>true</value></property>
<property name="maxOpenPreparedStatements"><value>20</value></property>
</bean>
<bean id="dataSourceTwo" class="com.alibaba.druid.pool.DruidDataSource" init-method="init" destroy-method="close">
<property name="url" value="${hibernate.connection.url2}" />
<property name="username"><value>${hibernate.connection.username}</value></property>
<property name="password" value="${hibernate.connection.password}" />
<property name="filters"><value>stat</value></property>
<property name="maxActive"><value>100</value></property>
<property name="initialSize"><value>1</value></property>
<property name="maxWait"><value>60000</value></property>
<property name="minIdle"><value>1</value></property>
<property name="timeBetweenEvictionRunsMillis"><value>60000</value></property>
<property name="minEvictableIdleTimeMillis"><value>300000</value></property>
<property name="validationQuery"><value>SELECT 'x'</value></property>
<property name="testWhileIdle"><value>true</value></property>
<property name="testOnBorrow"><value>false</value></property>
<property name="testOnReturn"><value>false</value></property>
<property name="poolPreparedStatements"><value>true</value></property>
<property name="maxOpenPreparedStatements"><value>20</value></property>
</bean>
新增一个动态数据源bean
<bean class="com.test.common.dao.DynamicDataSource" id="dataSourceTarget">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry value-ref="dataSourceOne" key="one"></entry>
<entry value-ref="dataSourceTwo" key="two"></entry>
</map>
</property>
<property name="debug" value="true"/>
<property name="defaultTargetDataSource" ref="dataSourceOne" ></property>
</bean>
然后是sessionFactory的设置
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSourceTarget" />
<property name="namingStrategy">
<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.format_sql">${hibernate.format_sql}</prop>
<prop key="hibernate.generate_statistics">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>com.test.**.bean</value>
</list>
</property>
</bean>
可以看到动态数据源使用了重新编写的类,具体代码如下
public class DynamicDataSource extends AbstractRoutingDataSource {
private boolean debug = false;
Logger log = Logger.getLogger(DynamicDataSource.class);
private Map<Object, Object> dynamicTargetDataSources;
private Object dynamicDefaultTargetDataSource;
@Override
protected Object determineCurrentLookupKey() {
String datasource = DBContextHolder.getDataSource();
if (debug) {
if (StringUtils.isEmpty(datasource)) {
log.info("---当前数据源:默认数据源---");
} else {
log.info("---当前数据源:" + datasource + "---");
}
}
return datasource;
}
@Override
public void setTargetDataSources(Map<Object, Object> targetDataSources) {
super.setTargetDataSources(targetDataSources);
this.dynamicTargetDataSources = targetDataSources;
}
// 创建数据源
public boolean createDataSource(String key, String driveClass, String url, String username, String password) {
try {
try { // 排除连接不上的错误
Class.forName(driveClass);
DriverManager.getConnection(url, username, password);// 相当于连接数据库
} catch (Exception e) {
return false;
}
@SuppressWarnings("resource")
DruidDataSource druidDataSource = new DruidDataSource();
druidDataSource.setName(key);
druidDataSource.setDriverClassName(driveClass);
druidDataSource.setUrl(url);
druidDataSource.setUsername(username);
druidDataSource.setPassword(password);
druidDataSource.setMaxWait(60000);
druidDataSource.setFilters("stat");
DataSource createDataSource = (DataSource) druidDataSource;
druidDataSource.init();
Map<Object, Object> dynamicTargetDataSources2 = this.dynamicTargetDataSources;
dynamicTargetDataSources2.put(key, createDataSource);// 加入map
setTargetDataSources(dynamicTargetDataSources2);// 将map赋值给父类的TargetDataSources
super.afterPropertiesSet();// 将TargetDataSources中的连接信息放入resolvedDataSources管理
return true;
} catch (Exception e) {
log.info(e + "");
return false;
}
}
// 删除数据源
public boolean delDatasources(String datasourceid) {
Map<Object, Object> dynamicTargetDataSources2 = this.dynamicTargetDataSources;
if (dynamicTargetDataSources2.containsKey(datasourceid)) {
Set<DruidDataSource> druidDataSourceInstances = DruidDataSourceStatManager.getDruidDataSourceInstances();
for (DruidDataSource l : druidDataSourceInstances) {
if (datasourceid.equals(l.getName())) {
System.out.println(l);
dynamicTargetDataSources2.remove(datasourceid);
DruidDataSourceStatManager.removeDataSource(l);
setTargetDataSources(dynamicTargetDataSources2);// 将map赋值给父类的TargetDataSources
super.afterPropertiesSet();// 将TargetDataSources中的连接信息放入resolvedDataSources管理
return true;
}
}
return false;
} else {
return false;
}
}
// 测试数据源连接是否有效
public boolean testDatasource(String key, String driveClass, String url, String username, String password) {
try {
Class.forName(driveClass);
DriverManager.getConnection(url, username, password);
return true;
} catch (Exception e) {
return false;
}
}
/**
* Specify the default target DataSource, if any.
* <p>
* The mapped value can either be a corresponding
* {@link javax.sql.DataSource} instance or a data source name String (to be
* resolved via a {@link #setDataSourceLookup DataSourceLookup}).
* <p>
* This DataSource will be used as target if none of the keyed
* {@link #setTargetDataSources targetDataSources} match the
* {@link #determineCurrentLookupKey()} current lookup key.
*/
public void setDefaultTargetDataSource(Object defaultTargetDataSource) {
super.setDefaultTargetDataSource(defaultTargetDataSource);
this.dynamicDefaultTargetDataSource = defaultTargetDataSource;
}
/**
* @param debug
* the debug to set
*/
public void setDebug(boolean debug) {
this.debug = debug;
}
/**
* @return the debug
*/
public boolean isDebug() {
return debug;
}
/**
* @return the dynamicTargetDataSources
*/
public Map<Object, Object> getDynamicTargetDataSources() {
return dynamicTargetDataSources;
}
/**
* @param dynamicTargetDataSources
* the dynamicTargetDataSources to set
*/
public void setDynamicTargetDataSources(Map<Object, Object> dynamicTargetDataSources) {
this.dynamicTargetDataSources = dynamicTargetDataSources;
}
/**
* @return the dynamicDefaultTargetDataSource
*/
public Object getDynamicDefaultTargetDataSource() {
return dynamicDefaultTargetDataSource;
}
/**
* @param dynamicDefaultTargetDataSource
* the dynamicDefaultTargetDataSource to set
*/
public void setDynamicDefaultTargetDataSource(Object dynamicDefaultTargetDataSource) {
this.dynamicDefaultTargetDataSource = dynamicDefaultTargetDataSource;
}
@Override
public java.util.logging.Logger getParentLogger() throws SQLFeatureNotSupportedException {
// TODO以上是关于hibernate动态多数据源的主要内容,如果未能解决你的问题,请参考以下文章
具有运行时 pojos 的带有 Hibernate 的 OSGi 片段包