Hibernate(28)Hibernate的级联操作是什么?

Hibernate的级联操作

级联操作(Cascade Operations)是Hibernate提供的一种机制,通过它可以在父实体上执行操作时,自动对其关联的子实体执行相应的操作。这样可以简化代码,避免手动管理关联实体的状态。

级联操作的主要类型包括:

  • CascadeType.PERSIST:在保存(persist)父实体时,自动保存关联的子实体。
  • CascadeType.MERGE:在合并(merge)父实体时,自动合并关联的子实体。
  • CascadeType.REMOVE:在删除(remove)父实体时,自动删除关联的子实体。
  • CascadeType.DETACH:在分离(detach)父实体时,自动分离关联的子实体。
  • CascadeType.REFRESH:在刷新(refresh)父实体时,自动刷新关联的子实体。
  • CascadeType.ALL:包括以上所有级联操作。

示例代码

配置文件 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.Person"/>
        <mapping class="com.example.domain.Address"/>
    </session-factory>
</hibernate-configuration>

实体类 PersonAddress

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

import javax.persistence.*;
import java.util.HashSet;
import java.util.Set;

@Entity
@Table(name = "person")
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "name")
    private String name;

    @Column(name = "age")
    private int age;

    @OneToMany(mappedBy = "person", cascade = CascadeType.ALL, orphanRemoval = true)
    private Set<Address> addresses = new HashSet<>();

    public Person() {}

    public Person(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;
    }

    public Set<Address> getAddresses() {
        return addresses;
    }

    public void setAddresses(Set<Address> addresses) {
        this.addresses = addresses;
    }

    public void addAddress(Address address) {
        addresses.add(address);
        address.setPerson(this);
    }

    public void removeAddress(Address address) {
        addresses.remove(address);
        address.setPerson(null);
    }
}
Address类
java 复制代码
package com.example.domain;

import javax.persistence.*;

@Entity
@Table(name = "address")
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @Column(name = "street")
    private String street;

    @ManyToOne
    @JoinColumn(name = "person_id", nullable = false)
    private Person person;

    public Address() {}

    public Address(String street, Person person) {
        this.street = street;
        this.person = person;
    }

    // Getters 和 Setters
    
    public Long getId() {
        return id;
    }

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

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }
}

级联操作示例

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;
    }
}

级联保存示例

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

public class HibernateCascadeSaveExample {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // 插入数据
        insertPersonWithAddresses(sessionFactory);

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

    private static void insertPersonWithAddresses(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            Person person = new Person("John Doe", 30);
            Address address1 = new Address("123 Street", person);
            Address address2 = new Address("456 Avenue", person);

            person.addAddress(address1);
            person.addAddress(address2);

            // 保存Person对象时,级联保存Address对象
            session.save(person);
            transaction.commit();
            System.out.println("Inserted Person with Addresses");
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

级联删除示例

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

public class HibernateCascadeDeleteExample {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // 删除数据
        deletePersonWithAddresses(sessionFactory);

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

    private static void deletePersonWithAddresses(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            // 获取Person对象
            Person person = session.get(Person.class, 1L);
            if (person != null) {
                // 删除Person对象时,级联删除Address对象
                session.delete(person);
                transaction.commit();
                System.out.println("Deleted Person with Addresses");
            } else {
                System.out.println("No Person found with ID 1");
            }
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

级联更新示例

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

public class HibernateCascadeUpdateExample {
    public static void main(String[] args) {
        // 获取SessionFactory
        SessionFactory sessionFactory = HibernateUtil.getSessionFactory();

        // 更新数据
        updatePersonWithAddresses(sessionFactory);

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

    private static void updatePersonWithAddresses(SessionFactory sessionFactory) {
        Session session = sessionFactory.openSession();
        Transaction transaction = session.beginTransaction();
        try {
            // 获取Person对象
            Person person = session.get(Person.class, 1L);
            if (person != null) {
                // 更新Person对象
                person.setName("Jane Doe");
                person.setAge(35);

                // 级联更新Address对象
                for (Address address : person.getAddresses()) {
                    address.setStreet(address.getStreet() + " Updated");
                }

                session.update(person);
                transaction.commit();
                System.out.println("Updated Person with Addresses");
            } else {
                System.out.println("No Person found with ID 1");
            }
        } catch (Exception e) {
            if (transaction != null) {
                transaction.rollback();
            }
            e.printStackTrace();
        } finally {
            if (session != null) {
                session.close();
            }
        }
    }
}

级联操作的详细解释

  1. 配置文件 hibernate.cfg.xml:定义数据库连接信息、Hibernate属性配置以及实体类映射配置。

    xml 复制代码
    <mapping class="com.example.domain.Person"/>
    <mapping class="com.example.domain.Address"/>
  2. 实体类 PersonAddress

相关推荐
Victor3563 小时前
Hibernate(29)什么是Hibernate的连接池?
后端
Victor3563 小时前
Hibernate(30)Hibernate的Named Query是什么?
后端
源代码•宸3 小时前
GoLang八股(Go语言基础)
开发语言·后端·golang·map·defer·recover·panic
czlczl200209253 小时前
OAuth 2.0 解析:后端开发者视角的原理与流程讲解
java·spring boot·后端
颜淡慕潇3 小时前
Spring Boot 3.3.x、3.4.x、3.5.x 深度对比与演进分析
java·后端·架构
布列瑟农的星空3 小时前
WebAssembly入门(一)——Emscripten
前端·后端
小突突突5 小时前
Spring框架中的单例bean是线程安全的吗?
java·后端·spring
iso少年5 小时前
Go 语言并发编程核心与用法
开发语言·后端·golang
掘金码甲哥5 小时前
云原生算力平台的架构解读
后端
码事漫谈5 小时前
智谱AI从清华实验室到“全球大模型第一股”的六年征程
后端