当前位置:首页 > 行业动态 > 正文

Hibernate中获取Session的两种方式代码示例

Hibernate获取Session的两种方式:①SessionFactory.openSession();②通过ContextualSession(如Spring整合时this.getSession(

通过SessionFactory.openSession()手动获取

核心特点

  • 非事务绑定:需手动管理事务和Session生命周期。
  • 灵活性高:适用于独立操作或非事务性场景。
  • 显式关闭:必须手动调用session.close()释放资源。

代码示例

// 1. 创建SessionFactory(通常作为单例)
Configuration config = new Configuration().configure(); // 读取hibernate.cfg.xml
SessionFactory sessionFactory = config.buildSessionFactory();
// 2. 获取Session
Session session = null;
Transaction transaction = null;
try {
    session = sessionFactory.openSession(); // 手动打开Session
    transaction = session.beginTransaction(); // 开启事务
    // 执行数据库操作(例如保存实体)
    session.save(entity);
    transaction.commit(); // 提交事务
} catch (Exception e) {
    if (transaction != null) {
        transaction.rollback(); // 回滚事务
    }
    e.printStackTrace();
} finally {
    if (session != null) {
        session.close(); // 必须手动关闭Session
    }
}

关键步骤解析

步骤 作用 注意事项
openSession() 创建新Session 每次调用返回独立Session,需显式关闭
beginTransaction() 开启事务 需在操作前开启,否则无法提交/回滚
commit() 提交事务 需在操作成功后调用
rollback() 回滚事务 在异常捕获时调用
close() 释放资源 必须放在finally块中防止泄漏

通过SessionFactory.getCurrentSession()绑定线程

核心特点

  • 事务绑定:需配置current_session_context_classthreadjta
  • 自动管理:Session生命周期与事务绑定,提交后自动关闭。
  • 线程安全:每个线程独享Session,适合Web应用。

代码示例

<!-hibernate.cfg.xml 配置 -->
<property name="hibernate.current_session_context_class">thread</property>
// 1. 创建SessionFactory(同上)
SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory();
// 2. 获取当前线程的Session
Session session = null;
Transaction transaction = null;
try {
    session = sessionFactory.getCurrentSession(); // 获取线程绑定的Session
    transaction = session.beginTransaction(); // 开启事务
    // 执行数据库操作(例如更新实体)
    session.update(entity);
    transaction.commit(); // 提交事务(Session自动关闭)
} catch (Exception e) {
    if (transaction != null) {
        transaction.rollback(); // 回滚事务
    }
    e.printStackTrace();
}

关键步骤解析

配置项 作用 注意事项
current_session_context_class 指定Session上下文 thread表示绑定到当前线程,jta用于容器事务
getCurrentSession() 获取线程绑定的Session 若未开启事务,可能抛出HibernateException
自动关闭 事务提交后自动关闭 无需显式调用close(),但需确保事务正常结束

两种方式对比表

特性 方式一(openSession) 方式二(getCurrentSession)
事务绑定 需配置current_session_context_class
Session生命周期 手动管理 自动与线程/事务绑定
资源释放 必须显式close() 事务提交后自动关闭
适用场景 独立操作、非事务性任务 Web应用、长事务操作
异常处理 需手动回滚 依赖容器或框架管理
线程安全 需手动控制 天然线程安全(每个线程独立Session)

注意事项

  1. 资源泄漏风险

    • 方式一中若忘记session.close(),可能导致数据库连接耗尽,建议使用try-with-resources(Java 7+)或始终在finally块中关闭。
    • 方式二需确保事务正常提交或回滚,否则Session可能不会自动关闭。
  2. 事务传播问题

    Hibernate中获取Session的两种方式代码示例  第1张

    • 方式二依赖外部事务管理(如Spring或JTA),若在无事务环境下调用getCurrentSession(),会抛出NonUniqueObjectException
  3. 性能优化

    • 方式一适合短生命周期操作,避免频繁创建Session。
    • 方式二在Web应用中可结合线程池复用Session,减少创建开销。

FAQs

问题1:为什么推荐在Web应用中使用getCurrentSession()

答:Web应用通常基于线程模型处理请求,getCurrentSession()能自动绑定Session到当前线程,避免手动传递Session对象,结合Spring等框架时,可利用事务管理器(如@Transactional)自动管理事务和Session生命周期,简化代码并提高安全性。

问题2:openSession()getCurrentSession()能否混合使用?

答:不建议混合使用,两者管理Session的机制不同,混合可能导致资源冲突或异常,若同一线程先调用openSession()再调用getCurrentSession(),可能创建多个Session实例,导致数据不一致或连接泄漏,建议根据项目需求统一选择一种

0