线程不安全的原因 基于Spring+Ibatis的安全线程实现
基于Spring+Ibatis的安全线程实现
过去做过一些基于spring hibernate整合应用的实例 本人感觉spring与hibernate最好的结合就是泛型Dao的实现 代码量节省了一半 而且业务逻辑一目了然
后来做别的系统时候考虑过这样的框架 但是数据库结构如果不固定 动态生成的东西比较多这个时候只好放弃了hibernate而选择了同样具有orm性能的ibatis 下面就spring与ibatis的结合相关配置做下说明(如有不同意见 希望交流)
首先spring和ibatis具体下载和安装就不多说了 直接切入正题
Spring框架下的ibatis应用 特别是在容器事务管理模式下的ibatis应用开发
部署如下
首先spring配置文件
Spring_base xml
<?xml version= encoding= UTF ?>
<!DOCTYPE beans PUBLIC //SPRING//DTD BEAN//EN beans dtd >
<beans default lazy init= true >
<! 配置数据源 >
<bean id= dataSource class= mons dbcp BasicDataSource destroy method= close >
<property name= driverClassName >
<value>net sourcefe jtds jdbc Driver</value>
</property>
<property name= url >
<value>jdbc:jtds:sqlserver://localhost: /test</value>
</property>
<property name= username >
<value>sa</value>
</property>
<property name= password >
<value>sa</value>
</property>
<property name= maxActive >
<value> </value>
</property>
<property name= maxIdle >
<value> </value>
</property>
<property name= maxWait >
<value> </value>
</property>
</bean>
/////////////////// dataSource 配置你的数据源连接
<bean id= sqlMapClient
class= springframework orm ibatis SqlMapClientFactoryBean >
<property name= configLocation >
<value>SqlMap_config xml</value>
</property>
<property name= dataSource ><! 从指定dataSource中获取数据源 亦可把该定义放到每个自定义Dao中 >
<ref bean= dataSource />
</property>
</bean>
//////////////////// sqlMapClient 集成ibatis配置文件和把数据源与ibatis相关联
<! 配置事务管理 >
<bean id= transactionManager class= springframework jdbc datasource DataSourceTransactionManager >
<property name= dataSource >
<ref local= dataSource />
</property>
</bean>
///////////////// transactionManager:配置事务管理
<! 公共组件 >
<import resource= spring_other xml />
////////////把用户自定义Bean与基本bean分开 集成进去spring_other xml文件
</beans>
以上是spring 把一些ibatis相关配置集成到自己的配置文件里面
Spring_other xml
<?xml version= encoding= UTF ?>
<!DOCTYPE beans PUBLIC //SPRING//DTD BEAN//EN beans dtd >
<beans>
<bean id= userService class= user UserServiceImpl >
<property name= transactionManager >
<ref bean= transactionManager />
</property>
<property name= userDao >
<ref local= userDao />
</property>
</bean>
////////////////////////使用service管理所有用户自定义bean和Dao操作 用来设置事务回滚 线程安全等
<bean id= userDao class= user dao UserDaoImpl >
<property name= sqlMapClient ref= sqlMapClient />
</bean>
///////////////用户自定义Dao操作 因spring_base xml中sqlMapClient已经把dataSource包含 故dataSource不再声明 如果该操作需要别的数据连接 可加入例如
////////<property name= dataSource ref= dataSource />//////////
</beans>
Spring_other xml存放用户自定义bean
SqlMap_config xml
<?xml version= encoding= UTF ?>
<!DOCTYPE sqlMapConfig
PUBLIC ////DTD SQL Map Config //EN
map config dtd >
<sqlMapConfig>
<settings lazyLoadingEnabled= true
useStatementNamespaces= true
enhancementEnabled= true
errorTracingEnabled= true
/>
/////////////定义ibatis相关操作参数 例如延迟加载 命名空间是否生效 是否打开缓存 调试阶段出错信息反馈等等
<sqlMap resource= /user/user xml />
//////////////包含用户的相关操作xml文件
</sqlMapConfig>
User xml
<?xml version= encoding= UTF ?>
<!DOCTYPE sqlMap
PUBLIC ////DTD SQL Map //EN
map dtd >
<sqlMap namespace= User >
<typeAlias alias= user type= user User /><! obj >
<! get user >
<select id= getUser
parameterClass= java lang String
resultClass= user >
<![CDATA[
select
id
name
sex
from
t_user
where name like #name#
]]>
</select>
<! update user >
<update id= updateUser parameterClass= user >
<![CDATA[
update t_user
set
name=#name#
sex=#sex#
where id = #id#
]]>
</update>
<insert id= insertUser parameterClass= user >
<![CDATA[
insert into t_user(
id
name
sex)
values(
#id#
#name#
#sex#
)
]]>
</insert>
<delete id= deleteUser parameterClass= java lang String >
<![CDATA[
delete from t_user
where id = #value#
]]>
</delete>
<select id= selectUser resultClass= user >
<![CDATA[
select * from t_user order by id desc
]]>
</select>
</sqlMap>
该配置文件属性就不多了 用户可在网上搜一堆够看了
针对spring_other xml 里面的用户自定义bean如下
UserDao java 接口
package user dao;
import java util List;
import user User;
public interface UserDao {
public User getUser(String name);
public void updateUser(User user);
public List selectUser();
public void insertUser(User user);
}
UserDaoImpl java 实现类
package user dao;
import java util List;
import springframework orm ibatis support SqlMapClientDaoSupport;
import user User;
public class UserDaoImpl extends SqlMapClientDaoSupport implements UserDao {
//private static Logger log = Logger getLogger(UserDaoImpl class);
public User getUser(String name) {
return (User) this getSqlMapClientTemplate() queryForObject( User getUser name );
}
public void updateUser(User user) {
this getSqlMapClientTemplate() update( User updateUser user);
}
public List selectUser() {
return this getSqlMapClientTemplate() queryForList( User selectUser );
}
public void insertUser(User user) {
this getSqlMapClientTemplate() insert( User insertUser user);
}
}
现在大家也许看到这里觉得就差不多了 该Dao方法差不多全了 可以进行操作了 其实不然 下面我载自官方的一段
Spring提供两种方式的编程式事务管理 分别是 使用TransactionTemplate和直接使用PlatformTransactionManager ⅰ TransactionTempale采用和其他Spring模板 如JdbcTempalte和HibernateTemplate一样的方法 它使用回调方法 把应用程序从处理取得和释放资源中解脱出来 如同其他模板 TransactionTemplate是线程安全的
所以我们下面我们要再封装一层以实现线程是安全的 这就是我们在spirng_other xml里面的那段配置实现
baseService java
package base;
import springframework transaction support TransactionTemplate;
/**
* 工厂的基础类.
* @author 刘玉华
* @time
*/
public class BaseService extends TransactionTemplate{
private static final long serialVersionUID = L;
}
serviceFactory java
package base;
import springframework beans factory BeanFactory;
import ntext support ClassPathXmlApplicationContext;
import user dao UserDao;
/**
* 数据操作工厂 所有的数据操作都从该工厂中获得
* @author 刘玉华
* @time
*/
public class ServiceFactory {
private static BeanFactory factory = null;
static {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(
new String[] { spring_base xml });
factory = (BeanFactory) context;
}
/**
* 获得用户服务类
* @return 用户服务
*/
public static UserDao getUserService(){
return (UserDao) factory getBean( userService );
}
}
我们所需要做的就是继承Baseservice java 以实现tx管理
UserService java
package 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 用户服务实现类
package user;
import java util List;
import springframework transaction TransactionStatus;
import springframework transaction support TransactionCallback;
import base BaseService;
import user dao UserDao;
public class UserServiceImpl extends BaseService implements UserDao {
private UserDao userDao;
public UserDao getUserDao() {
return userDao;
}
public void setUserDao(UserDao userDao) {
this userDao = userDao;
}
public List selectUser() {
Object obj = execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus status) {
return userDao selectUser();
}
});
return (List)obj;
}
public User getUser(final String name){
Object obj = execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus status) {
// TODO Auto generated method stub
return userDao getUser(name);
}
});
return (User) obj;
}
public void insertUser(final User user) {
Object obj = execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus status) {
userDao insertUser(user);
return null;
}
});
}
public void updateUser(final User user) {
Object obj = execute(new TransactionCallback(){
public Object doInTransaction(TransactionStatus arg ) {
userDao updateUser(user);
return null;
}
});
}
} 这样我们就把相关操作实现事务控制了
数据表建立
create table t_user(
id int null
name varchar( ) null
sex int null
)
这样我们在以后调用方式为
测试类
package user junit;
import java util List;
import base ServiceFactory;
import user User;
import user dao UserDao;
import mon Logger;
public class UserTest {
private static Logger log = Logger getLogger(UserTest class);
public static void main(String args[]){
UserDao service = ServiceFactory getUserService();
User user=null;
int i = ;
switch (i) {
case :
user setId( );
user setName( );
user setSex( );
service updateUser(user);
System out println(user getName()+ +user getSex());
break;
case :
try {
user = service getUser( );
} catch (Exception e) {
log debug( 出错了 +e getMessage());
}
System out println(user getId());
case :
List<User> ls = service selectUser();
for (int j = ; j < ls size(); j++) {
System out println(ls get(j) getId()+ ==== +ls get(j) getName());
}
case :
List<User> ls = service selectUser();
for (int j = ; j < ls size(); j++) {
user = ls get(j);
System out println(user getId()+user getName()+user getSex()+user getAddress());

}
for (int j = ; j < ; j++) {
user setId(user getId()+ );
service insertUser(user);
}
default:
break;
}
}
lishixinzhi/Article/program/Java/ky/201311/28732