Hibernate 一對多操作

一 表與表之間關(guān)系回顧

  • 一對多
  • 多對多
  • 一對一

二 hibernate一對多操作
1 一對多映射配置
以客戶聯(lián)系人為列:客戶是一,聯(lián)系人是多
(1)創(chuàng)建兩個實體類,一個客戶,一個聯(lián)系人 
Customer.java

package entity;

import java.util.HashSet;
import java.util.Set;

public class Customer {
    private Integer cid;
    private String custName;
    private String custLevel;
    private String custSource;
    private String custPhone;
    private String custMobile;
    // 在客戶類里面表示多個聯(lián)系人,一個客戶有多個聯(lián)系人
    //在hibernate要求使用集合表示多的數(shù)據(jù),使用set集合
    private Set<LinkMan>  setlinkMan = new HashSet<LinkMan>();

    public Set<LinkMan> getSetlinkMan() {
        return setlinkMan;
    }

    public void setSetlinkMan(Set<LinkMan> setlinkMan) {
        this.setlinkMan = setlinkMan;
    }

    public Integer getCid() {
        return cid;
    }

    public void setCid(Integer cid) {
        this.cid = cid;
    }

    public String getCustName() {
        return custName;
    }

    public void setCustName(String custName) {
        this.custName = custName;
    }

    public String getCustLevel() {
        return custLevel;
    }

    public void setCustLevel(String custLevel) {
        this.custLevel = custLevel;
    }

    public String getCustSource() {
        return custSource;
    }

    public void setCustSource(String custSource) {
        this.custSource = custSource;
    }

    public String getCustPhone() {
        return custPhone;
    }

    public void setCustPhone(String custPhone) {
        this.custPhone = custPhone;
    }

    public String getCustMobile() {
        return custMobile;
    }

    public void setCustMobile(String custMobile) {
        this.custMobile = custMobile;
    }
}

LinkMan.java

package entity;

public class LinkMan {
    private Integer lkm_id;
    private String lkm_name;
    private String lkm_gender;
    private String lkm_phone;
    //在聯(lián)系人實體類里面表示所屬客戶,一個聯(lián)系人只能屬于一個客戶
    private Customer customer;

    public Customer getCustomer() {
        return customer;
    }

    public void setCustomer(Customer customer) {
        this.customer = customer;
    }

    public Integer getLkm_id() {
        return lkm_id;
    }

    public void setLkm_id(Integer lkm_id) {
        this.lkm_id = lkm_id;
    }

    public String getLkm_name() {
        return lkm_name;
    }

    public void setLkm_name(String lkm_name) {
        this.lkm_name = lkm_name;
    }

    public String getLkm_gender() {
        return lkm_gender;
    }

    public void setLkm_gender(String lkm_gender) {
        this.lkm_gender = lkm_gender;
    }

    public String getLkm_phone() {
        return lkm_phone;
    }

    public void setLkm_phone(String lkm_phone) {
        this.lkm_phone = lkm_phone;
    }
}

(2)讓實體類之間互相進行表示

  • 在客戶實體類里面有多個聯(lián)系人

    • 一個客戶里面有多個聯(lián)系人
  • 在聯(lián)系人實體類里面表示所屬客戶

    • 一個聯(lián)系人只能屬于一個客戶

(3)配置映射文件

  • 一般一個實體類對應(yīng)一個映射文件
    Customer.hb,.xml
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="entity.Customer" table="t_customer">
        <id name="cid" column="cid">
        <generator class="native"></generator>
        </id>
        <property name="custLevel" column="custLevel"></property>
        <property name="custMobile" column="custMobile"></property>
        <property name="custName" column="custName"></property>
        <property name="custPhone" column="custPhone"></property>
        <property name="custSource" column="custSource"></property>
        <!--在客戶映射文件中,表示所有聯(lián)系人
        使用set標(biāo)簽表示所有聯(lián)系人
        set標(biāo)簽里面有name屬性,屬性值寫在客戶實體類里面表示聯(lián)系人的set集合
        -->
        <set name="setlinkMan">
            <!--一對多建表,有外鍵
            hibernate機制:雙向維護外鍵,在一和多那一方配置外鍵
            column屬性值:外鍵名稱-->
            <key column="clid"></key>
            <!--客戶所有聯(lián)系人,class里面寫聯(lián)系人實體類全路徑-->
            <one-to-many class="entity.LinkMan"></one-to-many>
        </set>

    </class>
