#管理session

hibernate 自身提供了三种管理session对象的方法

  • sesion对象的生命周期与本地线程绑定
  • sesion对象的生命周期与JTA事务绑定
  • hibernate委托程序管理session对象的生命周期

在hibernate的配置文件中
hibernate.current_session_context_class 属性用于指定session管理方式,可选择的值有:

  • thread , session对象生命周期与本地线程绑定
  • jta* , session对象生命周期与JTA事务绑定
  • managed:,hibernate委托程序来管理session。

下面来个模拟操作示例代码

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
package com.mamh.hibernate.dao;

import com.mamh.hibernate.hql.entities.Department;
import com.mamh.hibernate.utils.HibernateUtils;
import org.hibernate.Session;

public class DepartmentDao {//
private Session session;

/**
* 这里session不能通过参数传来了,就需要类内部获取
*
* <p>
* hibernate 自身提供了三种管理session对象的方法
* sesion对象的生命周期与本地线程绑定
* sesion对象的生命周期与JTA事务绑定
* hibernate委托程序管理session对象的生命周期
* <p>
* 在hibernate的配置文件中
* hibernate.current_session_context_class 属性用于指定session管理方式,可选择的值有:
* thread , session对象生命周期与本地线程绑定
* jta* , session对象生命周期与JTA事务绑定
* managed:,hibernate委托程序来管理session。
*
* @param department
*/
public void save(Department department) {
//获取和当前线程绑定的session对象
//不需要从外部传入session对象
//多个dao方法也可以使用一个事务
Session session = HibernateUtils.getInstance().getSession();
System.out.println("session hashcode = " + session.hashCode());
//session.save(department);

}


/**
* 这里传入一个session对象,则意味着上一层(service)需要获取到session对象,
* 这说明上一层需要和hibernate的api紧密耦合,所以不推荐这种方式。
*
* @param session
* @param department
*/
public void save(Session session, Department department) {

}
}


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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

package com.mamh.hibernate.utils;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.ServiceRegistryBuilder;

public class HibernateUtils {//
private static HibernateUtils instance = new HibernateUtils();
private static SessionFactory sessionFactory;

private HibernateUtils() {

}


public static HibernateUtils getInstance() {
return instance;
}


public SessionFactory getSessionFactory() {
if (sessionFactory == null) {//
//1.创建一个SessionFactory 对象,创建session的工厂的一个类
//1.1创建一个Configuration对象,对应hibernate的基本配置信息和对象关系映射信息
Configuration configuration = new Configuration().configure();
//1.2创建一个ServiceRegistry对象,hibernate4.x新添加的对象,hibernate任何的配置和服务都要在该对象中注册才能有效。
ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().
applySettings(configuration.getProperties()).buildServiceRegistry();
//1.3
sessionFactory = configuration.buildSessionFactory(serviceRegistry);
}

return sessionFactory;
}


public Session getSession() {//
return getSessionFactory().getCurrentSession();
}


}


测试方法

1
2
3
4
5
6
7
8
9
10
11
12

@Test
public void testSessonManage(){//
DepartmentDao departmentDao = new DepartmentDao();

com.mamh.hibernate.hql.entities.Department department = null;
departmentDao.save(department);
departmentDao.save(department);
departmentDao.save(department);
departmentDao.save(department);
}

hibernate.cfg.xml 文件中添加下面配置属性

1
2
<property name="current_session_context_class">thread</property>

1
2
3
4
5
6
7
8

session hashcode = 1110195322
session hashcode = 1110195322
session hashcode = 1110195322
session hashcode = 1110195322
=destroy=


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

@Test
public void testSessonManage(){//
Session session = HibernateUtils.getInstance().getSession();
System.out.println("---->"+session.hashCode());
Transaction transaction = session.beginTransaction();

DepartmentDao departmentDao = new DepartmentDao();
com.mamh.hibernate.hql.entities.Department department = null;
department = new com.mamh.hibernate.hql.entities.Department();
department.setName("");

departmentDao.save(department);
departmentDao.save(department);
departmentDao.save(department);
departmentDao.save(department);

transaction.commit();//

System.out.println("-----> session is open ? "+session.isOpen());
}

1
2
3
4
5
6
---->1110195322
session hashcode = 1110195322
session hashcode = 1110195322
session hashcode = 1110195322
session hashcode = 1110195322
-----> session is open ? false

若session是由thread管理的,在提交或回滚事务时,已经关闭session了。

#批量处理数据

  • 通过session,session会有缓存,容易把缓存撑爆
  • 通过HQL
  • 通过statelessSession,无状态的session,这个没有缓存,
  • 通过 JDBC API ,推荐这种方式
1
2
3
4
5
6
7
8
9
10
11
12
13

@Test
public void testBatch(){//
//批量操作
session.doWork(new Work() {
public void execute(Connection connection) throws SQLException {
//通过jdbc的原生api来操作,效率最高,速度最快
}
});


}