多数据源---SessionFactory

之前做过一个多database的例子,当时没有达到动态更换数据源的目的。

后来做了个多session工厂的例子,达到了动态更换数据源的目的了。在网上有些例子,

不过感觉有帮助但是不全,特此把我自己的弄得贴出来,如果说的不清楚的话,可以下载

附件看代码!

 

spring配置文件

<?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:context="http://www.springframework.org/schema/context"
	xmlns:aop="http://www.springframework.org/schema/aop"
	xmlns:tx="http://www.springframework.org/schema/tx"
	xsi:schemaLocation="
	   http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
       http://www.springframework.org/schema/context
       http://www.springframework.org/schema/context/spring-context-2.5.xsd
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-2.5.xsd
       http://www.springframework.org/schema/aop 
       http://www.springframework.org/schema/aop/spring-aop-2.5.xsd"
	default-autowire="byName">
	
	
	<context:annotation-config />
	<bean id="parentDataSource"
		class="org.apache.commons.dbcp.BasicDataSource">
		<property name="driverClassName">
			<value>com.mysql.jdbc.Driver</value>
		</property>
		<property name="username" value="root"></property>
		<property name="password" value="hejie"></property>
	</bean>

	<bean id="primaryDataSource" parent="parentDataSource">
		<property name="url">
			<value>jdbc:mysql://localhost:3306/test1</value>
		</property>
	</bean>

	<bean id="backupDataSource" parent="parentDataSource">
		<property name="url">
			<value>jdbc:mysql://localhost:3306/test2</value>
		</property>
	</bean>
	<!-- 
	<bean id="dataSource" scope="prototype"
		class="com.mul.spring.MyAbstractRoutingDataSource">
		<property name="targetDataSources">
			<map key-type="java.lang.String">
				<entry key="admin1" value-ref="primaryDataSource" />
				<entry key="guest1" value-ref="backupDataSource" />
			</map>
		</property>
		<property name="defaultTargetDataSource" ref="primaryDataSource" />
	</bean>
 	-->
	<bean id="sessionFactory1"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="primaryDataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<prop key="hibernate.current_session_context_class">
					thread
				</prop>
				<prop key="hibernate.show_sql">false</prop>
			</props>
		</property>

		<property name="mappingResources">
			<list>
				<value>
					com/mul/entity/DataEntity.hbm.xml
				</value>
			</list>
		</property>

		<property name="exposeTransactionAwareSessionFactory">
			<value>false</value>
		</property>

	</bean>
	<bean id="sessionFactory2"
		class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
		<property name="dataSource">
			<ref bean="backupDataSource" />
		</property>
		<property name="hibernateProperties">
			<props>
				<prop key="hibernate.dialect">
					org.hibernate.dialect.MySQLDialect
				</prop>
				<prop key="hibernate.show_sql">true</prop>
				<prop key="hibernate.format_sql">true</prop>
				<prop key="hibernate.hbm2ddl.auto">update</prop>
				<prop key="hibernate.current_session_context_class">
					thread
				</prop>
				<prop key="hibernate.show_sql">false</prop>
			</props>
		</property>

		<property name="mappingResources">
			<list>
				<value>
					com/mul/entity/DataEntity.hbm.xml
				</value>
			</list>
		</property>

		<property name="exposeTransactionAwareSessionFactory">
			<value>false</value>
		</property>

	</bean>
	
	<bean id="sessionFactory" class="com.mul.spring.MultiSessionFactory">
	   <property name="sessionFactory"><ref local="sessionFactory2"/></property>
	</bean>
	
	<bean id="transactionManager"
		class="org.springframework.orm.hibernate3.HibernateTransactionManager">
		<property name="sessionFactory" ref="sessionFactory" />
