一区二区三区在线-一区二区三区亚洲视频-一区二区三区亚洲-一区二区三区午夜-一区二区三区四区在线视频-一区二区三区四区在线免费观看

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - 深入解析Java的Hibernate框架中的一對一關聯映射

深入解析Java的Hibernate框架中的一對一關聯映射

2020-03-20 12:17cxshun JAVA教程

這篇文章主要介紹了Java的Hibernate框架的一對一關聯映射,包括對一對一外聯映射的講解,需要的朋友可以參考下

作為一個ORM框架,hibernate肯定也需要滿足我們實現表與表之間進行關聯的需要。hibernate在關聯方法的實現很簡單。下面我們先來看看一對一的做法:
 不多說了,我們直接上代碼:
 兩個實體類,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> 

  這里我們看到有一個新標簽,one-to-one,它表明當前類與所對應的類是一對一的關系,cascade是級聯關系,all表明無論什么情況都進行級聯,即當對TUser類進行操作時,TPassport也會進行相應的操作,outer-join是指是否使用outer join語句。
 我們再看另外一個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>

  
  這里我們重點看到generator的class值,它為foreign表明參照外鍵,而參照哪一個是由param來進行指定,這里表明參照User類的id。而one-to-one標簽中多了一個constrained屬性,它是告訴hibernate當前類存在外鍵約束,即當前類的ID根據TUser的ID進行生成。
 下面我們直接上測試類,這次測試類沒有用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(); 
   
 } 

  代碼很簡單,就不說了。我們主要看這里:

session.save(user); 

  這里為什么我們只調用一個save呢,原因就在我們的TUser映射文件中的cascade屬性,它被設為all,即表明當我們對TUser進行保存,更新,刪除等操作時,TPassport也會進行相應的操作,所以這里我們不用寫session.save(passport)。我們看到后臺:

Hibernate: insert into USER4 (name, age) values (?, ?) 
Hibernate: insert into passport4 (serial, expiry, id) values (?, ?, ?) 
Hibernate:   它打印出兩個語句,證明hibernate確定幫我們做了這個工作。
 
 
 下面我們再來一個測試類,測試查詢:
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對象。
 我們可以看到hibernate的SQL語句是:
復制代碼 代碼如下:

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=?
  我們看到語句當中有left outer join,這是因為我們前面在one-to-one當中設了outer-join="true",我們試著把它改成false,看到SQL語句如下:
復制代碼 代碼如下:

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=?
 
  現在是分成兩條來查了,根據第一條查出的ID再到第二條查出來。
 
 也許很多人會問為什么測試的時候不用TPassport查出TUser呢,其實也可以的,因為它們是一對一的關系,誰查誰都是一樣的。

外鍵關聯
現在我們看一下通過外鍵來進行關聯的一對一關聯。
 還是一貫的直接上例子:我們寫了兩個實體類,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方法 
  
} 

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

<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標簽而不是one-to-one,為什么呢?
 這里以前用的時候也沒多在注意,反正會用就行,但這次看了夏昕的書終于明白了,實際上這種通過外鍵進行關聯方式只是多對一的一種特殊方式而已,我們通過unique="true"限定了它必須只能有一個,即實現了一對一的關聯。
 接下來我們看一下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,表明當前的實體和TUser是一對一的關系,這里我們不用many-to-one,而是通過one-to-one指定了TUser實體中通過哪個屬性來關聯當前的類TGroup。這里我們指定了TUser是通過group屬性和Tuser進行關聯的。property-ref指定了通過哪個屬性進行關聯。
 下面我們看測試類:

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(); 
 } 
 
} 

  注意,這次我們的代碼中需要進行兩次的保存,因為它們對各自都有相應的對應,只保存一個都不會對另外一個有什么操作。所以我們需要調用兩次保存的操作。最后進行提交。
 hibernate打印出語句:

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

  這說明我們正確地存入了兩個對象值。
 
 我們寫多一個測試類進行查詢:

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(); 
   
 } 

  我們都可以得到正確的結果,這表明我們可以通過兩個對象拿出對方的值,達到了我們的目的。
 這個例子中用到的TGroup和TUser只是例子而已,實際上現實生活中的user一般都對應多個group。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 91东航翘臀女神在线播放 | 极品妖艳许清赵丽全文免费阅读 | 情缘1完整版在线观看 | aaa在线| 星空无限传媒xk8027穆娜 | 色播影院性播影院私人影院 | 99久久精品免费看国产一区二区 | 人与动人物性行为zozo共患病 | 亚洲婷婷在线视频 | 国产videos hd | 十大网站免费货源 | 日本大片网 | 国产精品嫩草影院一二三区入口 | 视频大全在线观看网址 | 视频免费视频观看网站 | xxxxyoujizz护士 | 色婷婷综合缴情综六月 | 日韩高清在线高清免费 | 调教人妖 | 日产乱码2021永久手机版 | 无遮掩60分钟从头啪到尾 | 亚洲精品色综合久久 | 桃乃木香奈作品在线观看 | 好奇害死猫在线观看 | 很很草 | 四虎影视紧急入口地址大全 | 互换娇妻爽文100系列小说 | 污污动图| 国产精品一级片 | 国产精品亚洲片在线观看麻豆 | 精品9e精品视频在线观看 | 欧美les同性videos | 成人欧美一区二区三区白人 | 国产成人精品高清不卡在线 | 国产全部理论片线观看 | 欧美高清一级 | 激情综合色啪啪小说 | 男生操男生 | 日韩性公交车上xxhd免费 | 欧美最新在线 | 色哟哟哟在线精品观看视频 |