Hibernate(11)什么是Hibernate的持久化上下文?

Hibernate的持久化上下文(Persistence Context)是一个非常重要的概念,它指的是一个特定的Session对象管理的持久化实体的集合。持久化上下文负责管理实体的生命周期、缓存实体,并提供事务性处理。持久化上下文的主要作用包括:

  1. 实体管理:管理对象的持久化状态,包括新建、删除、更新等操作。
  2. 一级缓存:Session的一级缓存,用于在数据库查询中缓存实体,减少数据库访问次数,提高性能。
  3. 事务性操作:在事务的范围内保持持久化上下文的一致性。
  4. 脏检查:在事务提交时,自动检测并同步持久化对象的状态变化到数据库。

示例项目结构

为了深入理解持久化上下文,下面是一个完整的示例,包括如何配置Hibernate、定义实体类、管理Session,以及演示持久化上下文的行为。

配置文件 hibernate.cfg.xml

xml 复制代码
<!DOCTYPE hibernate-configuration PUBLIC
        "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
        "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
    <session-factory>
        <!-- 数据库连接配置 -->
        <property name="hibernate.connection.driver_class">com.mysql.cj.jdbc.Driver</property>
        <property name="hibernate.connection.url">jdbc:mysql://localhost:3306/your_database</property>
        <property name="hibernate.connection.username">your_username</property>
        <property name="hibernate.connection.password">your_password</property>

        <!-- Hibernate 属性配置 -->
        <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
        <property name="hibernate.show_sql">true</property>
        <property name="hibernate.format_sql">true</property>
        <property name="hibernate.hbm2ddl.auto">update</property>

        <!-- 映射类配置 -->
        <mapping class="com.example.domain.Student"/>
    </session-factory>
</hibernate-configuration>

HibernateUtil 类

java 复制代码
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class HibernateUtil {
    private static final SessionFactory sessionFactory;

    static {
        try {
            // 从配置文件创建SessionFactory
            sessionFactory = new Configuration().configure("hibernate.cfg.xml").buildSessionFactory();
        } catch (Throwable ex) {
            // 记录启动失败的错误
            System.err.println("Initial SessionFactory creation failed." + ex);
            throw new ExceptionInInitializerError(ex);
        }
    }

    public static SessionFactory getSessionFactory() {
        return sessionFactory;
    }
}

实体类 Student

java 复制代码
package com.example.domain;

public class Student {
    private Long id;
    private String name;
    private int age;

    public Student() {}

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // getters 和 setters
    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}

持久化上下文示例

下面的示例展示了持久化上下文的基本行为,包括实体的持久化、缓存管理以及事务性同步。

java 复制代码
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;

public class HibernatePersistenceContextExample {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();
        
        // 打开一个新的Session
        Session session = sessionFactory.openSession();
        Transaction transaction = null;

        try {
            // 启动事务
            transaction = session.beginTransaction();

            // 创建并保存一个新的Student对象
            Student student = new Student("John Doe", 20);
            session.save(student);

            // 持久化上下文中的student对象现在是持久化状态
            student.setAge(21); // 修改对象的属性

            // 提交事务
            transaction.commit();
            // 到这里,student对象的状态已经同步到数据库
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close(); // 关闭Session
        }

        // 重新打开一个新的Session
        session = sessionFactory.openSession();
        try {
            // 启动事务
            transaction = session.beginTransaction();

            // 从数据库加载Student对象
            Student student = session.get(Student.class, 1L);
            System.out.println("Student: " + student.getName() + ", Age: " + student.getAge());

            // 提交事务
            transaction.commit();
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            session.close(); // 关闭Session
        }

        // 关闭SessionFactory
        sessionFactory.close();
    }
}

详细解释

  1. 持久化上下文 :当调用session.save(student)时,student对象进入持久化上下文,成为持久化状态。任何对该对象的修改都会在事务提交时自动同步到数据库。

  2. 一级缓存 :在单个Session范围内,Hibernate维护一级缓存。第一次查询某个实体后,它会被缓存到Session中,随后对该实体的访问会直接从缓存中获取,而不再访问数据库。

  3. 脏检查:在事务提交时,Hibernate会检查持久化上下文中的实体,找出已更改但未同步到数据库的实体,并自动执行相应的SQL更新操作。

持久化上下文的生命周期

  • Transient(瞬态):对象在未与Session关联之前处于瞬态状态。
  • Persistent(持久态) :对象一旦通过Sessionsaveupdatemerge等方法与持久化上下文关联,就进入持久态。
  • Detached(游离态)Session关闭后,持久化上下文也就不存在了,之前关联的对象变为游离态对象。

事务性操作

  • session.beginTransaction():开启一个新的事务。
  • transaction.commit():提交事务,持久化上下文中的变化同步到数据库。
  • transaction.rollback():回滚事务,撤销未提交的更改。

一级缓存的作用

一级缓存由当前Session实例维护,确保在同一个Session中,重复查询相同的实体不会多次访问数据库,提高了性能。

总结

持久化上下文是Hibernate的核心机制之一,它通过管理实体的生命周期和提供一级缓存,实现了对持久化对象的高效管理。理解持久化上下文的工作原理,对于使用Hibernate进行高效的数据访问和管理具有重要意义。通过实际的代码示例,可以看到持久化上下文如何在事务范围内管理实体的状态变化,并自动同步到数据库。

相关推荐
源代码•宸2 小时前
Leetcode—3. 无重复字符的最长子串【中等】
经验分享·后端·算法·leetcode·面试·golang·string
0和1的舞者3 小时前
基于Spring的论坛系统-前置知识
java·后端·spring·系统·开发·知识
invicinble4 小时前
对于springboot
java·spring boot·后端
码界奇点4 小时前
基于Spring Boot与Vue的校园后台管理系统设计与实现
vue.js·spring boot·后端·毕业设计·源代码管理
爱编程的小庄4 小时前
Rust 发行版本及工具介绍
开发语言·后端·rust
Apifox.6 小时前
测试用例越堆越多?用 Apifox 测试套件让自动化回归更易维护
运维·前端·后端·测试工具·单元测试·自动化·测试用例
sunnyday04266 小时前
Nginx与Spring Cloud Gateway QPS统计全攻略
java·spring boot·后端·nginx
康王有点困6 小时前
Link入门
后端·flink
海南java第二人6 小时前
Spring Boot全局异常处理终极指南:打造优雅的API错误响应体系
java·spring boot·后端
小楼v7 小时前
消息队列的核心概念与应用(RabbitMQ快速入门)
java·后端·消息队列·rabbitmq·死信队列·交换机·安装步骤