多数据源---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包
上一篇: Spark 集群架构
下一篇: spring多数据源