<!--		<property name="hibernateManagedSession" value="false"/>-->
	</bean>
	<tx:annotation-driven transaction-manager="transactionManager" />
	<context:component-scan base-package="com.mul" />

		<aop:config>
	
			<aop:pointcut id="testservice"
				expression="execution(* com.mul.service.*Service.*(..))" />
			
				
			<aop:advisor id="testServiceAd" advice-ref="txAdvice" pointcut-ref="testservice" />		
		</aop:config>
		<tx:advice id="txAdvice" transaction-manager="transactionManager">
			<tx:attributes>
				<tx:method name="*" propagation="REQUIRED" rollback-for="java.lang.Exception"/>
<!--				<tx:method name="*" propagation="REQUIRED"/>-->
			</tx:attributes>
		</tx:advice>


	


	
	
	<!-- dao -->
	<bean id="dataEntityDao" class="com.mul.dao.DataEntityDao">

	</bean>
	<!-- service -->
	<bean id="dataEntityService" class="com.mul.service.DataEntityService">

	</bean>
	
</beans>

 

 映射文件

<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
	<!--
		Mapping file autogenerated by MyEclipse Persistence Tools
	-->
<hibernate-mapping>
	<class name="com.mul.entity.DataEntity" table="dataentity"
		mutable="false">
		<id name="id" type="java.lang.Integer">
			<column name="id" />
			<generator class="native"></generator>
		</id>
		<property name="name" type="java.lang.String">
			<column name="name" length="128" />
		</property>
		<property name="age">
			<column name="age" />
		</property>
	</class>


</hibernate-mapping>

 

 

dao

package com.mul.dao;

import org.springframework.orm.hibernate3.support.HibernateDaoSupport;

import com.mul.entity.DataEntity;

public class DataEntityDao extends HibernateDaoSupport{
	public DataEntity save(DataEntity de){
		this.getSession().save(de);
		return de;
	}
}

 

 

service

package com.mul.service;

import com.mul.dao.DataEntityDao;
import com.mul.entity.DataEntity;
import com.mul.spring.CustomerContextHolder;
import com.mul.spring.DynamicDataSourceType;

public class DataEntityService {
	private DataEntityDao dataEntityDao ;
	public DataEntity save(DataEntity de){
		System.out.println("保存到s1:"+DynamicDataSourceType.S1);
		this.dataEntityDao.save(de);
		return de;
	}
	public DataEntity save2(DataEntity de){
		System.out.println("保存到s2:"+DynamicDataSourceType.S2);
		this.dataEntityDao.save(de);
		return de;
	}
	public DataEntityDao getDataEntityDao() {
		return dataEntityDao;
	}
	public void setDataEntityDao(DataEntityDao dataEntityDao) {
		this.dataEntityDao = dataEntityDao;
	}
	
}

 

servlet: 建议使用struts试一试,在servlet中跟我在网上查的不同

package com.mul.servlet;

import java.io.IOException;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mul.entity.DataEntity;
import com.mul.service.DataEntityService;
import com.mul.spring.CustomerContextHolder;
import com.mul.spring.DataSourceTypeChoose;
import com.mul.spring.DataSourceTypeKey;
import com.mul.spring.DynamicDataSourceType;

public class mulDataServlet extends HttpServlet {
	public mulDataServlet() {
		super();
	}
	public void destroy() {
		super.destroy(); 
	}
	public void doGet(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {
		this.doPost(request, response);
	}
	public void doPost(HttpServletRequest request, HttpServletResponse response)
			throws ServletException, IOException {

		String name = request.getParameter("name");
		String age = request.getParameter("age");
		String db = request.getParameter("db");
		
		DataEntity de = new DataEntity(name,new Integer(age==null?"16":age));
		System.out.println("要保存的对象:"+de);
//		if("admin1".equals(db))
//			DataSourceTypeChoose.setThreadLocal(DataSourceTypeKey.ADMIN);
//		else
//			DataSourceTypeChoose.setThreadLocal(DataSourceTypeKey.GUEST);
		if(DataSourceTypeKey.appContext == null)
			DataSourceTypeKey.appContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
		DataEntityService dataEntityService = (DataEntityService)DataSourceTypeKey.appContext.getBean("dataEntityService");
		System.out.println("开始保存到数据库");
		if("admin1".equals(db)){
			//必须在save方法
			CustomerContextHolder.setCustomerType(DynamicDataSourceType.S1);
			dataEntityService.save(de);
		}else{
			CustomerContextHolder.setCustomerType(DynamicDataSourceType.S2);
			dataEntityService.save2(de);
		}
		
//		ApplicationContext appContext = new ClassPathXmlApplicationContext("/applicationContext.xml");
//		DataEntityService dataE = (DataEntityService)appContext.getBean("dataEntityService");
//		dataE.save(de);
		request.setAttribute("de", de);
		request.getRequestDispatcher("/index.jsp").forward(request, response);
	}

	/**
	 * Initialization of the servlet. <br>
	 *
	 * @throws ServletException if an error occurs
	 */
	public void init() throws ServletException {
		// Put your code here
	}

}

 

辅助类,为了线程安全

package com.mul.spring;

public class CustomerContextHolder {
	private static final ThreadLocal contextHolder = new ThreadLocal();

