Hibernate框架之雙向多對多關係映射

来源:http://www.cnblogs.com/liujiayun/archive/2016/08/12/5764574.html
-Advertisement-
Play Games

昨天跟大家分享了Hibernate中單向的一對多、單向多對一、雙向一對多的映射關係,今天跟大家分享下在Hibernate中雙向的多對多的映射關係 這次我們以項目和員工舉個慄子,因為大家可以想象得到,在真實的環境下,一個項目肯定是對應著多個員工的,這毫無疑問, 那麼同時,一個比較牛員工也能同時參與多個 ...


昨天跟大家分享了Hibernate中單向的一對多單向多對一雙向一對多的映射關係,今天跟大家分享下在Hibernate中雙向的多對多的映射關係

這次我們以項目和員工舉個慄子,因為大家可以想象得到,在真實的環境下,一個項目肯定是對應著多個員工的,這毫無疑問,

那麼同時,一個比較牛員工也能同時參與多個項目的開發,這就體現了雙向多對多的關係。

首先呢,我們得弄清楚在底層資料庫中表與表之間的關係,我們創建一個員工表(Employee)和項目表(Project)毫無疑問,那麼我們要怎麼體現出多對多的關係呢?

當然有很多種方法,這裡我以單獨提出一張關係表為例,也就是說,我單獨創建一張表來保存員工和項目的關係,具體的實體類如下

Employee

package entity;

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

/*
 * 員工表
 * */
public class Employee {
    private Integer empid;//員工編號
    private String empname;//員工名稱
    //準備一個項目集合
    private Set<Project> pros=new HashSet<Project>();
    
    
    public Set<Project> getPros() {
        return pros;
    }
    public void setPros(Set<Project> pros) {
        this.pros = pros;
    }
    
    
    public Employee(String empname) {
        super();
        this.empname = empname;
    }
    public Employee(Integer empid, String empname) {
        this.empid = empid;
        this.empname = empname;
    }
    public Employee() {
    }
    public Integer getEmpid() {
        return empid;
    }
    public void setEmpid(Integer empid) {
        this.empid = empid;
    }
    public String getEmpname() {
        return empname;
    }
    public void setEmpname(String empname) {
        this.empname = empname;
    }
    
}

 

Proemp

package entity;
/*
 * 表示員工和項目相關聯的表
 * */
public class Proemp {
    private Integer rproid;//項目編號
    private Integer rempid;//員工編號
    
    
    public Proemp(Integer rproid, Integer rempid) {
        this.rproid = rproid;
        this.rempid = rempid;
    }
    public Proemp() {
    }
    public Integer getRproid() {
        return rproid;
    }
    public void setRproid(Integer rproid) {
        this.rproid = rproid;
    }
    public Integer getRempid() {
        return rempid;
    }
    public void setRempid(Integer rempid) {
        this.rempid = rempid;
    }
    
}

 

Project

package entity;

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

/*
 * 項目表
 * */
public class Project {
    private Integer proid;//項目編號
    private String proname;//項目名稱
    //聲明員工集合
    private Set<Employee> emps=new HashSet<Employee>();
    
    
    public Set<Employee> getEmps() {
        return emps;
    }
    public void setEmps(Set<Employee> emps) {
        this.emps = emps;
    }
    
    
    public Project(String proname) {
        this.proname = proname;
    }
    public Integer getProid() {
        return proid;
    }
    public void setProid(Integer proid) {
        this.proid = proid;
    }
    public String getProname() {
        return proname;
    }
    public void setProname(String proname) {
        this.proname = proname;
    }
    public Project(Integer proid, String proname) {
        this.proid = proid;
        this.proname = proname;
    }
    public Project() {
    }
}

 

這樣我們的實體類就全部創建完畢,接下來我們就可以配置映射關係文件了,既然是雙向的多對多的關係,那麼肯定少不了<set></set>標簽

Project.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="entity">
    <class name="Project" table="project">
        <id name="proid" column="proid">
            <generator class="increment" />
        </id>
        <property name="proname" type="string" column="proname" />
        <!-- 配置多對多的關聯關係  設置級聯屬性-->
        <set name="emps" table="proemp" cascade="all">
            <key column="rproid"></key>
            <many-to-many class="entity.Employee" column="rempid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

 

Employee.hbm.xml

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
        "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
        "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">

<hibernate-mapping package="entity">
    <class name="Employee" table="Employee">
        <id name="empid" column="empid">
            <generator class="increment" />
        </id>
        <property name="empname" type="string" column="empname" />
        <!-- 配置多對多的關聯配置  設置反轉屬性,讓項目管理關係 -->
        <set name="pros" table="proemp" inverse="true">
            <key column="rempid"></key>
            <many-to-many class="entity.Project" column="rproid"></many-to-many>
        </set>
    </class>
</hibernate-mapping>

 

經過以上的步驟,整個配置過程就全部完成了,當然同學們別忘記了在Hibernate配置文件(大配置)中添加對兩個映射文件(小配置)的引用

