适用范围åQšé€‚åˆSSH架构讉K—®å¤šä¸ªæ•°æ®åº“,数æ®åº“çš„¾cÕdž‹å’Œè¡¨¾l“æž„ä¸å¿…相åŒåQŒä¸”没有跨库事务的情况(跨库事务最好用分布å¼äº‹åС处ç†ï¼‰ã€?/p>
<!-- Hibernate SessionFactorys -->
<bean id="aSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="aDataSource" />
</property>
<property name="mappingResources">
<list>
<value>
.hbm.xmlæ–‡äšg
</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${ahibernate.dialect}
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="format_sql">true</prop>
</props>
</property>
</bean>
<bean id="bSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="bDataSource" />
</property>
<property name="mappingResources">
<list>
<value>
.hbm.xmlæ–‡äšg
</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${bhibernate.dialect}
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="format_sql">true</prop>
</props>
</property>
</bean>
<bean id="cSessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource">
<ref local="cDataSource" />
</property>
<property name="mappingResources">
<list>
<value>
.hbm.xmlæ–‡äšg
</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">
${chibernate.dialect}
</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="format_sql">true</prop>
</props>
</property>
</bean>
<bean id="sessionFactory" class="com.cintel.dcp.datasource.MultiSessionFactory">
<property name="sessionFactory"><ref local="aSessionFactory"/></property>
</bean>
注æ„åQ?font color="#ff0000">最åŽä¸€ä¸?font color="#0000ff">com.cintel.dcp.datasource.MultiSessionFactoryè¦è‡ªå·±å®žçŽŽÍ¼Œå®ƒå®žçŽîCº†SessionFactory接å£å’ŒApplicationContext接å£åQŒå¦‚下:
package com.cintel.dcp.datasource;
import java.io.Serializable;
import java.sql.Connection;
import java.util.Map;
import java.util.Set;
import javax.naming.NamingException;
import javax.naming.Reference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.HibernateException;
import org.hibernate.Interceptor;
import org.hibernate.SessionFactory;
import org.hibernate.StatelessSession;
import org.hibernate.classic.Session;
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;
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;
}
public SessionFactory getSessionFactory(String sessionFactoryName) {
log.debug("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 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 Session openSession() throws HibernateException {
return getSessionFactory().openSession();
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#openSession(java.sql.Connection)
*/
public Session openSession(Connection connection) {
return getSessionFactory().openSession(connection);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#openSession(org.hibernate.Interceptor)
*/
public Session openSession(Interceptor interceptor) throws HibernateException {
return getSessionFactory().openSession(interceptor);
}
/* (non-Javadoc)
* @see org.hibernate.SessionFactory#openSession(java.sql.Connection, org.hibernate.Interceptor)
*/
public 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 Reference getReference() throws NamingException {
return getSessionFactory().getReference();
}
}
ç„¶åŽæˆ‘用一个常é‡ç±»æ¥æ ‡è¯†sessionFactory
public class DynamicDataSourceType {
public static final String A= "aSessionFactory";
public static final String B= "bSessionFactory";
public static final String C= "cSessionFactory";
}
最åŽä¸€ä¸ªå…³é”®ç±»åQšç”¨æ¥å˜æ”‘Ö½“剿£åœ¨ä‹É用的sessionFactory
public class CustomerContextHolder {
private static final ThreadLocal contextHolder = new ThreadLocal();
public static void setCustomerType(String customerType) {
Assert.notNull(customerType, "customerType cannot be null");
contextHolder.set(customerType);
}
public static String getCustomerType() {
return (String) contextHolder.get();
}
public static void clearCustomerType() {
contextHolder.remove();
}
}
å¯ä»¥åœ¨actionã€serviceã€daoä¸è¿›è¡Œæ•°æ®åº“切æ¢åQŒåˆ‡æ¢æ–¹å¼ï¼š
CustomerContextHolder.setCustomerType(DynamicDataSourceType.A);
以上æ€èµ\æ¥è‡ªjavaEye论å›çš„ä¸€ä¸ªé«˜æ‰‹ï¼Œåœ¨æ¤æ ‡è¯†æ„Ÿè°¢
æ–‡ç« æ¥æºåQ?/strong>
èµ·å› åQšåœ¨å½“剿ˆ‘手上的一个项目ä¸éœ€è¦å¤šä¸ªæ•°æ®æº,òq¶ä¸”æ¥è‡ªäºŽä¸åŒç±»åž‹çš„æ•°æ®åº?.. å› äØ“å¾ˆå¤šåŽ†å²åŽŸå› .˜q™ä¸ª™å¹ç›®çš„使•°æ®æºæ˜¯MySQL,整个¾pÈ»Ÿçš„CURD都是æ“作的这个数æ®åº“.
但是˜q˜æœ‰å¦å¤–两个用于数æ®é‡‡é›†çš„æ•°æ®åº“: MSSQL,ACCESS.˜q˜å¥½åªæ˜¯ç”¨äºŽæ•°æ®é‡‡é›†åQŒåœ¨äº‹åŠ¡ä¸Šå¯ä»¥ä¸è¦è·¨æ•°æ®åº“了åQŒè¿™ä¸€ç‚¹èŠ‚çœäº†å¥½å¤šçš„工作é‡.环境åQšæˆ‘æå¾çš„æµ‹è¯•环境是 spring2.5.6+hibernate3.2package lhp.example.context;
public enum DBType {
dataSource1, dataSource2;
}
package lhp.example.context;
public class ContextHolder {
private static final ThreadLocal<Object> holder = new ThreadLocal<Object>();
public static void setDbType(DBType dbType) {
holder.set(dbType);
}
public static DBType getDbType() {
return (DBType) holder.get();
}
public static void clearDbType() {
holder.remove();
}
}
package lhp.example.context;
import java.util.logging.Logger;
import org.springframework.jdbc.datasource.lookup.AbstractRoutingDataSource;
public class DynamicDataSource extends AbstractRoutingDataSource {
public static final Logger logger = Logger.getLogger(DynamicDataSource.class.toString());
@Override
protected Object determineCurrentLookupKey() {
DBType key = ContextHolder.getDbType();//èŽ·å¾—å½“å‰æ•°æ®æºæ ‡è¯†ç¬¦
//logger.info("当剿•°æ®æº?:" + key);
return key;
}
}
<!-- æ•°æ®æº? åQ?mysql -->
<bean id="dataSource1" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/dec" />
<property name="user" value="root" />
<property name="password" value="" />
</bean>
<!-- æ•°æ®æº? åQ?mysql -->
<bean id="dataSource2" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="com.mysql.jdbc.Driver" />
<property name="jdbcUrl" value="jdbc:mysql://127.0.0.1:3306/lms" />
<property name="user" value="root" />
<property name="password" value="" />
</bean>
<!-- æ•°æ®æº? åQ? access -->
<bean id="dataSource3" class="com.mchange.v2.c3p0.ComboPooledDataSource">
<property name="driverClass" value="sun.jdbc.odbc.JdbcOdbcDriver" />
<property name="jdbcUrl" value="jdbc:odbc:accessTest" />
<property name="user" value="administrator" />
<property name="password" value="XLZX0309" />
</bean>
<!-- mysql åŠ¨æ€æ•°æ®æºè®„¡½®-->
<bean id="mysqlDynamicDataSource" class="lhp.example.context.DynamicDataSource">
<property name="targetDataSources">
<!-- æ ‡è¯†½W¦ç±»åž?-->
<map key-type="lhp.example.context.DBType">
<entry key="dataSource1" value-ref="dataSource1" />
<entry key="dataSource2" value-ref="dataSource2" />
</map>
</property>
<property name="defaultTargetDataSource" ref="dataSource1" />
</bean>
<!-- mysql sessionFactory -->
<bean id="mysqlSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="mysqlDynamicDataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">org.hibernate.dialect.MySQLDialect</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop><!--create validate -->
<prop key="hibernate.query.substitutions">true 1, false 0</prop>
</props>
</property>
</bean>
<!-- access sessionFactory -->
<bean id="aceessSessionFactory" class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource3" />
<property name="hibernateProperties">
<props>
<!-- access è¯æ³•å’ŒMSSQLç›æ€¼¼ 所以用的MSSQL方言åQŒæˆ–者å¯ä»¥ä‹É用第三方方言 -->
<prop key="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</prop>
<prop key="hibernate.jdbc.batch_size">30</prop>
<prop key="hibernate.jdbc.fetch_size">50</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">false</prop>
<prop key="hibernate.hbm2ddl.auto">update</prop><!--create validate -->
<prop key="hibernate.query.substitutions">true 1, false 0</prop>
<prop key="hibernate.cglib.use_reflection_optimizer">true</prop>
<!-- <prop key="hibernate.cache.use_second_level_cache">true</prop> -->
<!-- <prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop> -->
<!-- <prop key="hibernate.cache.use_query_cache">true</prop> -->
<!-- <prop key="hibernate.generate_statistics">true</prop> -->
<!-- <prop key="hibernate.cache.provider_configuration_file_resource_path">classpath:ehcache.xml</prop> -->
</props>
</property>
</bean>
package lhp.example.junit;
import static org.junit.Assert.*;
import java.sql.DatabaseMetaData;
import lhp.example.context.ContextHolder;
import lhp.example.context.DBType;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.junit.Before;
import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class ServiceTest {
private ApplicationContext context;
//ä¸‰ä¸ªæ•°æ®æºçš„URL
private String dataSource1_URL = "jdbc:mysql://127.0.0.1:3306/dec";
private String dataSource2_URL = "jdbc:mysql://127.0.0.1:3306/lms";
private String dataSource3_URL = "jdbc:odbc:accessTest";
private SessionFactory mysqlSessionFactory;
private SessionFactory aceessSessionFactory;
@Before
public void setUp() throws Exception {
// é€‰æ‹©æ•°æ®æºåˆå§‹åŒ–spring
ContextHolder.setDbType(DBType.dataSource1);
//
String[] xmlFiles = new String[] {
"applicationContext-dataSource.xml",
"applicationContext-hibernate.xml",
"applicationContext-spring.xml" };
//
context = new ClassPathXmlApplicationContext(xmlFiles);
//
mysqlSessionFactory = (SessionFactory) context.getBean("mysqlSessionFactory");
aceessSessionFactory = (SessionFactory) context.getBean("aceessSessionFactory");
}
@SuppressWarnings("deprecation")
@Test
public void mysqlDataSourceTest() {
try {
Session mysqlSession = mysqlSessionFactory.openSession();
// 获得数æ®åº“元数æ®
DatabaseMetaData meatData = mysqlSession.connection().getMetaData();
// 默认å¯åŠ¨æ•°æ®æº?dataSource1
//æ–è¨€å½“å‰æ•°æ®æºURLæ˜¯å¦æ˜¯dataSource1çš„URL
assertEquals(dataSource1_URL, meatData.getURL());
// 切æ¢åˆ°æ•°æ®æº dataSource2
ContextHolder.setDbType(DBType.dataSource2);
mysqlSession = mysqlSessionFactory.openSession();
meatData = mysqlSession.connection().getMetaData();
//æ–è¨€å½“å‰æ•°æ®æºURLæ˜¯å¦æ˜¯dataSource2çš„URL
assertEquals(dataSource2_URL, meatData.getURL());
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("deprecation")
@Test
public void accessDataSourceTest() {
try {
Session accessSession = aceessSessionFactory.openSession();
// 获得数æ®åº“元数æ®
DatabaseMetaData meatData = accessSession.connection().getMetaData();
//æ–è¨€å½“å‰æ•°æ®æºURLæ˜¯å¦æ˜¯dataSource3çš„URL
assertEquals(dataSource3_URL, meatData.getURL());
} catch (Exception e) {
e.printStackTrace();
}
}
}