	public static void setCustomerType(String customerType) {
	   System.out.println(customerType+"  customerType cannot be null");
	   contextHolder.set(customerType);
	}

	public static String getCustomerType() {
	   return (String) contextHolder.get();
	}

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


}

 

 

统一管理session工厂的id

package com.mul.spring;

public class DynamicDataSourceType {
	public static final String S1= "sessionFactory1";
	public static final String S2= "sessionFactory2";

}

 

多sessionFactory的实现

package com.mul.spring;

import java.io.Serializable;
import java.lang.ref.Reference;
import java.sql.Connection;
import java.util.Map;
import java.util.Set;

import javax.naming.NamingException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.engine.FilterDefinition;
import org.hibernate.metadata.ClassMetadata;
import org.hibernate.metadata.CollectionMetadata;
import org.hibernate.stat.Statistics;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

/**
 * 多SessionFactory 的一个实现
 * @author hejie
 */
public class MultiSessionFactory implements SessionFactory, ApplicationContextAware {
	private static final long serialVersionUID = 2064557324203496378L;
	private static final Log log = LogFactory.getLog(MultiSessionFactory.class);
	private ApplicationContext applicationContext = null;
	private SessionFactory sessionFactory = null;

	public ApplicationContext getApplicationContext() {
	   return applicationContext;
	}

	public void setApplicationContext(ApplicationContext applicationContext) {
	   this.applicationContext = applicationContext;
	}
	//在每次拿到bean时都会检查你当前的sessionFactory,sessionFactoryName就是bean的id
	public SessionFactory getSessionFactory(String sessionFactoryName) {
	   System.out.println("=========sessionFactoryName:"+sessionFactoryName);
	   try{
	    if(sessionFactoryName==null||sessionFactoryName.equals("")){
	     return sessionFactory;
	    }
	    return (SessionFactory)this.getApplicationContext().getBean(sessionFactoryName);
	   }catch(NoSuchBeanDefinitionException ex){
	    throw new RuntimeException("There is not the sessionFactory <name:"+sessionFactoryName+"> in the applicationContext!");
	   }
	}
	public SessionFactory getSessionFactory() {
	   String sessionFactoryName = CustomerContextHolder.getCustomerType();
	   return getSessionFactory(sessionFactoryName);
	}