測試類

package test;

import org.hibernate.Session;
import org.hibernate.Transaction;

import util.HibernateUtil;
import entity.Employee;
import entity.Project;

public class Test {
    public static void main(String[] args) {
        /*
         * 多對多的關聯關係配置
         * 同時配置了Project和Employee之間雙向的多對多的關聯關係
         * 關聯關係由Project方維護,並且在Project方設置了級聯屬性
         * */
        //獲取Session 
        Session session=HibernateUtil.currentSession();
        //開啟事務
        Transaction tx = session.beginTransaction();
        //構建兩個項目
        Project pro1=new Project("項目一");
        Project pro2=new Project("項目二");
        //構建多個員工
        Employee emp1=new Employee("巴黎的雨季");
        Employee emp2=new Employee("盛夏的果實");
        Employee emp3=new Employee("聽風");
        Employee emp4=new Employee("黎明前的黑暗");
        
        //將員工123加入項目一
        pro1.getEmps().add(emp1);
        pro1.getEmps().add(emp2);
        pro1.getEmps().add(emp3);
        //將員工234加入項目二
        pro2.getEmps().add(emp2);
        pro2.getEmps().add(emp3);
        pro2.getEmps().add(emp4);
        
        //保存項目一和項目二
        session.save(pro1);
        session.save(pro2);
        //提交事務
        tx.commit();
        //關閉連接
        HibernateUtil.closeSession();
    }
}

 

以上代碼,我們可以發現我們僅僅保存了項目,並沒有手動的添加保存員工的代碼,也沒有手動添加保存員工和項目之間關係的表的代碼

我們可以看到Hibernate幫我們生成的sql

Hibernate很智能的通過配置文件幫我們生成了我們需要的sql,這就是面向對象思想的體現,我們自始至終都只關註了項目這個對象就完成了我們所需要的操作

我們可以看看資料庫中的記錄

 

 以上就是如何去配置雙向多對多的映射關係的代碼和解釋了。希望對大家有點用~~

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 線程的優先順序用數字來表示,預設範圍是1到10,即Thread.MIN_PRIORITY到Thread.MAX_PRIORTY.一個線程的預設優先順序是5,即Thread.NORM_PRIORTY 對優先順序操作的方法: int getPriority():得到線程的優先順序 void setPriorit ...
  • 1.tomcat7-maven-plugin插件 1. 不通過外部的tomcat 直接將tomcat核心內嵌在項目中,tomcat7:run 命令就可以啟動項目,可以直接訪問 localhost:8080/Demo 2. 熱部署(tomcat是活的) tomcat7:deploy 命令就可以將項目發 ...
  • 設計一個小型的記憶體池以及鏈表 上一節擼到萬事俱備只欠真正的 , 但是 的作用是將源代碼轉化為 流, 用什麼保存 ? 這就涉及到我們要接觸的第一個數據結構—鏈表, 雖然標準庫中很多容器都可以承擔鏈表的任務, 但是我說過 出於鍛煉原因, 我會儘量不使用stl中的容器 , 所以我決定自己擼一個鏈表出來, ...
  • 今天來說說圖片壓縮技術,為什麼要使用圖片壓縮,圖片上傳不就完事了嗎?對的,這在幾年前可以這麼說,因為幾年前還沒有現在這麼大的併發,也沒有現在這麼關註性能。 如今手機很多,很多人都是通過手機訪問網路或者app,再調用介面的時候肯定會多多少少的瀏覽圖片,尤其是脫離wifi的情況下,可以看到很多軟體展示都 ...
  • 一、轉向(Forward) 1.要點說明 轉向是通過RequestDispatcher對象的forward()方法來實現的。RequestDispatcher可以通過HttpServletRequest的getRequestDispatcher()方法獲得。getRequestDispatcher( ...
  • Go語言是Google內部主推的語言,它作為一門全新的靜態類型開發語言,與當前的開發語言相比具有許多令人興奮不已的新特性。專門針對多處理器系統的應用程式編程進行了優化,使用go語言完全可以媲美c、c++的速度,而且更加安全、簡潔,支持並行進程。 以下是go語言的主要特性: 1、自動垃圾回收 2、更豐 ...
  • --> Poker類用於存入54張撲克牌 --> Player類對玩家進行發牌和顯示處理(寫完我就後悔了,J,Q,K,A,2的排序太low了..package com.dragon.java.hwddz; --> 寫完發現邏輯是不是有問題啊... ...
  • 定義: 單來源調用指一個類的生成工作只能由特定類來執行。 eg李寧牌鞋子只能由李寧專賣店生產 這個問題歸結起來,也就是說在工廠模式中,指定的產品類只能通過具體的特定工廠類來生成,而不能自己new出來或者通過其他類生成。 具體的,我們就在代碼實現中進行說明瞭。 這裡我們來一步一步分析。 首先,一個類實 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...