从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("调用销毁"); }*/ }