Hibernate学习之路(十五):hibernate中管理session和批处理

管理session
  • 如果把 Hibernate 配置文件的 hibernate.current_session_context_class 属性值设为 thread, Hibernate 就会按照与本地线程绑定的方式来管理 Session
<!-- 配置管理session的方式 -->
        <property name="current_session_context_class">thread</property>
  • session和线程绑定的流程过程

    1. 当一个线程(threadA)第一次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法会创建一个新的 Session(sessionA) 对象, 把该对象与 threadA 绑定, 并将 sessionA 返回

    2. 当 threadA 再次调用 SessionFactory 对象的 getCurrentSession() 方法时, 该方法将返回 sessionA 对象

    3. 当 threadA 提交 sessionA 对象关联的事务时, Hibernate 会自动flush sessionA 对象的缓存, 然后提交事务, 关闭 sessionA 对象. 当 threadA 撤销 sessionA 对象关联的事务时, 也会自动关闭 sessionA 对象
    4. 若 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:

mark

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();
            }
        });

    }

点我获取源代码

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值