管理session
- 如果把 Hibernate 配置文件的 hibernate.current_session_context_class 属性值设为 thread, Hibernate 就会按照与本地线程绑定的方式来管理 Session
<!-- 配置管理session的方式 -->
<property name="current_session_context_class">thread</property>
session和线程绑定的流程过程
当一个线程(threadA)第一次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会创建一个新的 Session(sessionA) 对象, 把该对象与 threadA 绑定, 并将 sessionA 返回
当 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法将返回 sessionA 对象
- 当 threadA 提交 sessionA 对象关联的事务时, Hibernate 会自动flush sessionA 对象的缓存, 然后提交事务, 关闭 sessionA 对象. 当 threadA 撤销 sessionA 对象关联的事务时, 也会自动关闭 sessionA 对象
- 若 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会又创建一个新的 Session(sessionB) 对象, 把该对象与 threadA 绑定, 并将 sessionB 返回
代码演示
1.获取session的工具类
public class HibernateUtils {
private HibernateUtils() {};
private static HibernateUtils instance = new HibernateUtils();
public static HibernateUtils getUibernateUtils() {
return instance;
}
private SessionFactory factory;
public SessionFactory getSessionFactory() {
if (factory == null) {
final StandardServiceRegistry registry = new StandardServiceRegistryBuilder()
.configure("/hibernate.cfg.xml").build();
factory = new MetadataSources(registry).buildMetadata().buildSessionFactory();
}
return factory;
}
public Session getSession() {
//获取和当前线程绑定的session
return getSessionFactory().getCurrentSession();
}
}
2.dao类
public class DepartmentDao {
public void save(Department dept) {
//1. 内部获取session对象
//2. 获取和当前线程绑定的session对象
//3. 不需要从外部传入session对象(外部不需要和session有任何关系)
//4. 多个dao方法也可以使用一个事务
Session session = HibernateUtils.getUibernateUtils().getSession();
System.out.println(session.hashCode());
}
/*
* 不推荐使用这种方式进行保存:
* 1. 需要从service层传入一个session对象
* 2. service层需要和hibernate的 API 紧密的结合在一起了
*/
public void save(Session session, Department dept) {
session.save(dept);
}
}
3.测试
// junit 不支持多线程,先用主方法来进行设置
public static void main(String[] args) {
// 获取session
// 开启事务
Session session2 = HibernateUtils.getUibernateUtils().getSession();
System.out.println("-------" + session2.hashCode());
Transaction transaction = session2.beginTransaction();
DepartmentDao departmentDao = new DepartmentDao();
departmentDao.save(null);
departmentDao.save(null);
departmentDao.save(null);
//若session是由thread来管理的,那么当事务提交或者回滚的时候,session就已经关闭了
transaction.commit();
System.out.println(session2.isOpen());
}
console:
hibernate中的批处理
- 对于批处理,只建议使用jdbc原生方式操作
- 代码:
/*
* 批处理,只建议使用jdbc原生的批处理方式,效率最高
*/
@Test
void testBatch() {
session.doWork(new Work() {
@Override
public void execute(Connection connection) throws SQLException {
//批处理方式1(好处自己看)
// String sql = "update GG_DEPARTMENT set name='福利部' where id = 10";
// String sql2 = "insert into GG_DEPARTMENT(id,name) values (110,'前台部')";
//
// Statement st = connection.createStatement();
// st.addBatch(sql);
// st.addBatch(sql2);
// st.executeBatch();
// st.clearBatch();
//批处理方式2(好处自己看代码)
String sql = "update GG_DEPARTMENT SET name='什么部' where id = ?";
PreparedStatement ps = connection.prepareStatement(sql);
for(int i = 10;i<30;i+=10) {
ps.setInt(1, i);
ps.addBatch();
}
ps.executeBatch();
}
});
}