程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> 關於JAVA >> 深刻解析Java的Hibernate框架中的一對一聯系關系映照

深刻解析Java的Hibernate框架中的一對一聯系關系映照

編輯:關於JAVA

深刻解析Java的Hibernate框架中的一對一聯系關系映照。本站提示廣大學習愛好者:(深刻解析Java的Hibernate框架中的一對一聯系關系映照)文章只能為提供參考,不一定能成為您想要的結果。以下是深刻解析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。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved