前言
今天继续学习了绑定sesssion,还是一些hibernate会出现的一些常见问题,但是已经有比较好的解决方法了。
先来说说在学习JavaWeb的时候有一个工具类,叫做ThreadLocal。它主要是一个MAP集合,在JavaAPI中可以查到
它的K值是线程,V值是存放的值。
它的set方法,只要存放的V值,K值会自动获取当前线程标识。
它的get方法,不需要参数,可以获得线程,存入的对象。
在Hibernate中会出现这样一个问题,我们是按照MVC分层,我们的业务处理在逻辑层,事务也是开启在逻辑层。如果一个事务有2个dao。那么他们就需要用到同一个session。如果同一个逻辑处理,没有用到同一个session。其中一个失败。回滚,就只回滚到一半。这个是很明显不对的。
分析
绑定本地的Session
1. 之前在讲JavaWEB的事务的时候,需要在业务层使用Connection来开启事务,
* 一种是通过参数的方式传递下去
* 另一种是把Connection绑定到ThreadLocal对象中
2. 现在的Hibernate框架中,使用session对象开启事务,所以需要来传递session对象,框架提供了ThreadLocal的方式
* 需要在hibernate.cfg.xml的配置文件中提供配置
* <property name="hibernate.current_session_context_class">thread</property>
* 重新HibernateUtil的工具类,使用SessionFactory的getCurrentSession()方法,获取当前的Session对象。并且该Session对象不用手动关闭,线程结束了,会自动关闭。
public static Session getCurrentSession(){
return factory.getCurrentSession();
}
* 注意:想使用getCurrentSession()方法,必须要先配置才能使用。
1.首先在核心配置里加上
* <property name="hibernate.current_session_context_class">thread</property>
2.之后在工具类中加上方法如下
package com.itheima.utils;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
/**
* Hibernate框架的工具类
* @author Administrator
*/
public class HibernateUtils {
// ctrl + shift + x
private static final Configuration CONFIG;
private static final SessionFactory FACTORY;
// 编写静态代码块
static{
// 加载XML的配置文件
CONFIG = new Configuration().configure();
// 构造工厂
FACTORY = CONFIG.buildSessionFactory();
}
/**
* 从工厂中获取Session对象
* @return
*/
public static Session getSession(){
return FACTORY.openSession();
}
/**
* // 从ThreadLocal类中获取到session的对象
* @return
*/
public static Session getCurrentSession(){
return FACTORY.getCurrentSession();
}
public static void main(String[] args) {
// 调用获取session的方法
getSession();
}
}
之后业务层。就如下:
public class UserService {
public void save(User u1,User u2){
UserDao dao = new UserDao();
// 获取session
Session session = HibernateUtils.getCurrentSession();
// 开启事务
Transaction tr = session.beginTransaction();
try {
dao.save1(u1);
int a = 10/0;
dao.save2(u2);
// 提交事务
tr.commit();
} catch (Exception e) {
e.printStackTrace();
// 出现问题:回滚事务
tr.rollback();
}finally{
// 自己释放资源,现在,session不用关闭,线程结束了,自动关闭的!!
}
}
}
dao层就如下。
package com.itheima.dao;
import org.hibernate.Session;
import com.itheima.domain.User;
import com.itheima.utils.HibernateUtils;
public class UserDao {
public void save1(User u1){
Session session = HibernateUtils.getCurrentSession();
session.save(u1);
}
public void save2(User u2){
Session session = HibernateUtils.getCurrentSession();
session.save(u2);
}
}
以上就是解决办法。注意,利用ThreadLocal封装的工具,不需要销毁session。已经自动销毁了。