上一篇
Hibernate中Session增删改查操作
- 行业动态
- 2025-05-12
- 10
Hibernate中Session增删改查操作:增用save(),删用delete(),改用saveOrUpdate(),查靠HQ
Hibernate中Session的增删改查操作详解
Session基础概念
Hibernate的Session
是Java应用程序与数据库交互的核心接口,提供CRUD(创建、读取、更新、删除)操作的实现。Session
是非线程安全的,通常与一次数据库事务关联,以下是Session
的核心功能及对应操作:
操作类型 | 核心方法 | 事务支持 | 是否需要手动提交 |
---|---|---|---|
新增 | save() | 是 | 是 |
删除 | delete() | 是 | 是 |
修改 | update() /saveOrUpdate() | 是 | 是 |
查询 | get() /load() /HQL/Criteria | 可选 | 依赖操作类型 |
新增操作(Create)
基本流程
步骤:创建实体对象 → 配置
Session
→ 开启事务 → 调用save()
→ 提交事务 → 关闭Session
。代码示例:
// 创建实体对象 Student student = new Student(); student.setName("张三"); student.setAge(20); // 获取Session并开启事务 Session session = factory.openSession(); Transaction tx = session.beginTransaction(); // 保存对象(自动生成ID) session.save(student); tx.commit(); session.close();
关键点:
save()
方法会触发INSERT
语句。- 如果实体类使用
@GeneratedValue
注解,Hibernate自动生成主键。
ID生成策略
策略 | 适用场景 | 示例注解 |
---|---|---|
Native | 数据库自增字段(如MySQL) | @GenericGenerator(strategy="native") |
Sequence | Oracle序列 | @SequenceGenerator(name="seq",sequenceName="SEQ_STUDENT") |
Identity | SQL Server自增列 | @GenericGenerator(strategy="identity") |
UUID | 全局唯一标识符 | @GenericGenerator(strategy="uuid") |
删除操作(Delete)
按主键删除
代码示例:
Session session = factory.openSession(); Transaction tx = session.beginTransaction(); // 按主键删除(需先查询对象) Student student = session.get(Student.class, 1L); session.delete(student); // 直接删除(需实体类启用`@GenericGenerator`) session.delete(session.get(Student.class, 2L)); tx.commit(); session.close();
注意:
- 如果实体关联其他表,需配置
cascade
属性(如CascadeType.DELETE
)。
- 如果实体关联其他表,需配置
按条件删除(HQL)
- 代码示例:
Query query = session.createQuery("DELETE FROM Student WHERE age > :age"); query.setParameter("age", 30); int rows = query.executeUpdate(); // 执行删除
修改操作(Update)
流程与关键点
步骤:加载对象 → 修改属性 → 调用
update()
或saveOrUpdate()
→ 提交事务。代码示例:
Session session = factory.openSession(); Transaction tx = session.beginTransaction(); // 方式1:手动修改后更新 Student student = session.get(Student.class, 1L); student.setAge(21); session.update(student); // 方式2:直接调用(适用于脱管对象) Student newStudent = new Student(); newStudent.setId(1L); newStudent.setName("李四"); session.saveOrUpdate(newStudent); tx.commit(); session.close();
注意:
update()
仅更新持久化对象,saveOrUpdate()
可处理脱管对象。- Hibernate通过脏数据检查(Dirty Checking)自动检测变化。
级联更新
- 配置:在实体类中添加
@ManyToOne(cascade = CascadeType.ALL)
,修改主表时自动更新从表。
查询操作(Read)
主键查询
方法对比:
| 方法 | 是否懒加载 | 是否触发SQL | 推荐场景 |
|———–|————|————|——————–|
|get()
| 是 | 立即执行 | 存在则返回对象 |
|load()
| 是 | 延迟加载 | 不存在会抛异常 |
|find()
| 否 | 立即执行 | 自定义查询逻辑 |代码示例:
Student student1 = session.get(Student.class, 1L); // 立即查询 Student student2 = session.load(Student.class, 1L); // 延迟加载
HQL与Criteria查询
- HQL示例:
String hql = "FROM Student WHERE age > :age"; Query query = session.createQuery(hql); query.setParameter("age", 20); List<Student> results = query.list();
- Criteria示例:
CriteriaBuilder builder = session.getCriteriaBuilder(); CriteriaQuery<Student> query = builder.createQuery(Student.class); query.from(Student.class); query.where(builder.greaterThan("age", 20)); List<Student> results = session.createQuery(query).getResultList();
原生SQL查询
- 代码示例:
SQLQuery query = session.createSQLQuery("SELECT FROM student WHERE age > :age"); query.addEntity(Student.class); // 映射结果到实体 query.setParameter("age", 20); List<Student> results = query.list();
操作对比表格
操作类型 | 常用方法 | 事务要求 | ID处理 | 级联支持 | 是否立即触发SQL |
---|---|---|---|---|---|
新增 | save() | 是 | 自动生成/手动指定 | 是 | 是 |
删除 | delete() | 是 | 必须存在 | 依赖配置 | 是 |
修改 | update()/saveOrUpdate() | 是 | 必须存在 | 是 | 否(延迟到事务提交) |
查询 | get()/load()/HQL/Criteria | 可选 | 无 | 否 | 取决于方法 |
FAQs
Q1: Session
何时需要手动关闭?
- A:
Session
应在操作完成后显式关闭(如session.close()
),或通过try-finally
块确保资源释放,未关闭会导致数据库连接泄漏。
Q2: Hibernate如何检测脏数据?
- A: Hibernate通过快照比较机制检测属性变化,当
Session
提交时,会比较当前对象状态与持久化时快照,差异会生成UPDATE
语句,启用<property name="hibernate.show_sql" value="true"/>
可观察SQL日志