最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

深入解析Java的Hibernate框架中的一對(duì)一關(guān)聯(lián)映射

 更新時(shí)間:2016年01月03日 15:55:51   作者:cxshun  
這篇文章主要介紹了Java的Hibernate框架的一對(duì)一關(guān)聯(lián)映射,包括對(duì)一對(duì)一外聯(lián)映射的講解,需要的朋友可以參考下

作為一個(gè)ORM框架,hibernate肯定也需要滿足我們實(shí)現(xiàn)表與表之間進(jìn)行關(guān)聯(lián)的需要。hibernate在關(guān)聯(lián)方法的實(shí)現(xiàn)很簡(jiǎn)單。下面我們先來看看一對(duì)一的做法:
 不多說了,我們直接上代碼:
 兩個(gè)實(shí)體類,TUser和TPassport:

public class TUser implements Serializable{ 
 
 private static final long serialVersionUID = 1L; 
 private int id; 
 private int age; 
 private String name; 
 private TPassport passport; 
  //省略Get/Set方法 
} 
public class TPassport implements Serializable{ 
 
 private static final long serialVersionUID = 1L; 
 private int id; 
 private String serial; 
 private int expiry; 
 private TUser user; 
  //省略Get/Set方法 
} 

  下面我們看一下映射文件有什么不同:

<hibernate-mapping package="org.hibernate.tutorial.domain4"> 
 <class name="TUser" table="USER4"> 
  <id name="id" column="id"> 
   <generator class="native" /> 
  </id> 
  <property name="name" type="java.lang.String" column="name"/> 
  <property name="age" type="java.lang.Integer" column="age"/> 
  <one-to-one name="passport" class="TPassport" 
     cascade="all" outer-join="true" /> 
 </class> 
</hibernate-mapping> 

  這里我們看到有一個(gè)新標(biāo)簽,one-to-one,它表明當(dāng)前類與所對(duì)應(yīng)的類是一對(duì)一的關(guān)系,cascade是級(jí)聯(lián)關(guān)系,all表明無論什么情況都進(jìn)行級(jí)聯(lián),即當(dāng)對(duì)TUser類進(jìn)行操作時(shí),TPassport也會(huì)進(jìn)行相應(yīng)的操作,outer-join是指是否使用outer join語句。
 我們?cè)倏戳硗庖粋€(gè)TPassport的映射文件:

<hibernate-mapping package="org.hibernate.tutorial.domain4"> 
 <class name="TPassport" table="passport4"> 
  <id name="id" column="id"> 
   <generator class="foreign" > 
    <param name="property">user</param> 
   </generator> 
  </id> 
  <property name="serial" type="java.lang.String" column="serial"/> 
  <property name="expiry" type="java.lang.Integer" column="expiry"/> 
  <one-to-one name="user" class="TUser" constrained="true" /> 
 </class> 
</hibernate-mapping>

  
  這里我們重點(diǎn)看到generator的class值,它為foreign表明參照外鍵,而參照哪一個(gè)是由param來進(jìn)行指定,這里表明參照User類的id。而one-to-one標(biāo)簽中多了一個(gè)constrained屬性,它是告訴hibernate當(dāng)前類存在外鍵約束,即當(dāng)前類的ID根據(jù)TUser的ID進(jìn)行生成。
 下面我們直接上測(cè)試類,這次測(cè)試類沒有用JUnit而是直接Main方法來了:

public static void main(String[] args) { 
   
  Configuration cfg = new Configuration().configure(); 
  SessionFactory sessionFactory = cfg.buildSessionFactory(); 
  Session session = sessionFactory.openSession(); 
   
  session.beginTransaction(); 
   
  TUser user = new TUser(); 
  user.setAge(20); 
  user.setName("shunTest"); 
   
  TPassport passport = new TPassport(); 
  passport.setExpiry(20); 
  passport.setSerial("123123123"); 
   
  passport.setUser(user); 
  user.setPassport(passport); 
   
  session.save(user); 
   
  session.getTransaction().commit(); 
   
 } 

  代碼很簡(jiǎn)單,就不說了。我們主要看這里:

session.save(user); 

  這里為什么我們只調(diào)用一個(gè)save呢,原因就在我們的TUser映射文件中的cascade屬性,它被設(shè)為all,即表明當(dāng)我們對(duì)TUser進(jìn)行保存,更新,刪除等操作時(shí),TPassport也會(huì)進(jìn)行相應(yīng)的操作,所以這里我們不用寫session.save(passport)。我們看到后臺(tái):

Hibernate: insert into USER4 (name, age) values (?, ?) 
Hibernate: insert into passport4 (serial, expiry, id) values (?, ?, ?) 
Hibernate:   它打印出兩個(gè)語句,證明hibernate確定幫我們做了這個(gè)工作。
 
 
 下面我們?cè)賮硪粋€(gè)測(cè)試類,測(cè)試查詢:
public static void main(String[] args) { 
  Configuration cfg = new Configuration().configure(); 
  SessionFactory sessionFactory = cfg.buildSessionFactory(); 
  Session session = sessionFactory.openSession(); 
   
  TUser user = (TUser)session.load(TUser.class,new Integer(3)); 
  System.out.println(user.getName()+":"+user.getPassport().getSerial()); 
   
 } 
  這里我們通過查詢出TUser類,取到TPassport對(duì)象。
 我們可以看到hibernate的SQL語句是:
復(fù)制代碼 代碼如下:

Hibernate:
select tuser0_.id as id0_1_, tuser0_.name as name0_1_, tuser0_.age as age0_1_, tpassport1_.id as id1_0_, tpassport1_.serial as serial1_0_, tpassport1_.expiry as expiry1_0_ from USER4 tuser0_ left outer join passport4 tpassport1_ on tuser0_.id=tpassport1_.id where tuser0_.id=?

  我們看到語句當(dāng)中有l(wèi)eft outer join,這是因?yàn)槲覀兦懊嬖趏ne-to-one當(dāng)中設(shè)了outer-join="true",我們?cè)囍阉某蒮alse,看到SQL語句如下:
復(fù)制代碼 代碼如下:

Hibernate:
select tuser0_.id as id0_0_, tuser0_.name as name0_0_, tuser0_.age as age0_0_ from USER4 tuser0_ where tuser0_.id=?
Hibernate:
select tpassport0_.id as id1_0_, tpassport0_.serial as serial1_0_, tpassport0_.expiry as expiry1_0_ from passport4 tpassport0_ where tpassport0_.id=?


  現(xiàn)在是分成兩條來查了,根據(jù)第一條查出的ID再到第二條查出來。
 
 也許很多人會(huì)問為什么測(cè)試的時(shí)候不用TPassport查出TUser呢,其實(shí)也可以的,因?yàn)樗鼈兪且粚?duì)一的關(guān)系,誰查誰都是一樣的。

外鍵關(guān)聯(lián)
現(xiàn)在我們看一下通過外鍵來進(jìn)行關(guān)聯(lián)的一對(duì)一關(guān)聯(lián)。
 還是一貫的直接上例子:我們寫了兩個(gè)實(shí)體類,TGroup和TUser

public class TGroup implements Serializable{ 
 
 private static final long serialVersionUID = 1L; 
 private int id; 
 private String name; 
 private TUser user; 
  //省略Get/Set方法 
} 
public class TUser implements Serializable{ 
 
 private static final long serialVersionUID = 1L; 
 private int id; 
 private int age; 
 private String name; 
 private TGroup group; 
  //省略Get/Set方法 
  
} 

  實(shí)體類完了我們就看一下映射文件:

<hibernate-mapping package="org.hibernate.tutorial.domain5"> 
 <class name="TUser" table="USER5"> 
  <id name="id" column="id"> 
   <generator class="native" /> 
  </id> 
  <property name="name" type="java.lang.String" column="name"/> 
  <property name="age" type="java.lang.Integer" column="age"/> 
  <many-to-one name="group" class="TGroup" column="group_id" unique="true" /> 
 </class> 