	public void setSessionFactory(SessionFactory sessionFactory) {
	   this.sessionFactory = sessionFactory;
	}


	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#close()
	*/
	public void close() throws HibernateException {
	   getSessionFactory().close();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#evict(java.lang.Class)
	*/
	public void evict(Class persistentClass) throws HibernateException {
	   getSessionFactory().evict(persistentClass);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#evict(java.lang.Class, java.io.Serializable)
	*/
	public void evict(Class persistentClass, Serializable id) throws HibernateException {
	   getSessionFactory().evict(persistentClass, id);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#evictCollection(java.lang.String)
	*/
	public void evictCollection(String roleName) throws HibernateException {
	   getSessionFactory().evictCollection(roleName);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#evictCollection(java.lang.String, java.io.Serializable)
	*/
	public void evictCollection(String roleName, Serializable id) throws HibernateException {
	   getSessionFactory().evictCollection(roleName, id);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#evictEntity(java.lang.String)
	*/
	public void evictEntity(String entityName) throws HibernateException {
	   getSessionFactory().evictEntity(entityName);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#evictEntity(java.lang.String, java.io.Serializable)
	*/
	public void evictEntity(String entityName, Serializable id) throws HibernateException {
	   getSessionFactory().evictEntity(entityName, id);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#evictQueries()
	*/
	public void evictQueries() throws HibernateException {
	   getSessionFactory().evictQueries();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#evictQueries(java.lang.String)
	*/
	public void evictQueries(String cacheRegion) throws HibernateException {
	   getSessionFactory().evictQueries(cacheRegion);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#getAllClassMetadata()
	*/
	public Map getAllClassMetadata() throws HibernateException {
	   return getSessionFactory().getAllClassMetadata();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#getAllCollectionMetadata()
	*/
	public Map getAllCollectionMetadata() throws HibernateException {
	   return getSessionFactory().getAllCollectionMetadata();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#getClassMetadata(java.lang.Class)
	*/
	public ClassMetadata getClassMetadata(Class persistentClass) throws HibernateException {
	   return getSessionFactory().getClassMetadata(persistentClass);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#getClassMetadata(java.lang.String)
	*/
	public ClassMetadata getClassMetadata(String entityName) throws HibernateException {
	   return getSessionFactory().getClassMetadata(entityName);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#getCollectionMetadata(java.lang.String)
	*/
	public CollectionMetadata getCollectionMetadata(String roleName) throws HibernateException {
	   return getSessionFactory().getCollectionMetadata(roleName);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#getCurrentSession()
	*/
	public org.hibernate.classic.Session getCurrentSession() throws HibernateException {
	   return getSessionFactory().getCurrentSession();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#getDefinedFilterNames()
	*/
	public Set getDefinedFilterNames() {
	   return getSessionFactory().getDefinedFilterNames();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#getFilterDefinition(java.lang.String)
	*/
	public FilterDefinition getFilterDefinition(String filterName) throws HibernateException {
	   return getSessionFactory().getFilterDefinition(filterName);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#getStatistics()
	*/
	public Statistics getStatistics() {
	   return getSessionFactory().getStatistics();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#isClosed()
	*/
	public boolean isClosed() {
	   return getSessionFactory().isClosed();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#openSession()
	*/
	public org.hibernate.classic.Session openSession() throws HibernateException {
	   return getSessionFactory().openSession();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#openSession(java.sql.Connection)
	*/
	public org.hibernate.classic.Session openSession(Connection connection) {
	   return getSessionFactory().openSession(connection);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#openSession(org.hibernate.Interceptor)
	*/
	public org.hibernate.classic.Session openSession(Interceptor interceptor) throws HibernateException {
	   return getSessionFactory().openSession(interceptor);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#openSession(java.sql.Connection, org.hibernate.Interceptor)
	*/
	public org.hibernate.classic.Session openSession(Connection connection, Interceptor interceptor) {
	   return getSessionFactory().openSession(connection, interceptor);
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#openStatelessSession()
	*/
	public StatelessSession openStatelessSession() {
	   return getSessionFactory().openStatelessSession();
	}
	/* (non-Javadoc)
	* @see org.hibernate.SessionFactory#openStatelessSession(java.sql.Connection)
	*/
	public StatelessSession openStatelessSession(Connection connection) {
	   return getSessionFactory().openStatelessSession(connection);
	}
	/* (non-Javadoc)
	* @see javax.naming.Referenceable#getReference()
	*/
	public javax.naming.Reference getReference() throws NamingException {
	   return getSessionFactory().getReference();
	}
	}

 

只创建一个application(struts等就不需要了)

package com.mul.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class DataSourceTypeKey {
	public static ApplicationContext appContext ; 
}

 

在servlet调用service时他去调用MultiSessionFactory openSession()

注意:发布项目是去掉asm-2.2.3.jar包

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值