您的位置:首页 > 其它

hibernate中session与本地线程绑定

2018-03-10 00:07 232 查看

Hibernate中Session与本地线程作绑定

为什么要把Session与本地线程绑定??

在overstackoverflow中有这样的说法:



大体意思就是:

openSession():

总是创建一个新的session对象

你需要去明确的关闭session对象

在单线程环境它比getCurrentSession()更慢

你也不需要去配置任何属性,你就能够使用这个方法

getCurrentSession():

如果session不存在,它将创建一个新的session,否则在当前hibernate环境中使用同一个session

你不需要去关闭session对象,它将自动被hibernate内部机制关闭

在单线程环境它比opensession更快

你需要去配置中附加hibernate.current_session_context_class这个属性,才能够调用getCurrentSession()方法否则将会抛出异常

所以在这里openSession()和getCurrentSession()的主要区别就是快和慢的区别。

//这是开源社区的一个答案:
所以对于查询方法,个人觉得没有必要添加事务,所以这个时候就不通过getCurrentSession来获取,只能OpenSession对于查询方法注解为readonly=true 就不用事务   //注解大概就是Spring吧,我还没学。。。
所有查询方法要么注解readonly=true 要么xml配置只读!
就不会影响效率!!

//另一个
但是添加注解会增加事务,而事务会影响程序运行效率,所以对于查询方法,个人觉得没有必要添加事务,所以这个时候就不通过getCurrentSession来获取,只能OpenSession

//总的来说要开启事务的话,还是用getCurrentSession()比较好。因为方便而且快啊。
1
2
3
4
5
6
7
8
9
10
11
[/code]

我们每次通过openSession()打开的session都是一次数据库连接。

session类似于jdbc的connection,它的底层依赖于我们web阶段学过的threadLocal

Hibernate已经帮我们实现了session与本地线程绑定

我们怎样获取与本地线程绑定的session:

首先在hibernate核心配置文件中配置

调用sessionFactory里面的方法得到

//在hibernate.cfg.xml中配置,也就是Hibernate核心配置文件中。配置部位是在第二部分。

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

//其中,上面的值一共有三个,但是我们一般只用thread,即Session对象与本地线程进行绑定。

- thread:Session对象的生命周期与本地线程绑定
- jta:Session对象的生命周期与JTA事务绑定
- managed:Hibernate委托程序来管理Session对象的生命周期
1
2
3
4
5
6
7
8
9
10
11
[/code]

然后我们调用sessionFactory里面的方法得到:

但是我们一般是把获取本地线程session的代码放在utils中:

public class HibernateUtils {
private static SessionFactory sessionFactory=null;
static{
Configuration configuration=new Configuration();
configuration.configure();
sessionFactory=configuration.buildSessionFactory();
}
public static SessionFactory getSessionFactory(){
return sessionFactory;
}
public static Session getCurrentSession(){//在工具类里面获取与本地线程绑定的session。
return sessionFactory.getCurrentSession();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[/code]

@Test
public void showLocalSession(){
Transaction transaction=null;
Session session=null;

try {
session=HibernateUtils.getCurrentSession();

transaction=session.beginTransaction();

Book book=new Book("《ACM入门训练指南》", 99);

session.save(book);

transaction.commit();
} catch (Exception e) {
transaction.rollback();
}
}

//不知道各位朋友是否发现了,我在上面的演示中并没有写关闭session的代码。
//其实通过单元测试工具就会知道,当我们在finaly里面写上关闭session的操作会显示session已经关闭。
//因为我们这里的session是绑定了本地线程的session,当本地线程被关闭后,session也就自然而然的被关闭了。就像是同一根绳子上面的蚂蚱。这样也就不用我们去关闭session了。

注意:绑定了本地线程的session是不用我们自己去关闭的!!!如果我们的sesson是没有与本地线程绑定的,是通过sessionFactory.openSession()获取的,那么就要我们自己手动进行关闭。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
[/code]

如果在finaly中关闭session的结果:



<link rel="stylesheet" href="http://csdnimg.cn/release/phoenix/production/markdown_views-68a8aad09e.css">
<script>
$(".MathJax").remove();
</script>
<script type="text/javascript" src="//static.blog.csdn.net/mdeditor/public/res/bower-libs/MathJax/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
</div>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: