深刻解析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對象。
外鍵聯系關系
如今我們看一下經由過程外鍵來停止聯系關系的一對一聯系關系。
照樣一向的直接上例子:我們寫了兩個實體類,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。