当前位置: 代码迷 >> Web前端 >> Spring调整iBatis之三:从Spring角度看两框架整合(包括事务处理)
  详细解决方案

Spring调整iBatis之三:从Spring角度看两框架整合(包括事务处理)

热度:352   发布时间:2012-11-06 14:07:00.0
Spring整合iBatis之三:从Spring角度看两框架整合(包括事务处理)


    从spring看整合,spring自己的本职工作大体上只剩加载配置文件,和运行service了。

    

   这两者都要有所改变,具体来讲:

    1.applicationContext-common.xml要把iBatis需要整合的功能都接手过来,比如数据源配置iBatis配置、准备和注入iBatis需要的template模版还有事务管理,下文细说。

    2.service要执行iBatis管理好了的DAO操作


    



一:applicationContext-common.xml

整个整合过程中最麻烦的东西就在这里边

由它加载的东西很多:

    1.iBatis的数据源配置(驱动、URL、用户名、密码)

    2.iBatis自身的配置(iBatis管理哪个类和表的对应,命名空间是什么)

    3.注入DAO的service(要执行DAOImpl)

    4.事务处理器(tx:advice,筛选的命名规则,什么只读,怎么处理)

    5.事务处理aop(什么方法要用事务处理,用哪个事务处理器处理)

具体看注释吧

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:aop="http://www.springframework.org/schema/aop"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
           	http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
            http://www.springframework.org/schema/tx 
     		http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
     		http://www.springframework.org/schema/aop 
     		http://www.springframework.org/schema/aop/spring-aop-3.0.xsd">

  
 
	<!-- 新增1:配置数据源(从ibatis配置改到spring配置) -->  
    <bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">  
        <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />  
        <property name="url" value="jdbc:oracle:thin:@localhost:1521:ORCL" />  
        <property name="username" value="scott" />  
        <property name="password" value="890307" />  
    </bean> 
	<!-- 新增2:spring的ibatis配制,目的是要SqlMapClientTemplate -->  
     <bean id="sqlMapClient"  class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">  
        <property name="configLocation" value="SqlMapConfig.xml"/>  
        <property name="dataSource" ref="dataSource" />  
    </bean> 

  
   
  <!-- 相当于调用了无参构造,实例化了s1Dao对象-->
  <!-- dao --> 
  <bean id="s1Dao" class="com.rt.sidemo.dao.StudentDAOImpl">
	<property name="sqlMapClient" ref="sqlMapClient"></property>  
  </bean> 
  <!-- bean标签中id=XXX或者name=XXX,作用基本一样,name可以加入一些特殊字符  -->
  <!-- scope默认是"singleton" 单例模式;  "prototype" 是每次都new一个新的实例-->
  <!-- service --> 
  <bean name="StudentService01" class="com.rt.sidemo.service.StudentService" scope="singleton">	 
  	<!--1.property这句就相当于设置了属性,也就是调用 set【studentDAO】(【s1Dao】) -->
  	<property name="studentDAO" ref="s1Dao" />
  	
  	<!-- 其他注入方式:
	1.property去注入一个属性,也是要去调用setter		
  	<property name="propertyInj" value="新注入的属性值" />  			 
  	2.constructor-arg相当于调用构造函数: public 【StudentService】(IStudentDAO 【s1Dao】)  
   	<constructor-arg>
  	 	<ref bean="u1"/>
  	</constructor-arg> -->	
  </bean>
  
  
	<!-- 事务处理,需要配套的xmlns和schemaLocation -->
	<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">  
	     <property name="dataSource" ref="dataSource"/>  
	</bean> 
	<tx:advice id="transactionManagerAdivice" transaction-manager="transactionManager">  
	   <tx:attributes>  
	      <tx:method name="get*" propagation="REQUIRED" read-only="true" rollback-for="java.lang.RuntionException" />  
	      <tx:method name="add*" propagation="REQUIRED" rollback-for="java.lang.RuntionException" />  
	   </tx:attributes>  
	</tx:advice>  
	<aop:config>  
	   <aop:pointcut id="allManagerMethod" expression="execution( * com.rt.sidemo.service.*.*(..))"/>  
	   <aop:advisor advice-ref="transactionManagerAdivice" pointcut-ref="allManagerMethod"/>  
	</aop:config> 
  

</beans>



二:StudentService.java

这个去用iDAO的接口就行了,


不过值得一提的是管理iBatis事务管理这块,我这用一个小例子验证了一下:

    1.我在一个操作中先后插入了一个正确的实例,和一个故意出错的实例(之前已经插入过相同主键)

        正常实例插入后,故意出错实例报错“违反唯一约束”
    2.此时,连同‘已经’插入的正常实例一起回滚,也就是只要有异常,整步操作全都回滚 

证明事务处理是正确的

package com.rt.sidemo.service;
import java.util.List;

import com.rt.sidemo.dao.IStudentDAO;
import com.rt.sidemo.model.Student;

public class StudentService {
	
	//xml中,"s1Dao" class="com.rt.sidemo.dao.StudentDAOImpl",将注入在此属性中
	//注入的实例中还包含dataSource和ibatis配置
	private IStudentDAO studentDAO;  
	
	public void add(Student stu) {//test调用这个add方法
		/*
		 * 正常实例插入后,故意出错实例报错‘违反唯一约束’
		 * 此时,连同‘已经’插入的正常实例一起回滚,也就是只要有异常,整步操作全都回滚
		 * 证明事务处理时是正确的
		 * 
		Student stuNew = new Student();//正常实例,这个可以正常插入没问题
		stuNew.setStudentid(780);
		stuNew.setName("Spring+iBatis4");
		stuNew.setAge(780);	
		studentDAO.addStudent(stuNew);
		
		Student stuReplace = new Student();//故意出错实例,这个主键之前已经有了,插入会‘违反唯一约束’
		stuReplace.setStudentid(779);
		stuReplace.setName("Spring+iBatis3");
		stuReplace.setAge(779);	
		studentDAO.addStudent(stuReplace);
		*/
		studentDAO.addStudent(stu);
	}
	public List<Student> getAll() {//test调用
		return studentDAO.selectAll();
	}

	//setter&getter
	public IStudentDAO getStudentDAO() {
		return studentDAO;
	}
	public void setStudentDAO(IStudentDAO studentDAO) {
		this.studentDAO = studentDAO;
	}
	/*其他注入方式
	 * 1属性注入
	private String propertyInj;//
	public String getPropertyInj() {
		return propertyInj;
	}
	public void setPropertyInj(String propertyInj) {
		this.propertyInj = propertyInj;
		System.out.println("属性注入--"+propertyInj);
	}
	 * 2构造
	public StudentService()
	{
	}
	public StudentService(IStudentDAO user)//构造时注入
	{
		user.addStudent(new Student());
	}
	//lazy-init
	public void UserInit()
	{
		System.out.println("调用初始");
	}
	public void UserDestroy()
	{
		System.out.println("调用销毁");
	}*/	
}






  相关解决方案