上一篇
Hibernate中Session增删改查操作代码详解
- 行业动态
- 2025-05-12
- 6
Session通过save()/update()/delete()实现数据操作,需配合事务管理(begin/commit),查询使用get()/load()/createQuery(),操作后应关闭Session释放资源。(43字
Hibernate中Session增删改查操作代码详解
Session核心操作
Hibernate的Session
接口是应用程序与数据库交互的核心通道,提供CRUD(创建、读取、更新、删除)操作的实现,以下通过代码示例详解Session的四大核心操作,并对比不同方法的使用场景。
Session增删改查代码详解
增(Save)操作
场景:将新实体持久化到数据库
关键方法:session.save(entity)
代码示例:
// 1. 获取SessionFactory SessionFactory sessionFactory = new Configuration().configure().buildSessionFactory(); // 2. 打开Session Session session = sessionFactory.openSession(); session.beginTransaction(); // 开启事务 // 3. 创建实体对象 User user = new User(); user.setId(null); // 主键未设置,由数据库生成 user.setName("张三"); user.setAge(25); // 4. 保存实体 session.save(user); // 生成INSERT语句 // 5. 提交事务并关闭Session session.getTransaction().commit(); session.close();
删(Delete)操作
场景:根据主键或条件删除数据
关键方法:session.delete(entity)
代码示例:
Session session = sessionFactory.openSession(); session.beginTransaction(); // 方式1:按主键删除(需先查询) User user = session.get(User.class, 1); // 生成SELECT语句 session.delete(user); // 生成DELETE语句(需存在关联) // 方式2:直接删除(需实体为持久化状态) User user2 = new User(); user2.setId(2); session.delete(user2); // 直接DELETE,不检查是否存在 session.getTransaction().commit(); session.close();
改(Update)操作
场景:修改持久化对象的字段值
关键方法:session.update(entity)
或 session.saveOrUpdate(entity)
代码示例:
Session session = sessionFactory.openSession(); session.beginTransaction(); // 1. 查询已持久化对象 User user = session.get(User.class, 1); // 生成SELECT语句 user.setAge(26); // 修改属性值 // 2. 更新实体(自动检测变化) session.update(user); // 生成UPDATE语句(需手动调用) // 或使用saveOrUpdate(推荐) session.saveOrUpdate(user); // 自动判断新增或更新 session.getTransaction().commit(); session.close();
查(Query)操作
场景:从数据库加载数据到内存
关键方法:session.get()
、session.load()
、HQL、Criteria
代码示例:
Session session = sessionFactory.openSession(); // 方式1:按主键查询(立即加载) User user1 = session.get(User.class, 1); // 生成SELECT语句,null时返回null // 方式2:按主键查询(延迟加载) User user2 = session.load(User.class, 2); // 生成SELECT语句,找不到抛ObjectNotFoundException // 方式3:HQL查询 Query<User> query = session.createQuery("FROM User WHERE age > :age", User.class); query.setParameter("age", 20); List<User> users = query.list(); // 生成SELECT语句 // 方式4:Criteria查询(动态条件) CriteriaBuilder cb = session.getCriteriaBuilder(); CriteriaQuery<User> cq = cb.createQuery(User.class); cq.where(cb.equal(cq.from(User.class).get("name"), "张三")); List<User> result = session.createQuery(cq).getResultList(); session.close();
Session操作对比表
操作类型 | 方法名 | 适用场景 | 是否需要事务 | 是否立即访问数据库 |
---|---|---|---|---|
新增 | save() | 保存新实体 | 是 | 立即执行INSERT |
删除 | delete() | 删除持久化对象 | 是 | 立即执行DELETE |
更新 | update() | 更新脱管对象(需先查询) | 是 | 立即执行UPDATE |
saveOrUpdate() | 自动判断新增或更新 | 是 | 根据状态决定 | |
查询 | get() | 按主键立即加载 | 可选 | 立即执行SELECT |
load() | 按主键延迟加载 | 可选 | 延迟访问数据库 | |
HQL/Criteria | 复杂条件查询 | 可选 | 立即执行SELECT |
常见问题与注意事项
Session与数据库连接的关系
- 每个
Session
对应一个数据库连接,需及时关闭避免资源泄漏。 - 建议使用
try-with-resources
或finally
块确保session.close()
。
- 每个
事务边界与数据一致性
- CRUD操作需在事务内执行,否则可能无法提交。
session.flush()
可强制同步缓存到数据库,但通常由事务自动处理。
级联操作与懒加载
load()
方法仅加载代理对象,访问属性时才触发SQL。- 若实体关联其他对象(如
Set
),需配置级联类型(如CascadeType.ALL
)。
FAQs(常见问题解答)
Q1:Session的save()
和persist()
有什么区别?
A1:save()
将对象转为持久化状态并返回数据库生成的主键,而persist()
仅保证对象被持久化,不返回主键,若需立即获取主键,应使用save()
。
Q2:为什么session.load()
可能抛出ObjectNotFoundException
?
A2:load()
方法使用延迟加载策略,仅生成代理对象,当实际访问对象属性或集合时,若数据库无对应记录,会抛出此异常,建议对不确定存在的数据使用get()