</hibernate-mapping> 

  這里我們看到是用many-to-one標(biāo)簽而不是one-to-one,為什么呢?
 這里以前用的時(shí)候也沒多在注意,反正會(huì)用就行,但這次看了夏昕的書終于明白了,實(shí)際上這種通過外鍵進(jìn)行關(guān)聯(lián)方式只是多對(duì)一的一種特殊方式而已,我們通過unique="true"限定了它必須只能有一個(gè),即實(shí)現(xiàn)了一對(duì)一的關(guān)聯(lián)。
 接下來我們看一下TGroup的映射文件:

<hibernate-mapping package="org.hibernate.tutorial.domain5"> 
 <class name="TGroup" table="group5"> 
  <id name="id" column="id"> 
   <generator class="native" /> 
  </id> 
  <property name="name" type="java.lang.String" column="name"/> 
  <one-to-one name="user" class="TUser" property-ref="group" /> 
 </class> 
</hibernate-mapping> 

  這里,注意,我們又用到了one-to-one,表明當(dāng)前的實(shí)體和TUser是一對(duì)一的關(guān)系,這里我們不用many-to-one,而是通過one-to-one指定了TUser實(shí)體中通過哪個(gè)屬性來關(guān)聯(lián)當(dāng)前的類TGroup。這里我們指定了TUser是通過group屬性和Tuser進(jìn)行關(guān)聯(lián)的。property-ref指定了通過哪個(gè)屬性進(jìn)行關(guān)聯(lián)。
 下面我們看測(cè)試類:

public class HibernateTest { 
 
 public static void main(String[] args) { 
 
  Configuration cfg = new Configuration().configure(); 
  SessionFactory sessionFactory = cfg.buildSessionFactory(); 
  Session session = sessionFactory.openSession(); 
   
  session.beginTransaction(); 
   
  TGroup group = new TGroup(); 
  group.setName("testGroup"); 
   
  TUser user = new TUser(); 
  user.setAge(23); 
  user.setName("test"); 
   
  user.setGroup(group); 
  group.setUser(user); 
   
  session.save(group); 
  session.save(user); 
   
  session.getTransaction().commit(); 
  session.close(); 
 } 
 
} 

  注意,這次我們的代碼中需要進(jìn)行兩次的保存,因?yàn)樗鼈儗?duì)各自都有相應(yīng)的對(duì)應(yīng),只保存一個(gè)都不會(huì)對(duì)另外一個(gè)有什么操作。所以我們需要調(diào)用兩次保存的操作。最后進(jìn)行提交。
 hibernate打印出語句:

Hibernate: insert into group5 (name) values (?) 
Hibernate: insert into USER5 (name, age, group_id) values (?, ?, ?) 

  這說明我們正確地存入了兩個(gè)對(duì)象值。
 
 我們寫多一個(gè)測(cè)試類進(jìn)行查詢:

public static void main(String[] args) { 
 
  Configuration cfg = new Configuration().configure(); 
  SessionFactory sessionFactory = cfg.buildSessionFactory(); 
  Session session = sessionFactory.openSession(); 
   
  TUser user = (TUser)session.load(TUser.class,new Integer(1)); 
  System.out.println("From User get Group:"+user.getGroup().getName()); 
   
   
  TGroup group = (TGroup)session.load(TGroup.class,new Integer(1)); 
  System.out.println("From Group get User:" + group.getUser().getName()); 
   
  session.close(); 
   
 } 

  我們都可以得到正確的結(jié)果,這表明我們可以通過兩個(gè)對(duì)象拿出對(duì)方的值,達(dá)到了我們的目的。
 這個(gè)例子中用到的TGroup和TUser只是例子而已,實(shí)際上現(xiàn)實(shí)生活中的user一般都對(duì)應(yīng)多個(gè)group。

