基于Spring+Ibatis的安全线程实现
过去做过一些基于spring、hibernate整合应用的实例,本人感觉spring与hibernate最好的结合就是泛型Dao的实现,代码量节省了一半,而且业务逻辑一目了然。
后来做别的系统时候考虑过这样的框架,但是数据库结构如果不固定,动态生成的东西比较多这个时候只好放弃了hibernate而选择了同样具有orm性能的ibatis,下面就spring与ibatis的结合相关配置做下说明(如有不同意见,希望交流)
首先spring和ibatis具体下载和安装就不多说了。直接切入正题
Spring框架下的ibatis应用,特别是在容器事务管理模式下的ibatis应用开发
部署如下:
首先spring配置文件:
Spring_base.xml
/// dataSource:配置你的数据源连接 class="org.springframework.orm.ibatis.SqlMapClientFactoryBean">
sqlMapClient:集成ibatis配置文件和把数据源与ibatis相关联
/ transactionManager:配置事务管理
把用户自定义Bean与基本bean分开,集成进去spring_other.xml文件
|
以上是spring 把一些ibatis相关配置集成到自己的配置文件里面
Spring_other.xml
xml version="1.0" encoding="UTF-8"?> DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd"> <beans> <bean id="userService" class="com.user.UserServiceImpl"> <property name="transactionManager"> <ref bean="transactionManager" /> property> <property name="userDao"> <ref local="userDao" /> property> bean> 使用service管理所有用户自定义bean和Dao操作,用来设置事务回滚,线程安全等。 <bean id="userDao" class="com.user.dao.UserDaoImpl"> <property name="sqlMapClient" ref="sqlMapClient"/> bean> ///用户自定义Dao操作,因spring_base.xml中sqlMapClient已经把dataSource包含,故dataSource不再声明,如果该操作需要别的数据连接,可加入例如: beans> |
Spring_other.xml存放用户自定义bean
SqlMap_config.xml
xml version="1.0" encoding="UTF-8" ?>
DOCTYPE sqlMapConfig PUBLIC "-//ibatis.apache.org//DTD SQL Map Config 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-config-2.dtd">
<sqlMapConfig>
<settings lazyLoadingEnabled="true" useStatementNamespaces="true" enhancementEnabled="true" errorTracingEnabled="true" /> /定义ibatis相关操作参数,例如延迟加载,命名空间是否生效,是否打开缓存,调试阶段出错信息反馈等等 <sqlMap resource="com/user/user.xml" /> //包含用户的相关操作xml文件 sqlMapConfig> |
User.xml
xml version="1.0" encoding="UTF-8" ?>
DOCTYPE sqlMap PUBLIC "-//ibatis.apache.org//DTD SQL Map 2.0//EN" "http://ibatis.apache.org/dtd/sql-map-2.dtd">
<sqlMap namespace="User"> <typeAlias alias="user" type="com.user.User" />
<select id="getUser" parameterClass="java.lang.String" resultClass="user">
select id, name, sex from t_user where name like #name# ]]> select>
<update id="updateUser" parameterClass="user">
update t_user set name=#name#, sex=#sex# where id = #id# ]]> update>
<insert id="insertUser" parameterClass="user">
insert into t_user( id, name, sex) values( #id#, #name#, #sex# ) ]]> insert>
<delete id="deleteUser" parameterClass="java.lang.String">
delete from t_user where id = #value# ]]> delete>
<select id="selectUser" resultClass="user">
select * from t_user order by id desc ]]> select> sqlMap>
|
该配置文件属性就不多了。用户可在网上搜一堆够看了。
针对spring_other.xml 里面的用户自定义bean如下
UserDao.java 接口
1. package com.user.dao; 2. 3. import java.util.List; 4. 5. import com.user.User; 6. 7. 8. public interface UserDao { 9. public User getUser(String name); 10. public void updateUser(User user); 11. public List selectUser(); 12. public void insertUser(User user); 13. } |
UserDaoImpl.java 实现类
14. package com.user.dao; 15. 16. import java.util.List; 17. 18. import org.springframework.orm.ibatis.support.SqlMapClientDaoSupport; 19. 20. import com.user.User; 21. 22. 23. public class UserDaoImpl extends SqlMapClientDaoSupport implements UserDao { 24. //private static Logger log = Logger.getLogger(UserDaoImpl.class); 25. public User getUser(String name) { 26. return (User) this.getSqlMapClientTemplate().queryForObject("User.getUser","name"); 27. } 28. 29. public void updateUser(User user) { 30. this.getSqlMapClientTemplate().update("User.updateUser", user); 31. } 32. 33. public List selectUser() { 34. return this.getSqlMapClientTemplate().queryForList("User.selectUser",""); 35. } 36. 37. public void insertUser(User user) { 38. this.getSqlMapClientTemplate().insert("User.insertUser", user); 39. } 40. } |
现在大家也许看到这里觉得就差不多了。该Dao方法差不多全了,可以进行操作了。其实不然,下面我载自官方的一段:
Spring提供两种方式的编程式事务管理,分别是:使用TransactionTemplate和直接使用PlatformTransactionManager。 ⅰ. TransactionTempale采用和其他Spring模板,如JdbcTempalte和HibernateTemplate一样的方法。它使用回调方法,把应用程序从处理取得和释放资源中解脱出来。如同其他模板,TransactionTemplate是线程安全的 |
所以我们下面我们要再封装一层以实现线程是安全的。这就是我们在spirng_other.xml里面的那段配置实现
baseService.java
package com.base;
import org.springframework.transaction.support.TransactionTemplate;
/** * 工厂的基础类. * @author 刘玉华 * @time 2007-12-14 */
public class BaseService extends TransactionTemplate{ private static final long serialVersionUID = 1L; }
|
serviceFactory.java
41. package com.base; 42. 43. import org.springframework.beans.factory.BeanFactory; 44. import org.springframework.context.support.ClassPathXmlApplicationContext; 45. 46. import com.user.dao.UserDao; 47. 48. /** 49. * 数据操作工厂,所有的数据操作都从该工厂中获得。 50. * @author 刘玉华 51. * @time 2007-12-14 52. */ 53. 54. public class ServiceFactory { 55. private static BeanFactory factory = null; 56. 57. static { 58. ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext( 59. new String[] {"spring_base.xml"}); 60. factory = (BeanFactory) context; 61. } 62. 63. 64. 65. /** 66. * 获得用户服务类 67. * @return 用户服务 68. */ 69. public static UserDao getUserService(){ 70. return (UserDao) factory.getBean("userService"); 71. } 72. } |
我们所需要做的就是继承Baseservice.java 以实现tx管理
UserService.java
package com.user;
import java.util.List;
public interface UserService { public User getUser(final String name); public void updateUser(final User user); public List selectUser(); public void insertUser(final User user); }
|
UserServiceImpl.java 用户服务实现类
73. package com.user; 74. 75. import java.util.List; 76. 77. import org.springframework.transaction.TransactionStatus; 78. import org.springframework.transaction.support.TransactionCallback; 79. 80. import com.base.BaseService; 81. import com.user.dao.UserDao; 82. 83. public class UserServiceImpl extends BaseService implements UserDao { 84. private UserDao userDao; 85. 86. public UserDao getUserDao() { 87. return userDao; 88. } 89. 90. public void setUserDao(UserDao userDao) { 91. this.userDao = userDao; 92. } 93. 94. public List selectUser() { 95. Object obj = execute(new TransactionCallback(){ 96. public Object doInTransaction(TransactionStatus status) { 97. return userDao.selectUser(); 98. } 99. }); 100. return (List)obj; 101. } 102. 103. public User getUser(final String name){ 104. Object obj = execute(new TransactionCallback(){ 105. public Object doInTransaction(TransactionStatus status) { 106. // TODO Auto-generated method stub 107. return userDao.getUser(name); 108. } 109. }); 110. return (User) obj; 111. } 112. 113. public void insertUser(final User user) { 114. Object obj = execute(new TransactionCallback(){ 115. public Object doInTransaction(TransactionStatus status) { 116. userDao.insertUser(user); 117. return null; 118. } 119. }); 120. } 121. 122. public void updateUser(final User user) { 123. Object obj = execute(new TransactionCallback(){ 124. public Object doInTransaction(TransactionStatus arg0) { 125. userDao.updateUser(user); 126. return null; 127. } 128. }); 129. 130. } 131. 132. } |
这样我们就把相关操作实现事务控制了。
数据表建立:
create table t_user( "id" int null, "name" varchar(50) null, "sex" int null )
|
这样我们在以后调用方式为:
测试类
133. package com.user.junit; 134. 135. import java.util.List; 136. 137. import com.base.ServiceFactory; 138. import com.user.User; 139. import com.user.dao.UserDao; 140. import common.Logger; 141. 142. public class UserTest { 143. private static Logger log = Logger.getLogger(UserTest.class); 144. public static void main(String args[]){ 145. UserDao service = ServiceFactory.getUserService(); 146. User user=null; 147. int i = 4; 148. switch (i) { 149. case 0: 150. user.setId(1); 151. user.setName("444"); 152. user.setSex(2); 153. service.updateUser(user); 154. System.out.println(user.getName()+" "+user.getSex()); 155. break; 156. case 1: 157. try { 158. user = service.getUser("2"); 159. } catch (Exception e) { 160. log.debug("出错了"+e.getMessage()); 161. } 162. System.out.println(user.getId()); 163. case 3: 164. List 165. for (int j = 0; j < ls.size(); j++) { 166. System.out.println(ls.get(j).getId()+"===="+ls.get(j).getName()); 167. } 168. case 4: 169. List 170. for (int j = 0; j < ls1.size(); j++) { 171. user = ls1.get(j); 172. System.out.println(user.getId()+user.getName()+user.getSex()+user.getAddress()); 173. } 174. for (int j = 0; j < 100; j++) { 175. user.setId(user.getId()+1); 176. service.insertUser(user); 177. } 178. default: 179. break; 180. } 181. } 182. } |
基本上差不多了。如果有需要源码的请联系我,FirstIbatis.zip 为整合serivce之前的。
FirstIbatis_no_service.zip 为整合serivce之后的,可以到我的资源查找这两个下载