1. 程式人生 > >【SSH快速進階】——Hibernate一對一對映(one-to-one)——主鍵關聯對映

【SSH快速進階】——Hibernate一對一對映(one-to-one)——主鍵關聯對映

  現實生活中,有很多場景需要用到一對一對映,比如每個學生只有一個學生證,每個公民只有一張身份證等。這裡用公民-身份證來舉例說明。

  這裡寫圖片描述

  在Hibernate中實現一對一對映,有兩種實現方式:1、主鍵關聯;2、唯一外來鍵關聯,這裡先說一下主鍵關聯對映。

  主鍵關聯對映:其中一個表的主鍵依賴於另一張表的主鍵而建立起的一對一的關係,這兩張互相關聯的表的主鍵一致。

  關聯對映又可細分為單向關聯對映和雙向關聯對映。



一對一單向關聯對映

  一對一單向關聯對映,即一個物件依賴另一個物件,比如根據人能找到他的身份證:

  這裡寫圖片描述
  
  Po物件:

  IdCard .java

public class IdCard {
    private int id;
    private String cardNo;  
    //getter、setter
}

  Person.java

public class Person {
    private int id;
    private String name;
    private IdCard idCard;
    //getter、setter
}

  對映檔案:

  IdCard.hbm.xml

<hibernate-mapping package="org.hibernate.test"
> <class name="com.danny.hibernate.IdCard" table="t_idCard"> <id name="id"> <generator class="native"/> </id> <property name="cardNo"/> </class> </hibernate-mapping>

  Person.hbm.xml

<hibernate-mapping package
="org.hibernate.test" >
<class name="com.danny.hibernate.Person" table="t_person"> <id name="id" type="int"> <generator class="foreign"> <param name="property">idCard</param> </generator> </id> <one-to-one name="idCard" constrained="true"/> <property name="name"/> </class> </hibernate-mapping>



  上述配置檔案中<one-to-one name="idCard" constrained="true"/>是配置一對一關聯的核心,表示一個Person對應一個IdCard。constrained=”true”表示t_person表的主鍵上同時有個外來鍵指向被關聯的表(t_idCard)的主鍵,會對錶t_person建立約束,約束t_person的id只能跟idCard的主鍵一樣。

  執行程式,實際執行的sql語句如下,除了建立兩張表,還為t_person表建立了約束:

alter table t_person drop foreign key FK785BED803EEB3F3E
drop table if exists t_idCard
drop table if exists t_person
create table t_idCard (id integer not null auto_increment, cardNo varchar(255), primary key (id))
create table t_person (id integer not null, name varchar(255), primary key (id))
alter table t_person add index FK785BED803EEB3F3E (id), add constraint FK785BED803EEB3F3E foreign key (id) references t_idCard (id)



  插入測試

session.beginTransaction();
IdCard idCard=new IdCard();
idCard.setCardNo("123456789");
Person person=new Person();
person.setName("danny");
person.setIdCard(idCard);
session.save(person);
session.getTransaction().commit();

  測試中,先定義idCard,person.setIdCard(idCard)之後,直接儲存person,雖然session沒有直接save(idCard),但是由於一對一主鍵關聯對映的特性,必須先儲存關聯物件idCard,才可以儲存person。所以在執行session.save(person)時,先儲存的是idCard。

  可以發現執行的sql語句為:

insert into t_idCard (cardNo) values (?)
insert into t_person (name, id) values (?, ?)



  查詢測試

Person person=(Person)session.load(Person.class, 1);
System.out.println("person的name:"+person.getName());
System.out.println("person的cardNo:"+person.getIdCard().getCardNo());

  實際執行的sql語句:

select person0_.id as id0_0_, person0_.name as name0_0_ from t_person person0_ where person0_.id=?
select idcard0_.id as id1_0_, idcard0_.cardNo as cardNo1_0_ from t_idCard idcard0_ where idcard0_.id=?

  執行結果

person的name:danny
person的cardNo:123456789



一對一雙向關聯對映

  一對一雙向關聯對映,即兩個物件互相依賴,根據人也能找到他的身份證,根據某人的身份證也能找到這個人:

  這裡寫圖片描述

  在上面的一對一單向關聯對映中,根據Person可以查到IdCard,但只根據IdCard不能查詢到Person,要想根據IdCard也能查詢到Person,IdCard的po和配置檔案也可以這麼寫:

  IdCard.java