相關(guān)文章

  • 使用Nacos下載、配置、整合項(xiàng)目方式

    使用Nacos下載、配置、整合項(xiàng)目方式

    這篇文章主要介紹了使用Nacos 下載、配置、整合項(xiàng)目方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2024-08-08
  • Flowable歷史查詢實(shí)例分析

    Flowable歷史查詢實(shí)例分析

    這篇文章主要介紹了Flowable歷史查詢實(shí)例分析,歷史是記錄流程執(zhí)行過程中發(fā)生的事情,并將其永久存儲(chǔ)的組件,與運(yùn)行時(shí)數(shù)據(jù)不同,歷史數(shù)據(jù)在流程實(shí)例完成以后仍保存在數(shù)據(jù)庫中,下面我們來深入了解
    2023-10-10
  • java實(shí)現(xiàn)計(jì)算周期性提醒的示例

    java實(shí)現(xiàn)計(jì)算周期性提醒的示例

    本文分享一個(gè)java實(shí)現(xiàn)計(jì)算周期性提醒的示例,可以計(jì)算父親節(jié)、母親節(jié)這樣的節(jié)日,也可以定義如每月最好一個(gè)周五,以方便安排會(huì)議
    2014-04-04
  • JavaScript中new運(yùn)算符的實(shí)現(xiàn)過程解析

    JavaScript中new運(yùn)算符的實(shí)現(xiàn)過程解析

    這篇文章主要介紹了JavaScript中new運(yùn)算符的實(shí)現(xiàn)過程解析,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2019-10-10
  • SpringBoot沒有讀取到application.yml問題及解決

    SpringBoot沒有讀取到application.yml問題及解決

    這篇文章主要介紹了SpringBoot沒有讀取到application.yml問題及解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-12-12
  • 一文看懂springboot實(shí)現(xiàn)短信服務(wù)功能

    一文看懂springboot實(shí)現(xiàn)短信服務(wù)功能

    項(xiàng)目中的短信服務(wù)基本上上都會(huì)用到,簡(jiǎn)單的注冊(cè)驗(yàn)證碼,消息通知等等都會(huì)用到。這篇文章主要介紹了springboot 實(shí)現(xiàn)短信服務(wù)功能,需要的朋友可以參考下
    2019-10-10
  • java日期格式化SimpleDateFormat的使用詳解

    java日期格式化SimpleDateFormat的使用詳解

    這篇文章主要介紹了java SimpleDateFormat使用,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2019-05-05
  • SpringBoot整合Mybatis-plus關(guān)鍵詞模糊查詢結(jié)果為空

    SpringBoot整合Mybatis-plus關(guān)鍵詞模糊查詢結(jié)果為空

    SpringBoot整合Mybatis-plus使用關(guān)鍵詞模糊查詢的時(shí)候,數(shù)據(jù)庫中有數(shù)據(jù),但是無法查找出來,本文就來介紹一下SpringBoot整合Mybatis-plus關(guān)鍵詞模糊查詢結(jié)果為空的解決方法
    2025-04-04
  • Java使用@EnableEurekaServer實(shí)現(xiàn)自動(dòng)裝配詳解

    Java使用@EnableEurekaServer實(shí)現(xiàn)自動(dòng)裝配詳解

    這篇文章主要介紹了Java使用@EnableEurekaServer實(shí)現(xiàn)自動(dòng)裝配過程,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧
    2022-10-10
  • SpringBoot動(dòng)態(tài)數(shù)據(jù)源連接測(cè)試的操作詳解

    SpringBoot動(dòng)態(tài)數(shù)據(jù)源連接測(cè)試的操作詳解

    這篇文章主要介紹了SpringBoot動(dòng)態(tài)數(shù)據(jù)源連接測(cè)試的操作步驟,文中通過代碼示例和圖文結(jié)合的方式給大家講解的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2024-03-03

最新評(píng)論

新绛县| 察哈| 拜城县| 舒兰市| 无棣县| 五指山市| 观塘区| 额尔古纳市| 聂拉木县| 泾源县| 环江| 长岭县| 桦南县| 达州市| 家居| 织金县| 涟源市| 澳门| 平果县| 安远县| 波密县| 新竹市| 浦北县| 精河县| 驻马店市| 犍为县| 聂荣县| 鲁山县| 淳化县| 芜湖县| 恩施市| 嘉祥县| 周口市| 政和县| 阜阳市| 榆社县| 永川市| 陈巴尔虎旗| 嵩明县| 南雄市| 万源市|