`
wangkebin
  • 浏览: 74861 次
  • 性别: Icon_minigender_1
  • 来自: 贵阳
社区版块
存档分类
最新评论

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

阅读更多

   最近使用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比较多,所以分开写,在查看的时候也比较方便。
1
1
分享到:
评论
6 楼 wangkebin 2012-07-31  
casheen 写道
可以通过设置AOP优先级的方式,来解决该问题,参考http://hi.baidu.com/litianyi520/blog/item/71279e3e180db6f1838b1327.html

casheen 写道
测试发现去除Spring事务管理后,在AOP中就能够正确切换数据源了。有没有办法既支持数据源切换,又支持事务?
casheen 写道
经测试发现这种方法在DynamicDataSource.determineCurrentLookupKey();是在AOP方法之前执行的,也就是说拦截业务方法之前就已经决定了使用哪个数据源,AOP拦截后调用DataSourceSwitch.setSlave();根本无法改变数据源。

需要进一步考虑改进方案。


casheen 写道
测试发现去除Spring事务管理后,在AOP中就能够正确切换数据源了。有没有办法既支持数据源切换,又支持事务?
casheen 写道
经测试发现这种方法在DynamicDataSource.determineCurrentLookupKey();是在AOP方法之前执行的,也就是说拦截业务方法之前就已经决定了使用哪个数据源,AOP拦截后调用DataSourceSwitch.setSlave();根本无法改变数据源。

需要进一步考虑改进方案。



好的,谢谢,过几天有空重新整理下代码。
5 楼 casheen 2012-07-24  
可以通过设置AOP优先级的方式,来解决该问题,参考http://hi.baidu.com/litianyi520/blog/item/71279e3e180db6f1838b1327.html

casheen 写道
测试发现去除Spring事务管理后,在AOP中就能够正确切换数据源了。有没有办法既支持数据源切换,又支持事务?
casheen 写道
经测试发现这种方法在DynamicDataSource.determineCurrentLookupKey();是在AOP方法之前执行的,也就是说拦截业务方法之前就已经决定了使用哪个数据源,AOP拦截后调用DataSourceSwitch.setSlave();根本无法改变数据源。

需要进一步考虑改进方案。


casheen 写道
测试发现去除Spring事务管理后,在AOP中就能够正确切换数据源了。有没有办法既支持数据源切换,又支持事务?
casheen 写道
经测试发现这种方法在DynamicDataSource.determineCurrentLookupKey();是在AOP方法之前执行的,也就是说拦截业务方法之前就已经决定了使用哪个数据源,AOP拦截后调用DataSourceSwitch.setSlave();根本无法改变数据源。

需要进一步考虑改进方案。


4 楼 casheen 2012-07-23  
测试发现去除Spring事务管理后,在AOP中就能够正确切换数据源了。有没有办法既支持数据源切换,又支持事务?
casheen 写道
经测试发现这种方法在DynamicDataSource.determineCurrentLookupKey();是在AOP方法之前执行的,也就是说拦截业务方法之前就已经决定了使用哪个数据源,AOP拦截后调用DataSourceSwitch.setSlave();根本无法改变数据源。

需要进一步考虑改进方案。

3 楼 casheen 2012-07-23  
经测试发现这种方法在DynamicDataSource.determineCurrentLookupKey();是在AOP方法之前执行的,也就是说拦截业务方法之前就已经决定了使用哪个数据源,AOP拦截后调用DataSourceSwitch.setSlave();根本无法改变数据源。

需要进一步考虑改进方案。
2 楼 wangkebin 2011-10-13  
lyy3323 写道
大概看了一下,有几个问题请教一下:
1.读写分离测试?

哪有?不过是两个数据源之间的切换,而且这两个数据源不是一样的吗??


2.
这样切换数据源对于连接池有没有影响?


你好,请看清楚我的文章开头的文字:"由于只是测试,所以读写分离使用的还是一个数据库,同一个用户名和密码.这个可以根据需求修改",如果要修改成不同数据库,修改下配置即可完成 ,其他地方不用修改的

2.对连接池是否有影响,这个问题我想是没有影响的,但是具体证明我暂时没有方法,如果哪位有好方法的话 不妨提供测试下.(数据源的连接池配置是采取共同配置)
1 楼 lyy3323 2011-10-13  
大概看了一下,有几个问题请教一下:
1.读写分离测试?

哪有?不过是两个数据源之间的切换,而且这两个数据源不是一样的吗??


2.
这样切换数据源对于连接池有没有影响?

相关推荐

    ibatis+spring+struts完整例子数据同步程序

    这个"ibatis+spring+struts完整例子数据同步程序"就是一个典型的Java EE应用程序,它整合了三个关键的开源框架:Struts、Spring和iBatis。这些框架分别负责表现层、业务层和服务层的管理,提供了一个强大的开发工具...

    SSi(Struts2+Spring+iBatis)实现文件上传下载功能

    而iBatis则作为一个持久层框架,简化了SQL操作,实现了数据访问层与业务逻辑的分离。 在这个项目中,"SSi实现文件上传下载功能"主要是利用Struts2的Action类和拦截器来处理HTTP请求,Spring来管理服务层对象,以及...

    struts2 spring2 ibatis整合代码完整项目

    Struts2、Spring2 和 iBatis 是三个在Java Web开发中非常重要的开源框架,它们分别负责MVC模式中的Action层、依赖注入及业务层的数据访问。本项目整合了这三个框架,提供了一个完整的代码实现,方便开发者快速搭建...

    mvc框架整合示例

    在IT行业中,MVC(Model-View-Controller)框架是一种广泛应用的设计模式,它将应用程序的业务逻辑、数据处理和用户界面分离,提高了代码的可维护性和可扩展性。本示例着重于展示如何将多种MVC相关的技术进行整合,...

    SpringMvc+Ibatis包

    iBATIS则是一个SQL映射框架,它允许开发者将SQL查询与Java代码分离,从而简化数据访问层的开发。`ibatis-2.3.4.726.jar`是iBATIS的主要库文件,包含了执行SQL、处理结果集以及事务管理等功能。iBATIS的使用可以使得...

    跟我学spring3(8-13).pdf

    1. **10.1 概述**:Spring可以通过Servlet监听器、DispatcherServlet、MVC配置等方式与其他Web框架如Struts、JSF集成,实现业务逻辑和展示层的分离。 2. **10.2 集成Struts1.x**:Spring可以作为Struts的动作处理器...

    iBATIS实战

    9.6.2 高速缓存可读写数据 169 9.6.3 高速缓存旧的静态数据 170 9.7 小结 172 第10章 iBATIS数据访问对象 173 10.1 隐藏实现细节 173 10.1.1 为何要分离 174 10.1.2 一个简单示例 175 10.2 配置DAO 177 10.2.1 ...

    ssi框架入门详解

    SSI框架,全称为Struts2、Spring和Ibatis的集成框架,是一种常见的Java Web开发解决方案。这个框架结合了这三个组件的优点,以实现高效且灵活的Web应用开发。 **Struts2**作为MVC框架,主要负责处理HTTP请求,提供...

    JAVA技术体系.pdf

    - **具体框架**:Struts1和2提供表现层支持,Spring提供业务层服务,Hibernate和iBATIS处理数据持久化。 4. **Java高级软件工程师**: - **开源技术与框架**:如工作流引擎、规则引擎、搜索引擎、缓存、任务调度...

    面试JAVA程序员常遇到的一些问题.pdf,这是一份不错的文件

    3. Hibernate与MyBatis/ibatis的区别:Hibernate提供了一种对象关系映射(ORM)解决方案,自动处理SQL和对象之间的转换,而MyBatis和ibatis更倾向于SQL的控制,允许开发者直接编写SQL语句进行数据操作。 4. Struts与...

    MyEclipse中涵盖知识点.pdf

    Spring框架中的声明式事务管理,允许开发者在配置文件中声明事务边界,而不是在代码中显式处理。这种方式降低了事务管理对业务逻辑的影响,提高了代码的可维护性。 11. 数据持久化: 数据持久化是将内存中的数据...

    java必备知识点大全.pdf

    字节流与字符流的区别:字节流用于读写二进制数据,字符流用于读写文本数据。 final、finally、finalize三者区别:final用于声明常量,finally用在try-catch-finally语句中表示必须执行的代码块,finalize是Object...

    java初学者的比较好的学习路线(转)

    - **Spring框架**:掌握Spring的核心容器、AOP、事务管理等技术。 ##### 实战项目 - **OA系统**:基于Spring + Struts + Hibernate开发办公自动化系统。 - **CRM系统**:实现客户关系管理系统,涉及客户信息管理、...

    【白雪红叶】JAVA学习技术栈梳理思维导图.xmind

    读写分离 性能优化架构能力 代码级别 关联代码优化 cache对其 分支预测 copy on write 内联优化 系统优化 cache 延迟计算 数据预读 异步 轮询与通知 内存池 模块化 工程架构能力 开发语言 运维与...

    常用jar包说明

    - **c3p0.jar**:C3P0是一个开放源代码的JDBC连接池,被许多框架如Hibernate用作数据源管理,优化数据库连接复用。 - **commons-pool.jar**, **commons-dbcp.jar**:Apache Commons下的连接池组件,主要用于管理...

    java资料集

    而`ibatis配置.txt`可能涉及的是MyBatis框架的配置和使用,它是一个轻量级的持久层框架,简化了数据库操作。 面向切面编程(AOP)是另一种提升代码组织和复用性的技术。`aop`标签暗示了这个资料集可能包含AOP的基本...

    java文集

    Java 6 RowSet 使用完全剖析 结合Spring2.0和ActiveMQ进行异步消息调用 struts+hibernate增删改查(一) AXIS 布署问题 struts+hibernate增删改查(二) MySQL中如何实现Top N及M至N段的记录查询?...

    java知识总结.doc

    2. 基础类库:Java的标准库提供了丰富的API,如IO流用于文件读写和数据传输,集合框架(Collection)提供了ArrayList、LinkedList、HashSet、HashMap等多种数据结构,线程(Thread)支持并发执行,Socket编程接口用于...

Global site tag (gtag.js) - Google Analytics