获取Session方式二

之前讲解的openSession()是获取Session的方式一:

开启事务: 开启事务属于数据库操作,但写在 dao 里面导致每个方法开启一次事务,所以一般在 service 开启, 方案:
通过参数的方式传递下去(确保底层使用的都是同样一个session)
把Connection绑定到ThreadLocal对象中,多线程能够保持使用各自的一个对象。如果set是同一个对象,get还是共享对象。

image.png

开发流程:
第一步:配置开启支持本地线程绑定
开启事务并传递session对象,框架提供了ThreadLocal方式。

<property name="hibernate.current_session_context_class">thread</property>


注意事项:
使用这种方式,所有的功能必须使用事务。


第二步:获取session
使用SessionFactory的getCurrentSession() 获取当前的Session对象。该对象不用手动关闭,线程结束了,会自动关闭。

完善HibernateUtils 工具类:

public class HibernateUtils {
private static SessionFactory sessionFactory ;
static {
Configuration configure = new Configuration().configure("hibernate.cfg.xml");
sessionFactory=configure.buildSessionFactory();
}
public static Session getSession(){
return sessionFactory.openSession();
}

//获取session方式二,使用这个session必须开启事务
public static Session getCuurentSession(){
    //受线程绑定,也就是在多线程环境下,是线程安全的。
    return sessionFactory.getCurrentSession();
}

}

第三步:开发

注意:

必须开启事务
这种方式查询也必须使用事务,可以设置为只读。

image.png

如过不开启事务会报错:

image.png

核心代码如下:
@Test
public void testQueryByAnotherSession(){
Session cuurentSession = HibernateUtils.getCuurentSession();
String sql="from TUserInfo where uId=:uid";
Query<TUserInfo> query = cuurentSession.createQuery(sql, TUserInfo.class);
query.setParameter("uid",15L);
TUserInfo tUserInfo = query.uniqueResult();
System.out.println(tUserInfo);
}
运行:


image.png

发现报错了, 报错信息很明显,这个时候需要我们去加上事物处理。

修改代码 加上事物如下:


image.png

正常输出:


image.png

扩展(对比两个session)
getCurrentSession多线程安全
openSession多线程不安全

image.png

public void testSession(){
//在用一个线程内,用HibernateUtils.getCuurentSession()取得到的是一样的session
Session cuurentSession = HibernateUtils.getCuurentSession();
System.out.println(cuurentSession);
Session cuurentSession1 = HibernateUtils.getCuurentSession();
System.out.println(cuurentSession1);
System.out.println("对比结果:");
System.out.println(cuurentSession==cuurentSession1);
Session session = HibernateUtils.openSession();
Session session2 = HibernateUtils.openSession();
System.out.println("openSession对比结果:");
System.out.println(session==session2);

}

输出结果如下所示


image.png

推荐阅读更多精彩内容