Hibernate的学习之路十六(绑定本地session)

前言  

       今天继续学习了绑定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。已经自动销毁了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值