</hibernate-mapping>

LinkMan.hbm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
    <class name="entity.LinkMan" table="t_linkman">
        <id name="lkm_id" column="lkm_id">
            <generator class="native"></generator>
        </id>
        <property name="lkm_name" column="lkm_name"></property>
        <property name="lkm_gender" column="lkm_gender"></property>
        <property name="lkm_phone" column="lkm_phone"></property>
        <!--表示聯(lián)系人所屬客戶
        name:因為聯(lián)系人在實體類使用customer對象表示,寫customer名稱
        class:customer全路徑
        column:外鍵名稱
        -->
        <many-to-one name="customer" class="entity.Customer" column="clid"></many-to-one>
    </class>
    

</hibernate-mapping>
  • 把映射最基本配置完成
  • 在映射文件中,配置一對多的關(guān)系
    • 在客戶映射文件中,表示所有聯(lián)系人
        <!--在客戶映射文件中,表示所有聯(lián)系人
        使用set標(biāo)簽表示所有聯(lián)系人
        set標(biāo)簽里面有name屬性,屬性值寫在客戶實體類里面表示聯(lián)系人的set集合
        -->
        <set name="setlinkMan">
            <!--一對多建表,有外鍵
            hibernate機制:雙向維護外鍵,在一和多那一方配置外鍵
            column屬性值:外鍵名稱-->
            <key column="clid"></key>
            <!--客戶所有聯(lián)系人,class里面寫聯(lián)系人實體類全路徑-->
            <one-to-many class="entity.LinkMan"></one-to-many>
        </set>
  • 在聯(lián)系人映射文件中,表示所屬客戶
        <!--表示聯(lián)系人所屬客戶
        name:因為聯(lián)系人在實體類使用customer對象表示,寫customer名稱
        class:customer全路徑
        column:外鍵名稱
        -->
        <many-to-one name="customer" class="entity.Customer" column="clid"></many-to-one>

(4)創(chuàng)建核心配置文件

        <mapping resource="Customer.hb,.xml"></mapping>
        <mapping resource="LinkMan.hbm.xml"></mapping>
測試結(jié)果
數(shù)據(jù)表創(chuàng)建成功

2 一對多級聯(lián)操作
(1)級聯(lián)操作

  • 級聯(lián)保存
    添加一個客戶,為這個客戶添加多個聯(lián)系人
  • 級聯(lián)刪除
    刪除某一給我客戶,這個客戶里面的所有的聯(lián)系人也刪除

(2)一對多級聯(lián)保存
目標(biāo):添加客戶,為這個客戶添加一個聯(lián)系人
方法一:

import Utils.HibernateUtils;
import entity.Customer;
import entity.LinkMan;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.junit.Test;

public class HibernateOnetoMany {
    //演示一對多級聯(lián)保存
    @Test
    public void testAddDemo1(){
        Transaction tx = null;
        try{
          Session session =  HibernateUtils.getSessionObject();
          tx= session.beginTransaction();
            //添加一個客戶,為這個客戶添加一個聯(lián)系人
            //1 創(chuàng)建客戶和聯(lián)系人對象
            Customer customer = new Customer();
            customer.setCustName("歐亞學(xué)院");
            customer.setCustLevel("VIP");
            customer.setCustSource("軟工");
            customer.setCustPhone("13692127465");
            customer.setCustMobile("029864564");

            LinkMan linkMan = new LinkMan();
            linkMan.setLkm_name("楊某人");
            linkMan.setLkm_gender("男");
            linkMan.setLkm_phone("130****3381");
            //2 在客戶表示聯(lián)系人,在聯(lián)系人表示客戶,建立客戶對象和聯(lián)系人對象關(guān)系
            //2.1 把聯(lián)系人對象放到客戶對象的set集合里面
            customer.getSetlinkMan().add(linkMan);
            //2.2 把客戶對象放到聯(lián)系人里面去
            linkMan.setCustomer(customer);
            //3 保存到數(shù)據(jù)庫
            session.save(customer);
            session.save(linkMan);
          tx.commit();
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }
    }
}