public class IdCard {
    private int id;
    private String cardNo;  
    private Person person;
}

  IdCard.hbm.xml

<hibernate-mapping package="org.hibernate.test" >
    <class name="com.danny.hibernate.IdCard" table="t_idCard">
        <id name="id">
            <generator class="native"/>
        </id>
        <property name="cardNo"/>
        <one-to-one name="person" fetch="join"/><!-- fetch值為select時,可以實現懶載入 -->
    </class>
</hibernate-mapping>

  這裡標籤不能加constrained=”true”的原因是:如果加上後,t_person主鍵既依賴於t_idCard的主鍵,t_idCard的主鍵也依賴於t_person的主鍵,您想想,是不是就“死迴圈”了?

  這樣在查詢IdCard時,就可以順便查出person

IdCard idCard=(IdCard)session.load(IdCard.class, 1);
System.out.println("person的cardNo:"+idCard.getCardNo());
System.out.println("person的name:"+idCard.getPerson().getName());

  執行結果:

person的cardNo:123456789
person的name:danny

  查詢執行的sql語句:

select idcard0_.id as id1_0_, idcard0_.cardNo as cardNo1_0_ from t_idCard idcard0_ where idcard0_.id=?
Hibernate: select person0_.id as id0_0_, person0_.name as name0_0_ from t_person person0_ where person0_.id=?

  但是標籤隻影響查詢,並不影響儲存。比如執行下列儲存時:

session.beginTransaction();
Person person=new Person();
person.setName("danny");
IdCard idCard=new IdCard();
idCard.setCardNo("123456789");          
idCard.setPerson(person);
session.getTransaction().commit();

  只會儲存idCard,而不會儲存person。

相關推薦

SSH快速——Hibernate一對一對映one-to-one——關聯對映

  現實生活中,有很多場景需要用到一對一對映,比如每個學生只有一個學生證,每個公民只有一張身份證等。這裡用公民-身份證來舉例說明。      在Hibernate中實現一對一對映,有兩種實現方式:1

SSH快速——探索Hibernate物件的三種狀態:Transient、Persistent、Detached

  學習過作業系統的朋友,腦子裡肯定都會有這張程序的狀態轉換圖:      當所有條件就緒,程序被排程執行,時間片到的時候,程序被掛起,進入就緒狀態……對程序進行的不同操作會導致程序進入到不同的狀

SSH高速——Hibernate 多對多映射

pen prop package 轉載 map tex test lec set   說到多對多關系。印象最深刻的就是大學的選修課。一個學生能夠選修多門課程,一門課程能夠有多個學生選修,學生所選的每一門課程還有成績。這個場景的E-R圖例如以下:  

SSH快速——struts2呼叫action的三種方式

經過前段時間對struts2的學習與實踐,總結了一下在struts2中呼叫action的三種方式。 1、直接呼叫 我前面的部落格【SSH快速進階】系列第一篇《【SSH快速進階】——strut

SSH快速——struts2的模型驅動—ModelDriven

上篇部落格《SSH快速進階——struts2簡單的例項》中,處理使用者登陸的action—LoginAction為: package com.danny.user.action; public cl

hibernatehibernate基本原理

        hibernate作為SSH的持久層,是一個開放原始碼的物件關係對映框架,它對JDBC進行了非常輕量級的物件封裝,使得Java程式設計師可以隨心所欲的使用物件程式設計思維來操縱資料庫。

01月05日 三周四次Python基礎

是個 快速 files 函數 true 結果 lis pre 序列 1.8 遞歸列出目錄裏的文件1.9 匿名函數 1.8 遞歸列出目錄裏的文件 #### 遍歷目錄裏的文件(不支持子目錄文件) import os for i in os.listdir(‘C:/Users

01月11日 四周四次Python基礎

顯示 進階 col super 自定義 方法總結 總結 類方法 3.1 3.1/3.2 類的繼承3.3 類的屬性總結3.4 類的方法總結 3.1/3.2 類的繼承 類的繼承 繼承是面向對象的重要特點之一 繼承關系: 繼承是相對兩個類而言的父子關系,子類繼承父類所有的公有

