欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

多数据源---SessionFactory

程序员文章站 2022-07-15 10:08:26
...

之前做过一个多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包