• 【Hibernate】Hibernate关联关系的映射


    一、实体之间的关系

    • 实体之间有三种关系:
    • 一对多:
      • 一个用户,生成多个订单,每一个订单只能属于一个用户.
      • 建表原则:
        • 在多的一方创建一个字段,作为外键,指向一的一方的主键.
    • 多对多:
      • 一个学生可以选择多门课程,一个课程可以被多个学生选择.
      • 建表原则:
      • 创建第三张表,中间表至少有两个字段,分别作为外键指向多对多双方主键.
    • 一对一:(特殊.最少.)
      • 一个公司只能有一个注册地址,一个注册地址,只能被一个公司使用.(否则将两个表建到一个表.)
      • 建表原则:
        • 唯一外键:
        • 一对一的双方,假设一方是多的关系.需要在多的一方创建一个字段,作为外键.指向一的一方的主键.但是在外键添加一个unique.
        • 主键对应:
        • 一对一的双方,通过主键进行关联.

    二、一对多的配置

    2.1 第一步创建两个实体

    /**
    * 客户实体 
    */
    public class Customer {
        private Integer cid;
        private String cname;
        // 一个客户有多个订单.
        private Set<Order> orders = new HashSet<Order>();
        public Integer getCid() {
            return cid;
        }
        public void setCid(Integer cid) {
            this.cid = cid;
        }
        public String getCname() {
            return cname;
        }
        public void setCname(String cname) {
            this.cname = cname;
        }
        public Set<Order> getOrders() {
            return orders;
        }
        public void setOrders(Set<Order> orders) {
            this.orders = orders;
        }
        
    }
    
    //订单实体
    public class Order {
        private Integer oid;
        private String addr;
        // 订单属于某一个客户.放置一个客户的对象.
        private Customer customer;
        public Integer getOid() {
            return oid;
        }
        public void setOid(Integer oid) {
            this.oid = oid;
        }
        public String getAddr() {
            return addr;
        }
        public void setAddr(String addr) {
            this.addr = addr;
        }
        public Customer getCustomer() {
            return customer;
        }
        public void setCustomer(Customer customer) {
            this.customer = customer;
        }   
    }
    

    2.2 第二步:配置映射文件

    • Customer.hbm.xml
     <hibernate-mapping>
            <class name="com.hao.hibernate.demo2.Customer" table="customer">
                <!-- 配置唯一标识 -->
                <id name="cid" column="cid">
                    <generator class="native"/>
                </id>
                <!-- 配置普通属性 -->
                <property name="cname" column="cname" length="20"/>
                
                <!-- 建立映射 -->
                <!-- 配置一个集合 <set>的name Customer对象中的关联对象的属性名称. -->
                <set name="orders">
                    <!-- <key>标签中column:用来描述一对多多的一方的外键的名称. -->
                    <key column="cno"></key>
                    <!-- 配置一个<one-to-many>标签中class属性:订单的类的全路径 -->
                    <one-to-many class="com.hao.hibernate.demo2.Order"/>
                </set>
            </class>
        </hibernate-mapping>
    
    
    • Order.hbm.xml
    <hibernate-mapping>
        <class name="com.hao.hibernate.demo2.Order" table="orders">
            <!-- 配置唯一标识  -->
            <id name="oid" column="oid">
                <generator class="native"/>
            </id>
            <!-- 配置普通属性 -->
            <property name="addr" column="addr" length="50"/>
            <!-- 配置映射 -->
            <!-- 
            <many-to-one>标签
                name    :关联对象的属性的名称.
                column  :表中的外键名称.
                class   :关联对象类的全路径
            -->
            <many-to-one name="customer" column="cno" class="com.hao.hibernate.demo2.Customer"/>
        </class>
    </hibernate-mapping>
     
    

    2.3 第三步:将映射放到核心配置文件中

    三、级联

    3.1 Hibernate中级联保存的效果

    • 级联:操作当前对象的时候,关联的对象如何处理.
    • cascade=”save-update”
    • 级联方向性:
      • 保存客户的时候,选择级联订单.
      • 保存订单的时候,选择级联客户.

    3.2 Hibernate中级联删除的效果

    • cascade=”delete”

    3.3 Hibernate中的级联取值

    • none : 不使用级联
    • dave-update : 保存或更新的时候级联
    • delete : 删除的时候级联
    • all : 除了孤儿删除以外的所有级联.
    • delete-orphan : 孤儿删除(孤子删除).
    • 孤儿删除:仅限于一对多.只有一对多时候,才有父子存在.认为一的一方是父亲,多的一方是子方.当一个客户与某个订单解除了关系.将外键置为null.订单没有了所属客户,相当于一个孩子没有了父亲.将这种记录就删除了.
    • all-delete-orphan :包含了孤儿删除的所有的级联.

    3.4 双向维护产生多余的SQL

    • 配置inverse=”true”:在哪一端配置.那么哪一端放弃了外键的维护权.一般情况下,一的一方去放弃.
    • cascade:操作关联对象.
    • inverse:控制外键的维护.

    四、Hibernate的多对多的配置

    4.1 第一步:创建实体类

    // 学生的实体:
    public class Student {
        private Integer sid;
        private String sname;
        // 一个学生选择多门课程:
        private Set<Course> courses = new HashSet<Course>();
        public Integer getSid() {
            return sid;
        }
        public void setSid(Integer sid) {
            this.sid = sid;
        }
        public String getSname() {
            return sname;
        }
        public void setSname(String sname) {
            this.sname = sname;
        }
        public Set<Course> getCourses() {
            return courses;
        }
        public void setCourses(Set<Course> courses) {
            this.courses = courses;
        }
        
    }
    
    
    //课程的实体:
    public class Course {
        private Integer cid;
        private String cname;
        // 一个课程被多个学生选择:
        private Set<Student> students = new HashSet<Student>();
        public Integer getCid() {
            return cid;
        }
        public void setCid(Integer cid) {
            this.cid = cid;
        }
        public String getCname() {
            return cname;
        }
        public void setCname(String cname) {
            this.cname = cname;
        }
        public Set<Student> getStudents() {
            return students;
        }
        public void setStudents(Set<Student> students) {
            this.students = students;
        }
        
    }
    

    4.2 第二步建立映射

    • Student.hbm.xml
    <hibernate-mapping>
        <class name="com.hao.hibernate.demo3.Student" table="student">
            <!-- 配置唯一标识 -->
            <id name="sid" column="sid">
                <generator class="native"/>
            </id>
            <!-- 配置普通属性 -->
            <property name="sname" column="sname" length="20"/>
            
            <!-- 配置关联映射 -->
            <!-- <set>标签 name:对应学生中的课程集合的名称   table:中间表名称. -->
            <set name="courses" table="stu_cour">
                <!-- <key>中column写 当前类在中间表的外键.-->
                <key column="sno"></key>
                <!-- <many-to-many>中class:另一方类的全路径. column:另一方在中间表中外键名称-->
                <many-to-many class="com.hao.hibernate.demo3.Course" column="cno"/>
            </set>
        </class>
    </hibernate-mapping>
    
    • Course.hbm.xml
    <hibernate-mapping>
        <class name="com.hao.hibernate.demo3.Course" table="course">
            <!-- 配置唯一标识 -->
            <id name="cid" column="cid">
                <generator class="native"/>
            </id>
            <!-- 配置普通属性 -->
            <property name="cname" column="cname" length="20"/>
            <!-- 配置与学生关联映射 -->
            <!-- <set>中name:对应当前类中的学生的集合的名称  table:中间表的名称-->
            <set name="students" table="stu_cour">
                <!-- <key>中column:当前类在中间表中外键 -->
                <key column="cno"></key>
                <!-- <many-to-many>中class:另一方的类全路径. column:另一方在中间表中外键名称 -->
                <many-to-many class="com.hao.hibernate.demo3.Student" column="sno"/>
            </set>
        </class>
    </hibernate-mapping>
    
    
    

    4.3 第三步:将映射文件加入到核心配置文件中

  • 相关阅读:
    EMV内核使用中的常见问题
    SM2国密证书合法性验证
    WP8.1中C++的winodws运行时组件位移操作的差异
    [源码]Literacy 快速反射读写对象属性,字段
    Vue 单文件元件 — vTabs
    vue-router路径计算问题
    前端跨域新方案尝试
    Vue 单文件原件 — vCheckBox
    JavaScript 功能类 Url.js
    Vue 学习笔记 — 组件初始化
  • 原文地址:https://www.cnblogs.com/haoworld/p/hibernatehibernate-guan-lian-guan-xi-de-ying-she.html
Copyright © 2020-2023  润新知