final SqlSession sqlSession = getSqlSession( SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
public class EjsSqlSessionTemplate extends SqlSessionTemplate {
private Map<String, SqlSessionFactory> targetSqlSessionFactory = new HashMap<String, SqlSessionFactory>();
public void setTargetSqlSessionFactory(Map<String, SqlSessionFactory> targetSqlSessionFactory) {
this.targetSqlSessionFactory = targetSqlSessionFactory;
}
<bean id="sqlSessionTemplate" class="com.ejushang.spider.datasource.EjsSqlSessionTemplate">
<constructor-arg ref="sqlSessionFactory" />
<property name="targetSqlSessionFactory">
<map>
<entry value-ref="sqlSessionFactory" key="spider"/>
<entry value-ref="sqlSessionFactoryTb" key="sysinfo"/>
</map>
</property>
</bean>
<bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.foo.bar.**.mapper*" />
<property name="sqlSessionTemplateBeanName" value="sqlSessionTemplate"/>
</bean>
/**
* 重写得到SqlSessionFactory的方法
* @return
*/
@Override
public SqlSessionFactory getSqlSessionFactory() {
SqlSessionFactory targetSqlSessionFactory = this.targetSqlSessionFactory.get(SqlSessionContextHolder.getDataSourceKey());
if (targetSqlSessionFactory != null) {
return targetSqlSessionFactory;
} else if ( this.getSqlSessionFactory() != null) {
return this.getSqlSessionFactory();
}
throw new IllegalArgumentException("sqlSessionFactory or targetSqlSessionFactory must set one at least");
}
public class SqlSessionContextHolder {
private static final ThreadLocal<String> contextHolder = new ThreadLocal<String>();
private static Logger logger = LoggerFactory.getLogger(SqlSessionContextHolder.class);
public static void setSessionFactoryKey(String dataSourceKey) {
contextHolder.set(dataSourceKey);
}
public static String getDataSourceKey() {
String key = contextHolder.get();
logger.info("当前线程Thread:"+Thread.currentThread().getName()+" 当前的数据源 key is "+ key);
return key;
}
}
final SqlSession sqlSession = getSqlSession( EjsSqlSessionTemplate.this.getSqlSessionFactory(), EjsSqlSessionTemplate.this.getExecutorType(), EjsSqlSessionTemplate.this.getPersistenceExceptionTranslator());
public SqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
PersistenceExceptionTranslator exceptionTranslator) {
notNull(sqlSessionFactory, "Property 'sqlSessionFactory' is required");
notNull(executorType, "Property 'executorType' is required");
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
this.exceptionTranslator = exceptionTranslator;
this.sqlSessionProxy = (SqlSession) newProxyInstance(
SqlSessionFactory.class.getClassLoader(),
new Class[] { SqlSession.class },
new SqlSessionInterceptor());
}
public EjsSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType, PersistenceExceptionTranslator exceptionTranslator) {
super(getSqlSessionFactory(), executorType, exceptionTranslator);
}
public class EjsSqlSessionTemplate extends SqlSessionTemplate {
private final SqlSessionFactory sqlSessionFactory;
private final ExecutorType executorType;
private final SqlSession sqlSessionProxy;
private final PersistenceExceptionTranslator exceptionTranslator;
private Map<Object, SqlSessionFactory> targetSqlSessionFactory;
public void setTargetSqlSessionFactory(Map<Object, SqlSessionFactory> targetSqlSessionFactory) {
this.targetSqlSessionFactory = targetSqlSessionFactory;
}
public EjsSqlSessionTemplate(SqlSessionFactory sqlSessionFactory) {
this(sqlSessionFactory, sqlSessionFactory.getConfiguration().getDefaultExecutorType());
}
public EjsSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType) {
this(sqlSessionFactory, executorType, new MyBatisExceptionTranslator(sqlSessionFactory.getConfiguration()
.getEnvironment().getDataSource(), true));
}
public EjsSqlSessionTemplate(SqlSessionFactory sqlSessionFactory, ExecutorType executorType,
PersistenceExceptionTranslator exceptionTranslator) {
super(sqlSessionFactory, executorType, exceptionTranslator);
this.sqlSessionFactory = sqlSessionFactory;
this.executorType = executorType;
this.exceptionTranslator = exceptionTranslator;
this.sqlSessionProxy = (SqlSession) newProxyInstance(
SqlSessionFactory.class.getClassLoader(),
new Class[] { SqlSession.class },
new SqlSessionInterceptor());
}
@Override
public SqlSessionFactory getSqlSessionFactory() {
SqlSessionFactory targetSqlSessionFactory = this.targetSqlSessionFactory.get(SqlSessionContextHolder.getDataSourceKey());
if (targetSqlSessionFactory != null) {
return targetSqlSessionFactory;
} else if ( this.sqlSessionFactory != null) {
return this.sqlSessionFactory;
}
throw new IllegalArgumentException("sqlSessionFactory or targetSqlSessionFactory must set one at least");
}
@Override
public Configuration getConfiguration() {
return this.getSqlSessionFactory().getConfiguration();
}
public ExecutorType getExecutorType() {
return this.executorType;
}
public PersistenceExceptionTranslator getPersistenceExceptionTranslator() {
return this.exceptionTranslator;
}
/**
* {@inheritDoc}
*/
public <T> T selectOne(String statement) {
return this.sqlSessionProxy.<T> selectOne(statement);
}
/**
* {@inheritDoc}
*/
public <T> T selectOne(String statement, Object parameter) {
return this.sqlSessionProxy.<T> selectOne(statement, parameter);
}
/**
* {@inheritDoc}
*/
public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
return this.sqlSessionProxy.<K, V> selectMap(statement, mapKey);
}
/**
* {@inheritDoc}
*/
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
return this.sqlSessionProxy.<K, V> selectMap(statement, parameter, mapKey);
}
/**
* {@inheritDoc}
*/
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
return this.sqlSessionProxy.<K, V> selectMap(statement, parameter, mapKey, rowBounds);
}
/**
* {@inheritDoc}
*/
public <E> List<E> selectList(String statement) {
return this.sqlSessionProxy.<E> selectList(statement);
}
/**
* {@inheritDoc}
*/
public <E> List<E> selectList(String statement, Object parameter) {
return this.sqlSessionProxy.<E> selectList(statement, parameter);
}
/**
* {@inheritDoc}
*/
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
return this.sqlSessionProxy.<E> selectList(statement, parameter, rowBounds);
}
/**
* {@inheritDoc}
*/
public void select(String statement, ResultHandler handler) {
this.sqlSessionProxy.select(statement, handler);
}
/**
* {@inheritDoc}
*/
public void select(String statement, Object parameter, ResultHandler handler) {
this.sqlSessionProxy.select(statement, parameter, handler);
}
/**
* {@inheritDoc}
*/
public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
this.sqlSessionProxy.select(statement, parameter, rowBounds, handler);
}
/**
* {@inheritDoc}
*/
public int insert(String statement) {
return this.sqlSessionProxy.insert(statement);
}
/**
* {@inheritDoc}
*/
public int insert(String statement, Object parameter) {
return this.sqlSessionProxy.insert(statement, parameter);
}
/**
* {@inheritDoc}
*/
public int update(String statement) {
return this.sqlSessionProxy.update(statement);
}
/**
* {@inheritDoc}
*/
public int update(String statement, Object parameter) {
return this.sqlSessionProxy.update(statement, parameter);
}
/**
* {@inheritDoc}
*/
public int delete(String statement) {
return this.sqlSessionProxy.delete(statement);
}
/**
* {@inheritDoc}
*/
public int delete(String statement, Object parameter) {
return this.sqlSessionProxy.delete(statement, parameter);
}
/**
* {@inheritDoc}
*/
public <T> T getMapper(Class<T> type) {
return getConfiguration().getMapper(type, this);
}
/**
* {@inheritDoc}
*/
public void commit() {
throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void commit(boolean force) {
throw new UnsupportedOperationException("Manual commit is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void rollback() {
throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void rollback(boolean force) {
throw new UnsupportedOperationException("Manual rollback is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void close() {
throw new UnsupportedOperationException("Manual close is not allowed over a Spring managed SqlSession");
}
/**
* {@inheritDoc}
*/
public void clearCache() {
this.sqlSessionProxy.clearCache();
}
/**
* {@inheritDoc}
*/
public Connection getConnection() {
return this.sqlSessionProxy.getConnection();
}
/**
* {@inheritDoc}
* @since 1.0.2
*/
public List<BatchResult> flushStatements() {
return this.sqlSessionProxy.flushStatements();
}
/**
* Proxy needed to route MyBatis method calls to the proper SqlSession got from Spring's Transaction Manager It also
* unwraps exceptions thrown by {@code Method#invoke(Object, Object...)} to pass a {@code PersistenceException} to
* the {@code PersistenceExceptionTranslator}.
*/
private class SqlSessionInterceptor implements InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
final SqlSession sqlSession = getSqlSession(
EjsSqlSessionTemplate.this.getSqlSessionFactory(),
EjsSqlSessionTemplate.this.executorType,
EjsSqlSessionTemplate.this.exceptionTranslator);
try {
Object result = method.invoke(sqlSession, args);
if (!isSqlSessionTransactional(sqlSession, EjsSqlSessionTemplate.this.getSqlSessionFactory())) {
// force commit even on non-dirty sessions because some databases require
// a commit/rollback before calling close()
sqlSession.commit(true);
}
return result;
} catch (Throwable t) {
Throwable unwrapped = unwrapThrowable(t);
if (EjsSqlSessionTemplate.this.exceptionTranslator != null && unwrapped instanceof PersistenceException) {
Throwable translated = EjsSqlSessionTemplate.this.exceptionTranslator
.translateExceptionIfPossible((PersistenceException) unwrapped);
if (translated != null) {
unwrapped = translated;
}
}
throw unwrapped;
} finally {
closeSqlSession(sqlSession, EjsSqlSessionTemplate.this.getSqlSessionFactory());
}
}
}
}
/**
* 注解式数据源,用来进行数据源切换
* User:Amos.zhou
* Date: 14-2-27
* Time: 下午2:34
*/
@Target({ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface ChooseDataSource {
String value() default "";
}
/**
* <li>类描述:完成数据源的切换,抽类切面,具体项目继承一下,不需要重写即可使用</li>
*
* @author: amos.zhou
* 2013-8-1 上午11:51:40
* @since v1.0
*/
@Aspect
public abstract class ChooseDataSourceAspect {
protected static final ThreadLocal<String> preDatasourceHolder = new ThreadLocal<String>();
@Pointcut("execution(public * *.*(..))")
public void allMethodPoint() {
}
@Pointcut("@within(com.ejushang.spider.annotation.ChooseDataSource) && allMethodPoint()")
public void allServiceMethod() {
}
/**
* 对所有注解有ChooseDataSource的类进行拦截
*/
@Pointcut("cflow(allServiceMethod()) && allServiceMethod()")
public void changeDatasourcePoint() {
}
/**
* 根据@ChooseDataSource的属性值设置不同的dataSourceKey,以供DynamicDataSource
*/
@Before("changeDatasourcePoint()")
public void changeDataSourceBeforeMethodExecution(JoinPoint jp) {
//拿到anotation中配置的数据源
String resultDS = determineDatasource(jp);
//没有配置实用默认数据源
if (resultDS == null) {
SqlSessionContextHolder.setSessionFactoryKey(null);
return;
}
preDatasourceHolder.set(SqlSessionContextHolder.getDataSourceKey());
//将数据源设置到数据源持有者
SqlSessionContextHolder.setSessionFactoryKey(resultDS);
}
/**
* <p>创建时间: 2013-8-20 上午9:48:44</p>
* 如果需要修改获取数据源的逻辑,请重写此方法
*
* @param jp
* @return
*/
@SuppressWarnings("rawtypes")
protected String determineDatasource(JoinPoint jp) {
String methodName = jp.getSignature().getName();
Class targetClass = jp.getSignature().getDeclaringType();
String dataSourceForTargetClass = resolveDataSourceFromClass(targetClass);
String dataSourceForTargetMethod = resolveDataSourceFromMethod(
targetClass, methodName);
String resultDS = determinateDataSource(dataSourceForTargetClass,
dataSourceForTargetMethod);
return resultDS;
}
/**
* 方法执行完毕以后,数据源切换回之前的数据源。
* 比如foo()方法里面调用bar(),但是bar()另外一个数据源,
* bar()执行时,切换到自己数据源,执行完以后,要切换到foo()所需要的数据源,以供
* foo()继续执行。
* <p>创建时间: 2013-8-16 下午4:27:06</p>
*/
@After("changeDatasourcePoint()")
public void restoreDataSourceAfterMethodExecution() {
SqlSessionContextHolder.setSessionFactoryKey(preDatasourceHolder.get());
preDatasourceHolder.remove();
}
/**
* <li>创建时间: 2013-6-17 下午5:34:13</li> <li>创建人:amos.zhou</li> <li>方法描述 :</li>
*
* @param targetClass
* @param methodName
* @return
*/
@SuppressWarnings("rawtypes")
private String resolveDataSourceFromMethod(Class targetClass,
String methodName) {
Method m = ReflectUtil.findUniqueMethod(targetClass, methodName);
if (m != null) {
ChooseDataSource choDs = m.getAnnotation(ChooseDataSource.class);
return resolveDataSourcename(choDs);
}
return null;
}
/**
* <li>创建时间: 2013-6-17 下午5:06:02</li>
* <li>创建人:amos.zhou</li>
* <li>方法描述 : 确定
* 最终数据源,如果方法上设置有数据源,则以方法上的为准,如果方法上没有设置,则以类上的为准,如果类上没有设置,则使用默认数据源</li>
*
* @param classDS
* @param methodDS
* @return
*/
private String determinateDataSource(String classDS, String methodDS) {
// if (null == classDS && null == methodDS) {
// return null;
// }
// 两者必有一个不为null,如果两者都为Null,也会返回Null
return methodDS == null ? classDS : methodDS;
}
/**
* <li>创建时间: 2013-6-17 下午4:33:03</li> <li>创建人:amos.zhou</li> <li>方法描述 : 类级别的 @ChooseDataSource
* 的解析</li>
*
* @param targetClass
* @return
*/
@SuppressWarnings({"unchecked", "rawtypes"})
private String resolveDataSourceFromClass(Class targetClass) {
ChooseDataSource classAnnotation = (ChooseDataSource) targetClass
.getAnnotation(ChooseDataSource.class);
// 直接为整个类进行设置
return null != classAnnotation ? resolveDataSourcename(classAnnotation)
: null;
}
/**
* <li>创建时间: 2013-6-17 下午4:31:42</li> <li>创建人:amos.zhou</li> <li>方法描述 :
* 组装DataSource的名字</li>
*
* @param ds
* @return
*/
private String resolveDataSourcename(ChooseDataSource ds) {
return ds == null ? null : ds.value();
}
}
@Aspect
public class OrderFetchAspect extends ChooseDataSourceAspect {
}
<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> </bean> <bean id="dataSourceTb" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close"> </bean> <!-- 事务管理 --> <bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> <property name="dataSource" ref="dataSource" /> </bean> <!-- 注解控制事务 --> <tx:annotation-driven transaction-manager="transactionManager"/> <bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSource"/> <property name="configLocation" value="classpath:mybatis.xml" /> <property name="mapperLocations" value="classpath*:com/foo/bar/**/config/*mapper.xml" /> </bean> <bean id="sqlSessionFactoryTb" class="org.mybatis.spring.SqlSessionFactoryBean"> <property name="dataSource" ref="dataSourceTb"/> <property name="configLocation" value="classpath:mybatis.xml" /> <property name="mapperLocations" value="classpath*:<span style="font-family: Arial, Helvetica, sans-serif;">com/foo/bar</span><span style="font-family: Arial, Helvetica, sans-serif;">/**/configtb/*mapper.xml" /></span> </bean> <bean id="sqlSessionTemplate" class="com.foo.bar.template.EjsSqlSessionTemplate"> <constructor-arg ref="sqlSessionFactory" /> <property name="targetSqlSessionFactory"> <map> <entry value-ref="sqlSessionFactory" key="spider"/> <entry value-ref="sqlSessionFactoryTb" key="sysinfo"/> </map> </property> </bean> <bean id="mapperScannerConfigurer" class="org.mybatis.spring.mapper.MapperScannerConfigurer"> <property name="basePackage" value="com.foo.bar.**.mapper*" /> <property name="sqlSessionTemplateBeanName" value="sqlSessionTemplate"/> </bean>
@ChooseDataSource("spider")
public class ShopServiceTest extends ErpTest {
private static final Logger log = LoggerFactory.getLogger(ShopServiceTest.class);
@Autowired
private IShopService shopService;
@Autowired
private IJdpTbTradeService jdpTbTradeService;
@Test
@Rollback(false)
public void testFindAllShop(){
List<Shop> shopList1 = shopService.findAllShop();
for(Shop shop : shopList1){
System.out.println(shop);
}
fromTestDB();
}
@ChooseDataSource("sysinfo")
private void fromTestDB(){
List<Shop> shopList = jdpTbTradeService.findAllShop();
for(Shop shop : shopList){
System.out.println(shop);
}
}
}
final SqlSession sqlSession = getSqlSession( SqlSessionTemplate.this.sqlSessionFactory, SqlSessionTemplate.this.executorType, SqlSessionTemplate.this.exceptionTranslator);
final SqlSession sqlSession = getSqlSession(
EjsSqlSessionTemplate.this.getSqlSessionFactory(),
EjsSqlSessionTemplate.this.executorType,
EjsSqlSessionTemplate.this.exceptionTranslator);
private Map<Object, SqlSessionFactory> targetSqlSessionFactory;
public void setTargetSqlSessionFactory(Map<Object, SqlSessionFactory> targetSqlSessionFactory) {
this.targetSqlSessionFactory = targetSqlSessionFactory;
}
机械节能产品生产企业官网模板...
大气智能家居家具装修装饰类企业通用网站模板...
礼品公司网站模板
宽屏简约大气婚纱摄影影楼模板...
蓝白WAP手机综合医院类整站源码(独立后台)...苏ICP备2024110244号-2 苏公网安备32050702011978号 增值电信业务经营许可证编号:苏B2-20251499 | Copyright 2018 - 2025 源码网商城 (www.ymwmall.com) 版权所有