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

Hibernate对象详解

Hibernate对象含实体、代理、持久化等,实体映射表,代理懒加载,持久化由Session管理,快照助

Hibernate对象详解

Hibernate是一个基于Java的持久层框架,其核心目标是简化数据库操作,通过对象关系映射(ORM)将面向对象的编程模型与关系型数据库无缝衔接,在Hibernate中,对象的状态管理数据库交互逻辑是通过一系列核心对象实现的,以下是Hibernate对象体系的详细解析:


核心对象分类

对象类型 功能描述 生命周期
Session 核心操作对象,用于CRUD、事务管理、对象状态维护 短生命周期(与线程绑定)
SessionFactory Session工厂,负责创建Session实例,管理全局配置(如缓存、连接池) 长生命周期(应用启动到关闭)
Transaction 事务对象,绑定Session并管理数据库事务的边界 与Session绑定,随事务提交/回滚
Query/Criteria 查询接口,支持HQL、SQL及条件构造器 单次查询生命周期
Persistent Object 持久化对象,由Hibernate管理其与数据库的同步状态 依赖Session的存活周期

持久化对象(Persistent Object)

  1. 定义与特征
    持久化对象是通过session.save()session.update()session.get()方法加载的实体对象,其核心特征包括:

    • 与数据库记录一一映射:对象属性对应表字段,对象ID对应主键。
    • 状态自动同步:调用session.saveOrUpdate()时,Hibernate会自动检测并更新数据库。
    • 脏数据检查:通过快照(Snapshot)机制记录加载时的状态,避免重复更新。
  2. 对象状态转换
    | 状态 | 描述 |
    |——————|————————————————————————–|
    | 临时状态 | 新建对象未关联Session(如new User()) |
    | 持久化状态 | 对象被Session管理,与数据库记录关联(如session.save(user)后) |
    | 游离状态 | Session关闭后,对象失去持久化能力,但保留数据(需重新关联Session) |
    | 删除状态 | 对象被session.delete()标记,等待事务提交后从数据库移除 |

  3. 快照机制与脏数据检查
    Hibernate通过快照(Snapshot)记录对象加载时的数据库状态,当执行session.saveOrUpdate()时,会对比当前对象属性与快照差异,仅更新变化部分。

    User user = session.get(User.class, id); // 生成快照
    user.setName("newName"); // 修改属性
    session.saveOrUpdate(user); // 仅更新name字段

Session对象详解

  1. 核心功能

    • CRUD操作save()update()delete()get()load()
    • 事务管理:绑定Transaction对象,控制事务边界。
    • 查询执行:支持HQL、原生SQL及条件查询。
    • 缓存管理:维护一级缓存(Session级别)和二级缓存(全局共享)。
  2. 一级缓存机制
    Session的一级缓存是HashMap结构,存储当前Session加载的所有持久化对象。

    Hibernate对象详解  第1张

    User u1 = session.get(User.class, 1); // 缓存中存入u1
    User u2 = session.get(User.class, 1); // 直接从缓存获取

    特点

    • 默认开启,无需配置。
    • 生命周期与Session一致,Session关闭后缓存清空。
    • 避免频繁查询数据库,提升性能。
  3. 事务与Session绑定
    事务必须绑定到Session,示例:

    Transaction tx = session.beginTransaction();
    session.save(entity); // 操作受事务保护
    tx.commit(); // 提交事务并同步数据库

    注意:未提交事务时,操作仅存在于Session缓存中,不会同步到数据库。


SessionFactory与Configuration

  1. SessionFactory的作用

    • 重量级对象,应用中通常单例。
    • 配置读取(如hibernate.cfg.xml)、映射文件解析、连接池管理。
    • 示例代码:
      Services.start(Configuration.createConfiguration()); // 初始化ServiceRegistry
      SessionFactory factory = new Configuration().configure().buildSessionFactory();
  2. 线程安全性

    • SessionFactory线程安全,可被多个线程共享。
    • Session非线程安全,每个线程需独立获取。

查询对象(Query与Criteria)

  1. HQL查询

    • 面向对象语法,
      Query<User> query = session.createQuery("from User where name = :name", User.class);
      query.setParameter("name", "John");
      List<User> result = query.list();
    • 支持分页(query.setFirstResult(0).setMaxResults(10))。
  2. Criteria查询

    • 动态构建条件,适合复杂逻辑。
      CriteriaBuilder cb = session.getCriteriaBuilder();
      CriteriaQuery<User> cq = cb.createQuery(User.class);
      Root<User> root = cq.from(User.class);
      cq.select(root).where(cb.equal(root.get("name"), "John"));
      List<User> result = session.createQuery(cq).getResultList();
    • 优势:类型安全,避免字符串拼接错误。

集合与延迟加载

  1. 集合初始化策略
    | 策略 | 描述 |
    |——————|————————————————————————–|
    | 懒加载(Lazy) | 仅在访问集合时加载数据(默认行为) |
    | 急加载(Eager)| 加载主对象时立即加载关联集合 |
    | 批量加载(Batch) | 通过batch-size属性分批加载,减少SQL次数 |

  2. 延迟加载异常
    当Session关闭后访问懒加载集合时,会抛出LazyInitializationException,解决方案:

    • 提前初始化:Hibernate.initialize(collection);
    • 使用fetch="join"在HQL中急加载关联数据。

FAQs

Q1:Session与JDBC Connection的区别是什么?
A1:

  • Session:Hibernate核心对象,封装CRUD、事务、查询及缓存管理,操作面向对象。
  • Connection:JDBC原始连接,直接执行SQL,需手动管理资源和映射结果集。
    本质区别:Session隐藏了底层数据库操作,通过ORM实现对象与记录的透明转换。

Q2:如何避免“LazyInitializationException”?
A2:

  • 方案1:在事务内初始化集合,
    @Transactional
    public void process(User user) {
        Hibernate.initialize(user.getRoles()); // 显式初始化
    }
  • 方案2:配置集合为fetch=Join,在HQL查询时急加载关联数据。
  • 方案3:延长Session生命周期(如OpenSessionInView模式),但需谨慎防止
0