




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
Spring3整合MyBatis3配置多數(shù)據(jù)源動(dòng)態(tài)選擇SqlSessionFactory一、摘要上兩篇文章分別介紹了Spring3.3整合Hibernate3、MyBatis3.2配置多數(shù)據(jù)源/動(dòng)態(tài)切換數(shù)據(jù)源方法和Spring3整合Hibernate3.5動(dòng)態(tài)切換SessionFactory(切換數(shù)據(jù)庫方言),這篇文章將介紹Spring整合Mybatis如何完成SqlSessionFactory的動(dòng)態(tài)切換的。并且會(huì)簡單的介紹下MyBatis整合Spring中的官方的相關(guān)代碼。Spring整合MyBatis切換SqlSessionFactory有兩種方法,第一、繼承SqlSessionDaoSupport,重寫獲取SqlSessionFactory的方法。第二、繼承SqlSessionTemplate重寫getSqlSessionFactory、getConfiguration和SqlSessionInterceptor這個(gè)攔截器。其中最為關(guān)鍵還是繼承SqlSessionTemplate并重寫里面的方法。而Spring整合MyBatis也有兩種方式,一種是配置MapperFactoryBean,另一種則是利用MapperScannerConfigurer進(jìn)行掃描接口或包完成對(duì)象的自動(dòng)創(chuàng)建。相對(duì)來說后者更方便些。MapperFactoryBean繼承了SqlSessionDaoSupport也就是動(dòng)態(tài)切換SqlSessionFactory的第一種方法,我們需要重寫和實(shí)現(xiàn)SqlSessionDaoSupport方法,或者是繼承MapperFactoryBean來重寫覆蓋相關(guān)方法。如果利用MapperScannerConfigurer的配置整合來切換SqlSessionFactory,那么我們就需要繼承SqlSessionTemplate,重寫上面提到的方法。在整合的配置中很多地方都是可以注入SqlSessionTemplate代替SqlSessionFactory的注入的。因?yàn)镾qlSessionTemplate的創(chuàng)建也是需要注入SqlSessionFactory的。二、實(shí)現(xiàn)代碼1、繼承SqlSessionTemplate重寫getSqlSessionFactory、getConfiguration和SqlSessionInterceptorpackagecom.hoo.framework.mybatis.support;importstaticjava.lang.reflect.Proxy.newProxylnstance;importstaticorg.apache.ibatis.reflection.ExceptionUtil.unwrapThrowable;importstaticorg.mybatis.spring.SqlSessionUtils.closeSqlSession;importstaticorg.mybatis.spring.SqlSessionUtils.getSqlSession;importstaticorg.mybatis.spring.SqlSessionUtils.isSqlSessionTransactional;importjava.lang.reflect.InvocationHandler;importjava.lang.reflect.Method;importjava.sql.Connection;importjava.util.List;importjava.util.Map;importorg.apache.ibatis.exceptions.PersistenceException;importorg.apache.ibatis.executor.BatchResult;importorg.apache.ibatis.session.Configuration;importorg.apache.ibatis.session.ExecutorType;importorg.apache.ibatis.session.ResultHandler;importorg.apache.ibatis.session.RowBounds;importorg.apache.ibatis.session.SqlSession;importorg.apache.ibatis.session.SqlSessionFactory;importorg.mybatis.spring.MyBatisExceptionTranslator;importorg.mybatis.spring.SqlSessionTemplate;importorg.springframework.dao.support.PersistenceExceptionTranslator;importorg.springframework.util.Assert;/**<b>function:</b>繼承SqlSessionTemplate重寫相關(guān)方法@authorhoojo@createDate2013-10-18下午03:07:46@fileCustomSqlSessionTemplate.java@packagecom.hoo.framework.mybatis.support@projectSHMB@blog/IBM_hoojo@emailhoojo_@126.com@version1.0*/publicclassCustomSqlSessionTemplateextendsSqlSessionTemplate(privatefinalSqlSessionFactorysqlSessionFactory;privatefinalExecutorTypeexecutorType;privatefinalSqlSessionsqlSessionProxy;privatefinalPersistenceExceptionTranslatorexceptionTranslator;privateMap<Object,SqlSessionFactory〉targetSqlSessionFactorys;privateSqlSessionFactorydefaultTargetSqlSessionFactory;publicvoidsetTargetSqlSessionFactorys(Map<Object,SqlSessionFactory〉targetSqlSessionFactorys)(this.targetSqlSessionFactorys=targetSqlSessionFactorys;}publicvoidsetDefaultTargetSqlSessionFactory(SqlSessionFactorydefaultTargetSqlSessionFactory)(this.defaultTargetSqlSessionFactory=defaultTargetSqlSessionFactory;}publicCustomSqlSessionTemplate(SqlSessionFactorysqlSessionFactory)(this(sqlSessionFactory,sqlSessionFactory.getConfiguration().getDefaultExecutorType());}publicCustomSqlSessionTemplate(SqlSessionFactorysqlSessionFactory,ExecutorTypeexecutorType)(this(sqlSessionFactory,executorType,newMyBatisExceptionTranslator(sqlSessionFactory.getConfiguration()
.getEnvironment().getDataSource(),true));}publicCustomSqlSessionTemplate(SqlSessionFactorysqlSessionFactory,ExecutorTypeexecutorType,PersistenceExceptionTranslatorexceptionTranslator)(super(sqlSessionFactory,executorType,exceptionTranslator);this.sqlSessionFactory=sqlSessionFactory;this.executorType=executorType;this.exceptionTranslator=exceptionTranslator;this.sqlSessionProxy=(SqlSession)newProxyInstance(SqlSessionFactoclass.getClassLoader(),newClass[](SqlSession.class},newSqlSessionInterceptor());this.defaultTargetSqlSessionFactory=sqlSessionFactory;}@OverridepublicSqlSessionFactorygetSqlSessionFactory()(SqlSessionFactorytargetSqlSessionFactory=targetSqlSessionFactorys.get(CustomerContextHolder.getContextType());if(targetSqlSessionFactory!=null)(returntargetSqlSessionFactory;}elseif(defaultTargetSqlSessionFactory!=null)(returndefaultTargetSqlSessionFactory;}else(Assert.notNull(targetSqlSessionFactorys"Property'targetSqlSessionFactorys'or'defaultTargetSqlSessionFactory'arerequired");Assert.notNull(defaultTargetSqlSessionFactory"Property'defaultTargetSqlSessionFactory'or'targetSqlSessionFactorys'arerequired");}returnthis.sqlSessionFactory;}@OverridepublicConfigurationgetConfiguration()(returnthis.getSqlSessionFactory().getConfiguration();}publicExecutorTypegetExecutorType()(returnthis.executorType;}publicPersistenceExceptionTranslatorgetPersistenceExceptionTranslator()(returnthis.exceptionTranslator;
}/**{@inheritDoc}*/public<T>TselectOne(Stringstatement){returnthis.sqlSessionProxy.<T>selectOne(statement);}/**{@inheritDoc}*/public<T>TselectOne(Stringstatement,Objectparameter){returnthis.sqlSessionProxy.<T>selectOne(statement,parameter);}/**{@inheritDoc}*/public<K,V>Map<K,V>selectMap(Stringstatement,StringmapKey){returnthis.sqlSessionProxy.<K,V>selectMap(statement,mapKey);}/**{@inheritDoc}*/public<K,V>Map<K,V>selectMap(Stringstatement,Objectparameter,StringmapKey){returnthis.sqlSessionProxy.<K,V>selectMap(statement,parameter,mapKey);}/**{@inheritDoc}*/public<K,V>Map<K,V>selectMap(Stringstatement,Objectparameter,StringmapKey,RowBoundsrowBounds){returnthis.sqlSessionProxy.<K,V>selectMap(statement,parameter,mapKey,rowBounds);}/**{@inheritDoc}*/public<E>List<E>selectList(Stringstatement){returnthis.sqlSessionProxy.<E>selectList(statement);}/***{@inheritDoc}
*/public<E>List<E>selectList(Stringstatement,Objectparameter)(returnthis.sqlSessionProxy.<E>selectList(statement,parameter);}/**{@inheritDoc}*/public<E>List<E>selectList(Stringstatement,Objectparameter,RowBoundsrowBounds){returnthis.sqlSessionProxy.<E>selectList(statement,parameter,rowBounds);}/**{@inheritDoc}*/publicvoidselect(Stringstatement,ResultHandlerhandler){this.sqlSessionProxy.select(statement,handler);}/**{@inheritDoc}*/publicvoidselect(Stringstatement,Objectparameter,ResultHandlerhandler){this.sqlSessionProxy.select(statement,parameter,handler);}/**{@inheritDoc}*/publicvoidselect(Stringstatement,Objectparameter,RowBoundsrowBounds,ResultHandlerhandler){this.sqlSessionProxy.select(statement,parameter,rowBounds,handler);}/**{@inheritDoc}*/publicintinsert(Stringstatement){returnthis.sqlSessionProxy.insert(statement);}/**{@inheritDoc}*/publicintinsert(Stringstatement,Objectparameter){
returnthis.sqlSessionProxy.insert(statement,parameter);/**{@inheritDoc}*/publicintupdate(Stringstatement){returnthis.sqlSessionProxy.update(statement);}/**{@inheritDoc}*/publicintupdate(Stringstatement,Objectparameter){returnthis.sqlSessionProxy.update(statement,parameter);}/**{@inheritDoc}*/publicintdelete(Stringstatement){returnthis.sqlSessionProxy.delete(statement);}/**{@inheritDoc}*/publicintdelete(Stringstatement,Objectparameter){returnthis.sqlSessionProxy.delete(statement,parameter);}/**{@inheritDoc}*/public<T>TgetMapper(Class<T>type){returngetConfiguration().getMapper(type,this);}/**{@inheritDoc}*/publicvoidcommit(){thrownewUnsupportedOperationException("ManualcommitisnotallowedoveraSpringmanagedSqlSession");}/**{@inheritDoc}*/publicvoidcommit(booleanforce){thrownewUnsupportedOperationException("Manualcommitisnot
allowedoveraSpringmanagedSqlSession");}/**{@inheritDoc}*/publicvoidrollback(){thrownewUnsupportedOperationException("ManualrollbackisnotallowedoveraSpringmanagedSqlSession");}/**{@inheritDoc}*/publicvoidrollback(booleanforce){thrownewUnsupportedOperationException("ManualrollbackisnotallowedoveraSpringmanagedSqlSession");}/**{@inheritDoc}*/publicvoidclose(){thrownewUnsupportedOperationException("ManualcloseisnotallowedoveraSpringmanagedSqlSession");}/**{@inheritDoc}*/publicvoidclearCache(){this.sqlSessionProxy.clearCache();}/**{@inheritDoc}*/publicConnectiongetConnection(){returnthis.sqlSessionProxy.getConnection();}/**{@inheritDoc}@since1.0.2*/publicList<BatchResult>flushStatements(){returnthis.sqlSessionProxy.flushStatements();}/***ProxyneededtorouteMyBatismethodcallstotheproperSqlSession
gotfromSpring'sTransactionManagerItalsounwrapsexceptionsthrownby{@codeMethod#invoke(Object,Object...)}topassa{@codePersistenceException}tothe{@codePersistenceExceptionTranslator}.*/privateclassSqlSessionInterceptorimplementsInvocationHandler{publicObjectinvoke(Objectproxy,Methodmethod,Object[]args)throwsThrowable{finalSqlSessionsqlSession=getSqlSession(CustomSqlSessionTemplate.this.getSqlSessionFactory(),CustomSqlSessionTemplathis.executorType,CustomSqlSessionTemplathis.exceptionTranslator);try{Objectresult=method.invoke(sqlSession,args);if(!isSqlSessionTransactional(sqlSession,CustomSqlSessionTemplate.this.getSqlSessionFactory())){//forcecommitevenonnon-dirtysessionsbecausesomedatabasesrequire//acommit/rollbackbeforecallingclose()sqlSmit(true);}returnresult;catch(Throwablet){Throwableunwrapped=unwrapThrowable(t);if(CustomSqlSessionTemplate.this.exceptionTranslator!=null&&unwrappedinstanceofPersistenceException){Throwabletranslated=CustomSqlSessionTemplate.this.exceptionTranslator.translateExceptionIfPossible((PersistenceException)unwrapped);if(translated!=null){unwrapped=translated;}}throwunwrapped;finally{closeSqlSession(sqlSession,CustomSqlSessionTemplate.this.getSqlSessionFactory());}}}}重寫后的getSqlSessionFactory方法會(huì)從我們配置的SqlSessionFactory集合
targetSqlSessionFactorys或默認(rèn)的defaultTargetSqlSessionFactory中獲取Session對(duì)象。而改寫的SqlSessionlnterceptor是這個(gè)MyBatis整合Spring的關(guān)鍵,所有的SqlSessionFactory對(duì)象的session都將在這里完成創(chuàng)建、提交、關(guān)閉等操作。所以我們改寫這里的代碼,在這里獲取getSqlSessionFactory的時(shí)候,從多個(gè)SqlSessionFactory中獲取我們設(shè)置的那個(gè)即可。上面添加了targetSqlSessionFactorys、defaultTargetSqlSessionFactory兩個(gè)屬性來配置多個(gè)SqlSessionFactory對(duì)象和默認(rèn)的SqlSessionFactory對(duì)象。CustomerContextHolder設(shè)置SqlSessionFactory的類型packagecom.hoo.framework.mybatis.support;/**<b>function:</b>多數(shù)據(jù)源@authorhoojo@createDate2013-9-27上午11:36:57@fileCustomerContextHolder.java@packagecom.hoo.framework.spring.support@projectSHMB@blog/IBM_hoojo@emailhoojo_@126.com@version1.0*/publicabstractclassCustomerContextHolder(publicfinalstaticStringSESSION_FACTORY_MYSQL="mysql";publicfinalstaticStringSESSION_FACTORY_ORACLE="oracle";privatestaticfinalThreadLocal<String>contextHolder=newThreadLocal<String>();publicstaticvoidsetContextType(StringcontextType)(contextHolder.set(contextType);}publicstaticStringgetContextType()(returncontextHolder.get();}publicstaticvoidclearContextType()(contextHolder.remove();}}2、配置相關(guān)的文件applicationContext-session-factory.xml<?xmlversion="1.0"encoding="UTF-8"?><beansxmlns="/schema/beans"
xmlns:aop="/schema/aop"xmlns:tx="/schema/tx"xmlns:xsi="/2001/XMLSchema-instance"xsi:schemaLocation="/schema/beanshttp://www.springframework.Org/schema/beans/spring-beans-3.2.xsd/schema/aophttp://www.springframework.Org/schema/aop/spring-aop-3.2.xsd/schema/txhttp://www.springframework.Org/schema/tx/spring-tx-3.2.xsd"><!--配置c3p0數(shù)據(jù)源--><beanid="dataSourceOracle"class="com.mchange.v2.c3p0.ComboPooledDataSource"destroy-method="close"><propertyname="driverClass"value="${datasource.driver}"/><propertyname="jdbcUrl"value="${datasource.url}"/><propertyname="user"value="${datasource.username}"/><propertyname="password"value="${datasource.password}"/><propertyname="acquireIncrement"value="${c3p0.acquireIncrement}"/><propertyname="initialPoolSize"value="${c3p0.initialPoolSize}"/><propertyname="minPoolSize"value="${c3p0.minPoolSize}"/><propertyname="maxPoolSize"value="${c3p0.maxPoolSize}"/><propertyname="maxIdleTime"value="${c3p0.maxIdleTime}"/><propertyname="idleConnectionTestPeriod"value="${c3p0.idleConnectionTestPeriod}"/><propertyname="maxStatements"value="${c3p0.maxStatements}"/><propertyname="numHelperThreads"value="${c3p0.numHelperThreads}"/><propertyname="preferredTestQuery"value="${c3p0.preferredTestQuery}"/><propertyname="testConnectionOnCheckout"value="${c3p0.testConnectionOnCheckout}"/></bean><beanid="dataSourceMySQL"class="com.mchange.v2.c3p0.ComboPooledDataSource"destroy-method="close"><propertyname="driverClass"value="com.mysql.jdbc.Driver"/><propertyname="jdbcUrl"value="jdbc:mysql://78:3306/world?useUnicode=true&characterEncoding=UTF-8&zeroDateTimeBehavior=convertToNull"/>
<propertyname="user"value="root"/><propertyname="password"value="jp2011"/><propertyname="acquireIncrement"value="${c3p0.acquireIncrement}"/><propertyname="initialPoolSize"value="${c3p0.initialPoolSize}"/><propertyname="minPoolSize"value="${c3p0.minPoolSize}"/><propertyname="maxPoolSize"value="${c3p0.maxPoolSize}"/><propertyname="maxIdleTime"value="${c3p0.maxIdleTime}"/><propertyname="idleConnectionTestPeriod"value="${c3p0.idleConnectionTestPeriod}"/><propertyname="maxStatements"value="${c3p0.maxStatements}"/><propertyname="numHelperThreads"value="${c3p0.numHelperThreads}"/><propertyname="preferredTestQuery"value="${c3p0.preferredTestQuery}"/><propertyname="testConnectionOnCheckout"value="${c3p0.testConnectionOnCheckout}"/></bean><!--配置SqlSessionFactoryBean--><beanid="oracleSqlSessionFactory"class="org.mybatis.spring.SqlSessionFactoryBean"><propertyname="dataSource"ref="dataSourceOracle"/><propertyname="configLocation"value="classpath:mybatis.xml"/><!--mapper和resultmap配置路徑--><propertyname="mapperLocations"><list><!--表示在com.hoo目錄下的任意包下的resultmap包目錄中,以-resultmap.xml或-mapper.xml結(jié)尾所有文件--><value>classpath:com/hoo/framework/mybatis/mybatis-common.xml</value><value>classpath:com/hoo/**/resultmap/*-resultmap.xml</value><value>classpath:com/hoo/**/mapper/*-mapper.xml</value><value>classpath:com/hoo/**/mapper/**/*-mapper.xml</value></list></property></bean><!--配置SqlSessionFactoryBean--><beanid="mysqlSqlSessionFactory"
class="org.mybatis.spring.SqlSessionFactoryBean"><propertyname="dataSource"ref="dataSourceMySQL"/><propertyname="configLocation"value="classpath:mybatis.xml"/><!--mapper和resultmap配置路徑--><propertyname="mapperLocations"><list><!--表示在com.hoo目錄下的任意包下的resultmap包目錄中,以-resultmap.xml或-mapper.xml結(jié)尾所有文件(oracle和mysql掃描的配置和路徑不一樣,如果是公共的都掃描這里要區(qū)分下,不然就報(bào)錯(cuò)找不到對(duì)應(yīng)的表、視圖)--><value>classpath:com/hoo/framework/mybatis/mybatis-common.xml</value><value>classpath:com/hoo/**/resultmap/*-mysql-resultmap.xml</value><value>classpath:com/hoo/**/mapper/*-mysql-mapper.xml</value><value>classpath:com/hoo/**/mapper/**/*-mysql-mapper.xml</value><value>classpath:com/hoo/**/mapper/**/multiple-datasource-mapper.xml</value〉</list></property></bean><!--配置自定義的SqlSessionTemplate模板,注入相關(guān)配置--><beanid="sqlSessionTemplate"class="com.hoo.framework.mybatis.support.CustomSqlSessionTemplate"><constructor-argref="oracleSqlSessionFactory"/><propertyname="targetSqlSessionFactorys"><map><entryvalue-ref="oracleSqlSessionFactory"key="oracle"/><entryvalue-ref="mysqlSqlSessionFactory"key="mysql"/></map></property></bean><!--通過掃描的模式,掃描目錄在com/hoo/任意目錄下的mapper目錄下,所有的mapper都需要繼承SqlMapper接口的接口--><beanclass="org.mybatis.spring.mapper.MapperScannerConfigurer"><propertyname="basePackage"value="com.hoo.**.mapper"/><!--注意注入sqlSessionTemplate--><propertyname="sqlSessionTemplateBeanName"value="sqlSessionTemplate"/><propertyname="markerInterface"
value="com.hoo.framework.mybatis.SqlMapper"/></bean></beans>上面的配置關(guān)鍵是在MapperScannerConfigurer中注入sqlSessionTemplate,這個(gè)要注意。當(dāng)我們配置了多個(gè)SqlSessionFactoryBean的時(shí)候,就需要為MapperScannerConfigurer指定一個(gè)sqlSessionFactoryBeanName或是sqlSessionTemplateBeanName。一般情況下注入了sqlSessionTemplateBeanName對(duì)象,那sqlSessionFactory也就有值了。如果單獨(dú)的注入了sqlSessionFactory那么程序會(huì)創(chuàng)建一個(gè)sqlSessionTemplate對(duì)象。我們可以看看代碼SqlSessionFactoryDaoSupport對(duì)象的代碼。如果你不喜歡使用掃描的方式,也可以注入sqlSessionTemplate或繼承sqlSessionTemplate完成數(shù)據(jù)庫操作。publicabstractclassSqlSessionDaoSupportextendsDaoSupport(privateSqlSessionsqlSession;privatebooleanexternalSqlSession;publicvoidsetSqlSessionFactory(SqlSessionFactorysqlSessionFactory)(if(!this.externalSqlSession)(this.sqlSession=newSqlSessionTemplate(sqlSessionFactory);}}publicvoidsetSqlSessionTemplate(SqlSessionTemplatesqlSessionTemplate)(this.sqlSession=sqlSessionTemplate;this.externalSqlSession=true;}這段代碼很明顯,如果注入了sqlSessionTemplate上面的注入也就不會(huì)執(zhí)行了。如果沒有注入sqlSessionTemplate,那么會(huì)自動(dòng)new一個(gè)sqlSessionTemplate對(duì)象。3、編寫相關(guān)測試接口和實(shí)現(xiàn)的mapper.xmlpackagecom.hoo.server.datasource.mapper;importjava.util.List;importjava.util.Map;importcom.hoo.framework.mybatis.SqlMapper;/**<b>function:</b>MyBatis多數(shù)據(jù)源測試查詢接口@authorhoojo@createDate2013-10-10下午04:18:08@fileMultipleDataSourceMapper.java@packagecom.hoo.server.datasource.mapper@projectSHMB@blog/IBM_hoojo@emailhoojo_@126.com*@version1.0*/publicinterfaceMultipleDataSourceMapperextendsSqlMapper(publicList<Map<String,Object>>execute4MySQL()throwsException;publicList<Map<String,Object>>execute4Oracle()throwsException;}multiple-datasource-mapper.xml<?xmlversion="1.0"encoding="UTF-8"?><!DOCTYPEmapperPUBLIC"-////DTDMapper3.0//EN""/dtd/mybatis-3-mapper.dtd"><mappernamespace="com.hoo.server.datasource.mapper.MultipleDataSourceMapper"><selectid="execute4Oracle"resultType="map"><![CDATA[SELECT*FROMdeviceInfo_tabtwhererowni<10]></select><selectid="execute4MySQL"resultType="map"><![CDATA[SELECT*FROMcitylimit2]></select></mapper>上面分別查詢oracle和mysql兩個(gè)數(shù)據(jù)庫中的table4、測試代碼@Autowired@Qualifier("multipleDataSourceMapper")privateMultipleDataSourceMappermapper;@TestpublicvoidtestMapper()(CustomerContextHolder.setContextType(CustomerContextHolder.SESSION_FACTORY_MYSQL);try(trace(mapper.execute4MySQL());}catch(Exceptionel)(e1.printStackTrace();}CustomerContextHolder.setContextType(CustomerContextHolder.SESSION_FACTORY_ORACLE);try(trace(mapper.execute4Oracle());}catch(Exceptione)(e.printStackTrace();}}運(yùn)行后發(fā)現(xiàn)能夠順利查詢出數(shù)據(jù)。如果你是重寫SqlSessionDaoSupport,那么方法如下packagecom.hoo.framework.mybatis.support;importjava.util.Map;importorg.apache.ibatis.session.SqlSession;importorg.apache.ibatis.session.SqlSessionFactory;importorg.mybatis.spring.SqlSessionUtils;importorg.mybatis.spring.support.SqlSessionDaoSupport;importorg.springframework.beans.BeansException;importorg.springframework.context.ApplicationContext;importorg.springframework.context.ApplicationContextAware;/**<b>function:</b>MyBatis動(dòng)態(tài)SqlSessionFactory@authorhoojo@createDate2013-10-14下午02:32:19@fileDynamicSqlSessionDaoSupport.java@packagecom.hoo.framework.mybatis.support@projectSHMB@blog/IBM_hoojo@emailhoojo_@126.com@version1.0*/publicclassDynamicSqlSessionDaoSupportextendsSqlSessionDaoSupportimplementsApplicationContextAware(privateApplicationContextapplicationContext;privateMap<Object,SqlSessionFactory〉targetSqlSessionFactorys;privateSqlSessionFactorydefaultTargetSqlSessionFactory;privateSqlSessionsqlSession;@OverridepublicfinalSqlSessiongetSqlSession()(SqlSessionFactorytargetSqlSessionFactory=targetSqlSessionFactorys.get(CustomerContextHolder.getContextType());if(targetSqlSessionFactory!=null)(setSqlSessionFactory(targetSqlSessionFactory);}elseif(defaultTargetSqlSessionFactory!=null)(setSqlSessionFactory(defaultTargetSqlSessionFactory);targetSqlSessionFactory=defaultTargetSqlSessionFactory;}else(targetSqlSessionFactory=(SqlSessionFactory)applicationContext.getBean(CustomerContextHolder.getContextType());setSqlSessionFactory(targetSqlSessionFactory);}this.sqlSession=SqlSessionUtils.getSqlSession(targetSqlSessionFactory);returnthis.sqlSession;}@OverrideprotectedvoidcheckDaoConfig()(//Assert.notNull(getSqlSession(),"Property'sqlSessionFactoryor'sqlSessionTemplate'arerequired");}publicvoidsetTargetSqlSessionFactorys(Map<Object,SqlSessionFactory>targetSqlSessionFactorys)(this.targetSqlSessionFactorys=targetSqlSessionFactorys;}publicvoidsetDefaultTargetSqlSessionFactory(SqlSessionFactorydefaultTargetSqlSessionFactory)(this.defaultTargetSqlSessionFactory=defaultTargetSqlSessionFactory;}@OverridepublicvoidsetApplicationContext(ApplicationContextapplicationContext)throwsBeansException(this.applicationContext=applicationContext;}}主要重寫getSqlSession方法,上面獲取SqlSessionFactory的方法。重寫好了后就可以配置這個(gè)對(duì)象,配置代碼如下//每^■個(gè)DAO由繼承SqlSessionDaoSupport全部改為DynamicSqlSessionDaoSupportpublicclassUserMapperDaoImplextendsDynamicSqlSessionDaoSupportimplementsUserDao(publicintaddUser(Useruser)(returnthis.getSqlSession().insert("com.hoo.user.dao.UserDao.addUser",user);}}在上面的配置文件中加入配置<beanid="baseDao"class="com.hoo.framework.mybatis.support.DynamicSqlSessionDaoSupport"abstract="true"lazy-init="true"><propertyname"targetSqlSessionFactorys"><map><entryvalue-re"oracleSqlSessionFactory"key="oracle"/><entryvalue-re"mysqlSqlSessionFactory"key="mysql"/></map></property><propertyname"defaultTargetSqlSessionFactory"ref="oracleSqlSessionFactory"/></bean><beanid="userMapperDao"class="com.hoo.user.dao.impl.UserMapperDaoImpl"parent="baseDao"/>就這樣也可以利用DynamicSqlSessionDaoSupport來完成動(dòng)態(tài)切換sqlSessionFactory對(duì)象,只需用在注入userMapperDao調(diào)用方法的時(shí)候設(shè)置下CustomerContextHolder的contextType即可。三、總結(jié)為了實(shí)現(xiàn)這個(gè)功能看了mybatis-spring-1.2.0.jar這個(gè)包的部分源代碼,代碼內(nèi)容不是很多。所以看了下主要的代碼,下面做些簡單的介紹。MapperScannerConfigurer這個(gè)類就是我們要掃描的Mapper接口的類,也就是basePackage中繼承markerInterface配置的接口。可以看看ClassPathBeanDefinitionScanner、ClassPathMapperScanner中的doScan這個(gè)方法。它會(huì)掃描basePackage這個(gè)包下所有接口,在ClassPathScanningCandidateComponentProvider中有這個(gè)方法findCandidateComponents,它會(huì)找到所有的BeanDefinition。最重要的一點(diǎn)是ClassPathMapperScanner中的doScan這個(gè)方法它會(huì)給這些接口創(chuàng)建一個(gè)MapperFactoryBean。并且會(huì)檢查sqlSessionFactory和sqlSessionTemplate對(duì)象的注入情況。for(BeanDefimrionHolderhold&r:keanDefrnitions)<GencxicBea^&sCinita.o^definition=£GsnezicSefti:Definitior)bolder^cetBeanDefinition(};1£(logger,isDebugEnabled()){loggst.deb-g{stingMapp-rFactor^SfianwxtjJiname1"+hol^erx□C3*afiiJariLej)+11'dnd+def-getBea^ClasaNamef)+ri1rr.app&rInterface;>//therr.apperinterfaceisrheoriginalcla3^o£thebean//tuttheactual01^53OEtlit日專firnMapp^rFsetcsand*flu土t:lan-gwcProp整瞿匚戲4【耳口旦_[)-食如fkmappEJ;工dmf.defi<imi,gecBeanClAS^NaiDje()};deflniticn.^etSeanClass(Mappex?muSr廨Wi:;;「:]definition,getPropertyValues[}-add{haddToConfic-trthis.addloConfig):booleantxplicitractoryUsed,false;if(StxingUcils.^dsText(this.2ql5es£ionFactoxy3earLNair.e))fg'etFTape^tyVAiues().flddf^sqiSe^iqrFacto^y^,newRuntitre5ea^R*f?^ence(this.sexplicitraccoryUsed=trae;}elseif4thi9.sqlSessicnFactcry!=nail){cfstinicion.gt^txape^cyValueaU.add(^^qlSe^fllonFac^ory1*,thia.sqlSes
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 物聯(lián)網(wǎng)產(chǎn)業(yè)園智能化基礎(chǔ)設(shè)施建設(shè)
- 小學(xué)語文跨學(xué)科教學(xué)策略及實(shí)施路徑
- 讀紅色革命故事有感10篇
- 2025年產(chǎn)權(quán)有證房屋買賣合同協(xié)議書
- 3月15日國際消費(fèi)者權(quán)益日模板2
- 2025金融科技租賃公司POS設(shè)備使用合同
- 2025水利工程建筑施工合同
- 2025三人簡易合伙合同協(xié)議書范本
- 2024年平?jīng)鋈A亭市特崗教師招聘考試真題
- 2024年甘肅特崗真題
- 電氣控制柜面試題及答案
- 藥房藥品追溯管理制度
- 2025年初中學(xué)業(yè)水平考試地理模擬卷:地震、臺(tái)風(fēng)等自然災(zāi)害防治措施試題及答案
- 2025年中國柔性透明導(dǎo)電膜項(xiàng)目投資計(jì)劃書
- 中醫(yī)執(zhí)業(yè)醫(yī)師資格考試《第一單元》真題及答案(2025年新版)
- 重癥醫(yī)學(xué)科醫(yī)院感染控制原則專家共識(shí)(2024)解讀
- 福建三明經(jīng)開區(qū)控股集團(tuán)有限公司子公司招聘筆試題庫2025
- 海洋垃圾資源化利用與環(huán)境影響評(píng)估-洞察闡釋
- 分公司收回協(xié)議書
- 虛擬現(xiàn)實(shí)技術(shù)的應(yīng)用場景的試題及答案
- 企業(yè)內(nèi)部審計(jì)與風(fēng)險(xiǎn)管理的互動(dòng)試題及答案
評(píng)論
0/150
提交評(píng)論