聯(lián)系人表
客戶表

方法二
一般根據(jù)客戶添加聯(lián)系人
第一步 在客戶映射文件中添加配置

  • 在客戶映射文件中有set標(biāo)簽進行配置
配置

第二步 創(chuàng)建客戶和聯(lián)系人對象,只需要把聯(lián)系人放到客戶里面就可以了,最終只需要保存客戶就可以了

public void testAddDemo2(){
        Transaction tx = null;
        try{
           Session session= HibernateUtils.getSessionObject();
           tx = session.beginTransaction();
            //1 創(chuàng)建客戶和聯(lián)系人對象
            Customer customer = new Customer();
            customer.setCustName("百度");
            customer.setCustLevel("普通用戶");
            customer.setCustSource("網(wǎng)絡(luò)");
            customer.setCustPhone("13612227465");
            customer.setCustMobile("021864564");

            LinkMan linkMan = new LinkMan();
            linkMan.setLkm_name("陳某人");
            linkMan.setLkm_gender("女");
            linkMan.setLkm_phone("130315245456");
            //2 把聯(lián)系人放到客戶里面
            customer.getSetlinkMan().add(linkMan);
            //3 保存
            session.save(customer);
           tx.commit();
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }
    }
聯(lián)系人表
客戶表

(3)級聯(lián)刪除
需求:刪除某個客戶,把客戶里面所有的聯(lián)系人刪除
實現(xiàn):
第一步 在客戶映射文件set標(biāo)簽,進行配置

配置

第二步 在代碼中直接刪除客戶(根據(jù)id查詢對象,調(diào)用session里面delete方法刪除)

 public void testDelDemo3(){
        Transaction tx = null;
        try{
             Session session= HibernateUtils.getSessionObject();
             tx = session.beginTransaction();
            Customer customer= session.get(Customer.class,1);
            session.delete(customer);
             tx.commit();
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }
    }
用戶表
聯(lián)系人表

執(zhí)行過程:

  • 根據(jù)id查詢客戶
第一步
  • 根據(jù)外鍵id值查詢聯(lián)系人
第二步
  • 把聯(lián)系人的外鍵設(shè)置外null
第三步
  • 刪除聯(lián)系人和客戶
第四步

(4)一對多修改操作
需求:讓陳某人聯(lián)系人所屬客戶不屬于百度,而是歐亞

    @Test
    public void testUpdateDemo4(){
        Transaction tx = null;
        try {
           Session session = HibernateUtils.getSessionObject();
           tx = session.beginTransaction();
            //1 根據(jù)id查詢陳某人,根據(jù)id查百度的客戶
            Customer eurasia= session.get(Customer.class,1);
           LinkMan chen = session.get(LinkMan.class,2);
           //2 設(shè)置持久態(tài)對象
            //把聯(lián)系人放到客戶里面
            eurasia.getSetlinkMan().add(chen);
            //把客戶放到聯(lián)系人里面
            chen.setCustomer(eurasia);
            
           tx.commit();
        }catch (Exception e){
            e.printStackTrace();
            tx.rollback();
        }
    }
數(shù)據(jù)庫

(5)inverse屬性

  • 因為hibernate雙向維護外鍵,在客戶和聯(lián)系人里面都需要維護外鍵,修改客戶時候修改一次外鍵,修改聯(lián)系人時候也修改一次外鍵,造成效率問題。
外鍵修改
  • 解決方式:讓其中一方不維護外鍵(一對多里面,讓其中一方放棄外鍵維護)
  • 具體實現(xiàn):在放棄關(guān)系維護映射文件中,進行配置,在set標(biāo)簽上使用inverse屬性
inverse

說明:inverse屬性默認(rèn)值,false不放棄關(guān)系維護,true表示放棄關(guān)系維護

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容