Hibernate 主从数据库配置

<?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:tx="http://www.springframework.org/schema/tx" xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="
        http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
        http://www.springframework.org/schema/tx 
        http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
        http://www.springframework.org/schema/aop 
        http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context-3.0.xsd">


<context:annotation-config />


<!-- 加载配置文件 -->
<bean id="propertyConfigurer"
class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:db1.properties" />
</bean>


<!-- c3p0配置 -->
<bean id="parentDataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="${jdbc.driverClass}" /> <!-- 驱动类 -->
<property name="minPoolSize" value="${jdbc.minPoolSize}" /> <!-- 最小连接数 -->
<property name="maxPoolSize" value="${jdbc.maxPoolSize}" /> <!-- 最大连接数 -->
<property name="initialPoolSize" value="${jdbc.initialPoolSize}" />   <!-- 初始连接数 -->
<property name="maxIdleTime" value="${jdbc.maxIdleTime}" />       <!-- 空闲丢弃时间 -->
<property name="acquireIncrement" value="${jdbc.acquireIncrement}" /> <!-- 耗尽再创建的连接数 -->
<property name="maxStatements" value="${jdbc.maxStatements}" /> <!-- 最大Statemenet数 -->
<property name="idleConnectionTestPeriod" value="${jdbc.idleConnectionTestPeriod}" /> <!-- 间隔检查空闲连接秒数 -->
<property name="acquireRetryAttempts" value="${jdbc.acquireRetryAttempts}" /> <!-- 获取连接失败继续尝试次数 -->
<property name="breakAfterAcquireFailure" value="${jdbc.breakAfterAcquireFailure}" /> <!-- 获取连接失败数据源是否关闭 -->
<property name="testConnectionOnCheckout" value="${jdbc.testConnectionOnCheckout}" /> <!-- connection提交检验有限性 -->
</bean>


<!-- 配置主数据源 -->
<bean id="masterDataSource" parent="parentDataSource"
destroy-method="close">
<property name="jdbcUrl" value="${jdbc.jdbcUrl.master}" /> <!-- 连接字符串 -->
<property name="user" value="${jdbc.user.master}" /> <!-- 用户名 -->
<property name="password" value="${jdbc.password.master}" /> <!-- 密码 -->
</bean>


<!-- 配置从数据源 -->
<bean id="slaveDataSource" parent="parentDataSource"
destroy-method="close">
<property name="jdbcUrl" value="${jdbc.jdbcUrl.slave}" /> <!-- 连接字符串 -->
<property name="user" value="${jdbc.user.slave}" /> <!-- 用户名 -->
<property name="password" value="${jdbc.password.slave}" /> <!-- 密码 -->
</bean>


<!-- 配置数据源 -->
<bean id="dataSource" class="com.dxm.aop.DynamicDataSource">
<property name="targetDataSources">
<map key-type="java.lang.String">
<entry key="slave" value-ref="slaveDataSource" />
</map>
</property>
<property name="defaultTargetDataSource" ref="masterDataSource" />
</bean>


<!-- 配置sessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource"></property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</prop>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.format_sql">true</prop>
<prop key="hibernate.connection.autocommit">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop>
<prop key="hibernate.generate_statistics">true</prop>
<prop key="hibernate.connection.release_mode">auto</prop>
<prop key="hibernate.autoReconnect">true</prop>
<prop key="hibernate.cache.use_query_cache">true</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
</props>
</property>
<property name="mappingResources">
<list>
<value>com/dxm/model/Notes.hbm.xml</value>
</list>
</property>
</bean>


<!-- 切换数据源 -->
<bean id="dataSourceAdvice" class="com.dxm.aop.DataSourceAdvice" />
<aop:config>
<aop:advisor pointcut="execution(* com.dxm.dao..DataImpl.*(..))"
advice-ref="dataSourceAdvice" />
</aop:config>


<!-- 配置hibernateTemplate -->
<bean id="hibernateTemplate" class="org.springframework.orm.hibernate3.HibernateTemplate">
<property name="sessionFactory">
<ref local="sessionFactory" />
</property>
</bean>


<!-- 定义事务管理器(声明式的事务) -->
<bean id="transactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>


<!-- 事务拦截器 -->
<bean id="transactionInterceptor"
class="org.springframework.transaction.interceptor.TransactionInterceptor">
<property name="transactionManager">
<ref bean="transactionManager" />
</property>
<property name="transactionAttributes">
<props>
<prop key="*">PROPAGATION_REQUIRED</prop>
</props>
</property>
</bean>


<!-- 自动代理 -->
<bean id="autoproxy"
class="org.springframework.aop.framework.autoproxy.BeanNameAutoProxyCreator">
<property name="beanNames">
<list>
<value>*Impl</value>
</list>
</property>
<property name="interceptorNames">
<list>
<value>transactionInterceptor</value>
</list>
</property>
</bean>

</beans> 


package com.dxm.aop;


import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;


public class DynamicDataSource extends AbstractRoutingDataSource {


@Override
protected Object determineCurrentLookupKey() {
return DataSourceSwitcher.getDataSource();
}
}


package com.dxm.aop;


import java.lang.reflect.Method;
import java.util.HashSet;
import java.util.Set;


import org.apache.log4j.Logger;
import org.springframework.aop.AfterReturningAdvice;
import org.springframework.aop.MethodBeforeAdvice;
import org.springframework.aop.ThrowsAdvice;


public class DataSourceAdvice implements MethodBeforeAdvice, AfterReturningAdvice, ThrowsAdvice {


// 日志
private Logger log = Logger.getLogger(DataSourceAdvice.class);


// 选用主数据库的方法前缀
public static Set<String> masterMethod = new HashSet<String>();
public static Set<String> slaveMethod = new HashSet<String>();


static {
masterMethod.add("add");
masterMethod.add("insert");
masterMethod.add("delete");
masterMethod.add("update");


slaveMethod.add("query");
slaveMethod.add("getByKey");
slaveMethod.add("getAll");
slaveMethod.add("findBySql");
slaveMethod.add("findByHql");
slaveMethod.add("getCount");
}


@Override
public void before(Method method, Object[] args, Object target) throws Throwable {


String methodName = method.getName();
log.info("__________________切入点: " + target.getClass().getName() + "类中" + methodName + "方法");


if (masterMethod.contains(methodName)) {
log.info("__________________切换到主数据库");
DataSourceSwitcher.setMaster();
} else if (slaveMethod.contains(methodName)) {
log.info("__________________切换到从数据库");
DataSourceSwitcher.setSlave();
} else {
log.info("__________________没有找到要切换的数据库");
}
}


@Override
public void afterReturning(Object arg0, Method method, Object[] args, Object target) throws Throwable {
}


/**
* 抛出Exception之后被调用

* @param method
* @param args
* @param target
* @param ex
* @throws Throwable
*/
public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {
DataSourceSwitcher.setSlave();
log.info("出现异常,切换到: slave");
}
}


package com.dxm.aop;


import org.springframework.util.Assert;


/**
 * 切换数据源
 * 
 * @author dxm
 * 
 */
@SuppressWarnings({ "rawtypes", "unchecked" })
public class DataSourceSwitcher {


private static final ThreadLocal contextHolder = new ThreadLocal();


public static void setMaster() {
contextHolder.remove();
}


public static void setSlave() {
Assert.notNull("slave", "dataSource cannot be null");
contextHolder.set("slave");
}


public static String getDataSource() {
Object source = contextHolder.get();
return (String) source;
}


}

Hibernate 主从数据库配置,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。