01月12日 四周五次Python基礎

python3.5 rc腳本(類的定義與腳本的結構)3.6 rc腳本(start方法)3.7 rc腳本(stop和status方法)3.8 rc腳本(以daemon方式啟動) 3.5 rc腳本(類的定義與腳本的結構)/3.6 rc腳本(start方法)/3.7 rc腳本(stop和status方法) imp

mongoDB查詢聚合管道(三)--表達式操作符

ips www. name tostring 作用 數組操作 操作符 data seconds https://segmentfault.com/a/1190000010910985 管道操作符的分類 管道操作符可以分為三類: 階段操作符(Stage Operators)

菜鳥連結串列_C 結構體 共用體 列舉_遞推遞迴

座右銘 這些年我一直提醒自己一件事情,千萬不要自己感動自己。大部分人看似的努力,不過是愚蠢導致的。什麼熬夜看書到天亮,連續幾天只睡幾小時,多久沒放假了,如果這些東西也值得誇耀,那麼富士康流水線上任何一個人都比你努力多了。人難免天生有自憐的情緒,唯有時刻保持清醒,才能看清

T-SQL02.理解SQL查詢的底層原理

本系列【T-SQL】主要是針對T-SQL的總結。 一、SQL Server組成部分 1.關係引擎:主要作用是優化和執行查詢。 包含三大元件: (1)命令解析器:檢查語法和轉換查詢樹。 (2)查詢優化器:優化查詢。 (3)查詢執行器:負責執行查詢。 2.儲存引擎:管理所有資料及涉及的IO

JVM菜鳥高手之路十基礎知識開場白

由於 重要性 基礎 陌生 bsp 參數 高手之路 開發人員 基礎知識 轉載請註明原創出處,謝謝! 最近沒有什麽實戰,準備把JVM知識梳理一遍,先以開發人員的交流來談談jvm這塊的知識以及重要性,依稀記得2、3年前用solr的時候老是經常oom,提到oom大家應該都不陌生,那

web前端第十五篇popup簡單使用彈出頁面

model 循環 sci return submit mutable 數據 src close 一、首先說一下自執行函數 1. 立即執行函數是什麽?也就是匿名函數 立即執行函數就是 聲明一個匿名函數 馬上調用這個匿名函數 2、popup的舉例 點擊,彈出一個新的窗口

BZOJ3294/洛谷3158[CQOI2011]放棋子組合數+DP

題目: 洛谷3158 分析: 某OIer兔崽子的此題程式碼中的三個函式名:dfs、ddfs、dddfs(充滿毒瘤的氣息 顯然,行與行之間、列與列之間是互相獨立的。考慮揹包,用\(f[k][i][j]\)表示用前\(k\)種顏色佔了\(i\)行\(j\)列的方案數,\(g[i][j]\)表示用顏色\(k

Java學習第二十九天POI操作Excel

一、POI操作Excel 1、Excel簡介 一個excel檔案就是一個工作簿workbook,一個工作簿中可以建立多張工作表sheet,而一個工作表中包含多個單元格Cell,這些單元格都是由列(Column)行(Row)組成,列用大寫英文字母表示,從A開始到Z共26列,然後再從AA

學習筆記之Openlayers3要素繪製篇第三篇

直接以專案例項來進行講解要素繪製 需求(假如): 1.實現在地圖上畫點線面功能 2.自定義其樣式 3.支援編輯功能 需要用到的openlayers3中的ol.interaction.Draw 類。這是openlayers3提供的內建互動方式,除了這

學習筆記之Openlayers3要素儲存篇第四篇

上一篇中已經講了要素的繪製功能,既然要素都繪製出來了,繪製完就應該儲存起來了吧,那麼怎麼儲存呢?這一篇就是講解怎麼儲存繪製好的要素的。 個人用到過兩種儲存要素的方法,一種是通過WFS直接儲存要素入庫,另一種是通過ajax的方法通過專案的伺服器端儲

學習筆記之Openlayers3查詢分析篇第五篇

select count(*) from "+sourceName+" where 1=1 "; String sql = "select gid as gid,fname as name,ST_AsText(geom) as geowkt from "+sourceName+" wher