Spring+Struts+ibatis下配置数据读写分离及事务(一)

本文介绍了使用SSI框架进行数据读写分离的测试过程,包括配置JDBC属性、编写数据源处理类、AOP切面类及动态数据源切换类。通过测试实现不同操作时数据源的自动切换,优化了数据管理和性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   最近使用ssi框架,参考了一位网友写的ssh数据读写分离及相关资源做了一个ssi的数据读写分离测试,一是给刚刚接触SSI的朋友一个参考,其次也给自己存储下code笔记,有不到位的地方请大家多多指教。

   首先介绍我使用相关框架的版本,Spring2.5+struts2.1.6+ibatis2.3,数据库使用的是mysql,使用的jar包请在附件中下载.

  1.配置jdbc.properties,由于只是测试,所以读写分离使用的还是一个数据库,同一个用户名和密码.这个可以根据需求修改

#MySQL master 主要数据源 负责数据Update
master.jdbc.driverClassName=com.mysql.jdbc.Driver
master.jdbc.url=jdbc:mysql://localhost:3306/myweb?useUnicode=true&characterEncoding=utf-8
master.jdbc.username=root
master.jdbc.password=root

#MySQL slave 从数据源 负责数据Query
slave.jdbc.driverClassName=com.mysql.jdbc.Driver
slave.jdbc.url=jdbc:mysql://localhost:3306/myweb?useUnicode=true&characterEncoding=utf-8
slave.jdbc.username=root
slave.jdbc.password=root
 

 2.编写数据源处理类

public class DataSourceSwitch {
	@SuppressWarnings("rawtypes")
	private static final ThreadLocal contextHolder = new ThreadLocal();

	@SuppressWarnings("unchecked")
	public static void setDataSource(String dataSource) {
		Assert.notNull(dataSource, "数据源未创建成功!");
		contextHolder.set(dataSource);
	}
	public static void setMaster() {
		contextHolder.remove();
		contextHolder.set("master");
	}
	public static void setSlave() {
		contextHolder.remove();
		contextHolder.set("slave");
	}
    public static String getDataSouce(){
    	return contextHolder.get().toString();
    }
}
 

 3.编写数据源AOP切面类

public class DataSourceAdvice implements MethodBeforeAdvice,
		AfterReturningAdvice, ThrowsAdvice {
	private static Log log = LogFactory.getLog(DataSourceAdvice.class);
    private long beginTime=0;
	@Override
	/**
	 * SERVICE方法调用结束后调用
	 */
	public void afterReturning(Object arg, Method method, Object[] args,
			Object target) throws Throwable {
		log.info("结束业务处理[" + method.getName() + "];耗时:" + (System.currentTimeMillis()-beginTime)+"毫秒;全路径[" +target.getClass().getName()+ "]");
		log.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
	}

	@Override
	public void before(Method method, Object[] arg, Object target)
			throws Throwable {
		    log.info("开始业务处理["+method.getName()+"];全路径["+  target.getClass().getName()+"]");
		    beginTime=System.currentTimeMillis();
		    log.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
		   if(method.getName().startsWith("add")||method.getName().startsWith("create")
		      ||method.getName().startsWith("del")||method.getName().startsWith("edit")
		      ||method.getName().startsWith("insert")||method.getName().startsWith("save")
		      ||method.getName().startsWith("update")||method.getName().startsWith("modeify")){
			     log.info("数据源切换到:master"); 
			     DataSourceSwitch.setMaster();
			     log.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
		   }else{
			     log.info("数据源切换到:slave"); 
			     DataSourceSwitch.setSlave();
			     log.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
		   }
	}
	/**
	 * 抛出Exception异常调用
	 */
	public void afterThrowing(Method method, Object[] args, Object target, Exception ex) throws Throwable {
		 log.info("数据源调用发生异常,数据源切换到:slave");
		 DataSourceSwitch.setSlave();
		 log.error("数据源调用异常信息:"+ex.getMessage());
		 log.info("数据源调用异常信息:"+ex.getMessage());
		 log.info("++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
	} 
}
 

 4.编写动态数据源切换AOP类

public class DynamicDataSource extends AbstractRoutingDataSource{

	@Override
	protected Object determineCurrentLookupKey() {
		return DataSourceSwitch.getDataSouce();
	}

}
 由于code比较多,所以分开写,在查看的时候也比较方便。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值