Hibernate的多数据源多数据库
基于SPRING+HIBERNATE的数据库的实现多租户的数据库选择和数据源路由
applicationContext.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:context="http://www.springframework.org/schema/context" xmlns:tx="http://www.springframework.org/schema/tx"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.1.xsd">
<!-- 加载jdbc.property,hibenrate.properties -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="locations">
<list>
<value>classpath:jdbc.properties</value>
<value>classpath:hibernate.properties</value>
</list>
</property>
<!-- 容许多次加载属性文件 -->
<property name="ignoreUnresolvablePlaceholders" value="true" />
</bean>
<!-- 连接池 -->
<bean id="dataSource1" name="dataSource1"
class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl}"></property>
<property name="user" value="${jdbc.user}"></property>
<property name="password" value="${jdbc.password}"></property>
<property name="initialPoolSize" value="5"></property>
<property name="minPoolSize" value="1"></property>
<property name="maxPoolSize" value="100"></property>
<property name="checkoutTimeout" value="5000"></property>
<property name="maxIdleTime" value="1800"></property>
<property name="idleConnectionTestPeriod" value="60"></property>
<property name="acquireIncrement" value="5"></property>
<!-- mysql连接超时,默认8小时,解决方案1 -->
<property name="preferredTestQuery" value="SELECT 1"></property>
<property name="testConnectionOnCheckin" value="true"></property>
<property name="testConnectionOnCheckout" value="true"></property>
</bean>
<bean id="dataSource2" name="dataSource2"
class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
<property name="driverClass" value="${jdbc.driverClass}"></property>
<property name="jdbcUrl" value="${jdbc.jdbcUrl_1}"></property>
<property name="user" value="${jdbc.user_1}"></property>
<property name="password" value="${jdbc.password_1}"></property>
<property name="initialPoolSize" value="5"></property>
<property name="minPoolSize" value="1"></property>
<property name="maxPoolSize" value="100"></property>
<property name="checkoutTimeout" value="5000"></property>
<property name="maxIdleTime" value="1800"></property>
<property name="idleConnectionTestPeriod" value="60"></property>
<property name="acquireIncrement" value="5"></property>
<!-- mysql连接超时,默认8小时,解决方案1 -->
<property name="preferredTestQuery" value="SELECT 1"></property>
<property name="testConnectionOnCheckin" value="true"></property>
<property name="testConnectionOnCheckout" value="true"></property>
</bean>
<bean id="dynamicDataSource" class="com.zhenjw.db.DynamicDataSource" >
<property name="targetDataSources">
<!--标识符类型-->
<map key-type="java.lang.String">
<entry key="kdataSource1" value-ref="dataSource1"/>
<entry key="kdataSource2" value-ref="dataSource2"/>
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource1" />
</bean>
<!-- hibernate4的sessionFacotry,hibernate4没有模版对象,直接使用sessionFactory,hibenrate4默认支持注解 -->
<bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dynamicDataSource"></property>
<!-- hibernate注解搜索路径 * 指定有注解的Hibenrate实体类的包 -->
<property name="packagesToScan">
<list>
<value>com.zhenjw.oa.**.entity</value>
</list>
</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.use_sql_comments">${hibernate.use_sql_comments}</prop>
<prop key="hibernate.autoReconnect">${hibernate.autoreconnect}</prop>
<!-- 设置数据库批量查询最大数量 -->
<prop key="hibernate.jdbc.fetch_size">${hibernate.jdbc.fetch_size}</prop>
<!-- 设置数据库批量更新、添加、删除最大数量 -->
<prop key="hibernate.jdbc.batch_size">${hibernate.jdbc.batch_size}</prop>
<!-- 二级缓存配置 -->
<!-- 是否开启二级缓存 -->
<prop key="hibernate.cache.use_second_level_cache">${hibernate.cache.use_second_level_cache}</prop>
<!-- 是否开启查询时的二级缓存,由于命中率很低,通常关闭 -->
<prop key="hibernate.cache.use_query_cache">${hibernate.cache.use_query_cache}</prop>
<!-- 设置二级缓存实现类 -->
<prop key="hibernate.cache.region.factory_class">${hibernate.cache.region.factory_class}</prop>
<!-- 如果是oracle 11g,需要制定默认schema <prop key="hibernate.default_schema">${hibernate.default_schema}</prop> -->
</props>
</property>
</bean>
<!-- 多数据源 -->
<!-- hibernate4的sessionFacotry,hibernate4没有模版对象,直接使用sessionFactory,hibenrate4默认支持注解 -->
<!-- 注解搜索路径 -->
<context:component-scan base-package="com.zhenjw" />
<!-- 支持注解依赖注入 -->
<context:annotation-config />
</beans>java源代码
package com.zhenjw.db;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource{
private Map dataSourceMap=new HashMap();
@Override
protected Object determineCurrentLookupKey() {
// TODO Auto-generated method stub
//数据源的选择,根据自己的业务修改具体的实现,是返回数据源的key
String sp = SpObserver.getSp();
return sp;
}
@Override
public Connection getConnection() throws SQLException {
// TODO Auto-generated method stub
Connection a= super.getConnection();
//用于选择数据库的逻辑,基于自己的业务规则进行修改
a.prepareStatement("use oa_2 ").executeUpdate();
return a;
}
}package com.zhenjw.db;
public class SpObserver {
private static ThreadLocal local = new ThreadLocal();
private static String sp;
public static void putSp(String sp) {
local.set(sp);
}
public static String getSp() {
return (String)local.get();
}
}package test.db;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.zhenjw.db.BaseDaoImpl;
import com.zhenjw.db.SpObserver;
import com.zhenjw.oa.wzaccount.entity.WzAccount;
public class TestDataSource {
//private static ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext-base.xml");
private static ApplicationContext ac=new ClassPathXmlApplicationContext("applicationContext-base2.xml");
public static void main(String[] args) {
// TODO Auto-generated method stub
SpObserver.putSp("kdataSource2");
BaseDaoImpl baseDao=ac.getBean(BaseDaoImpl.class);
System.out.println(baseDao);
WzAccount account=new WzAccount("zhenjw3");
baseDao.create(account);
System.out.println("Over");
}
}DAO层按hibernate的普通调用方式就可以了。结合具体的项目具体的实现有时间再细化,已经测试过可以向不同的数据源不同的数据库中增加数据。其它的功能应该也没有问题。
相关推荐
lbyd0 2020-11-17
腾讯soso团队 2020-11-06
yangkang 2020-11-09
KANSYOUKYOU 2020-11-16
wushengyong 2020-10-28
Apsaravod 2020-11-05
PeterChangyb 2020-11-05
gyunwh 2020-11-02