標籤:style blog class c code java
很不好意思,有兩天時間沒有更新部落格文章了,不寫文章的日子還真是感覺很空洞啊,養成了寫文章的惡習想改也改不掉啊。說點題外話,前兩天收到一位朋友的私信,邀請筆者寫一篇有關OWS的文章,用來研究表徵圖工具的一種技術,很榮幸收到這位朋友的邀請,但是因為這幾天開發的項目著急上線所以暫時沒有時間去研究,只能等這周末了,利用周末的時間來研究然後更新類似的技術文章。
回到文章的正題,上篇文章討論了雙向主鍵關聯,它其實是一對一主鍵關聯的一種特殊情況,想要實現雙向的關聯就必須在對應檔的兩端同時配置<one-to-one>,另外還要在主映射的一端採用foreign外部索引鍵關聯屬性。繼續討論雙向關聯的情況,在雙向關聯中還有一種外部索引鍵關聯沒有討論,接下來將會詳細討論雙向外部索引鍵關聯。
二、雙向外部索引鍵關聯
雙向的外部索引鍵關聯可以理解為外部索引鍵關聯的一種特殊情況,這種特殊主要是由於它是一種雙向的對應關係,在前篇文章中提到如果想要在一張表中添加一個外鍵欄位的話可以使用<many-to-one>標籤,它會關聯式模式中產生對應的外鍵列。這裡想要實現雙向的外部索引鍵關聯就必須使用該標籤。
1、物件模型
先來看物件模型,人和身份證屬於一對一的關係,一個人對應著一個身份,所以它們之間的多重性是一對一的,並且這種對應關係是雙向的。所以它的物件模型同雙向主鍵一對一是相同的,如:
2、關聯式模式
對應的關聯式模式會發生很大的變化,一對一的外部索引鍵關聯關係會在一張表中產生對應的外鍵,拿到人和身份證上來說也就是人的關聯式模式中會有一個社會安全號碼的主鍵列,它們之間形成了雙向的一對一的情況,如:
它們之間的對應關係就是中看到的,person表中有idCard表的主鍵,形成了一對一的外部索引鍵關聯關係,而且是雙向的,也就是說通過person能夠擷取到idCard,另外通過idCard也能擷取到person。
Person對象和IdCard對象內的代碼同上篇文章中的對象代碼一致,不在做代碼羅列,唯一不同的是對應檔中的配置問題。
3、對應檔
idCard.hbm.xml對應檔,idCard表不是映射的主表,所以在做一對一的映射時需要使用的是<one-to-one>標籤來配置,並且需要制定person關聯式模式中的外鍵屬性,具體代碼如下:
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2014-5-18 22:27:43 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping> <class name="com.src.hibernate.IdCard" table="IDCARD"> <id name="id" type="int"> <generator class="native" /> </id> <property name="cardNo" type="java.lang.String"> <column name="CARDNO" /> </property> <one-to-one name="person" property-ref="idCard"></one-to-one> </class></hibernate-mapping>
Person.hbm.xml對應檔,person表是映射的主表,需要在該表中添加一個外鍵屬性列來標示idCard表,所以這裡需要使用<many-to-one>標籤,在person對象中產生相應的外鍵,並且還要使用unique標明屬性唯一。
<?xml version="1.0"?><!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN""http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"><!-- Generated 2014-5-18 22:27:43 by Hibernate Tools 3.4.0.CR1 --><hibernate-mapping> <class name="com.src.hibernate.Person" table="PERSON"> <id name="id" type="int" column="personId"> <generator class="native" /> </id> <property name="name" type="java.lang.String"> <column name="NAME" /> </property> <many-to-one name="idCard" column="idCardNo" unique="true" not-null="true"></many-to-one> </class></hibernate-mapping>
對象的對應檔配置完成,接下來產生關聯式模式,SQL語句如下:
alter table PERSON drop foreign key FK8C768F55794A52CAdrop table if exists IDCARDdrop table if exists PERSONcreate table IDCARD (id integer not null auto_increment, CARDNO varchar(255), primary key (id))create table PERSON (personId integer not null auto_increment, NAME varchar(255), idCardNo integer not null unique, primary key (personId))alter table PERSON add index FK8C768F55794A52CA (idCardNo), add constraint FK8C768F55794A52CA foreign key (idCardNo) references IDCARD (id)
產生的SQL語句首先是建立的表,在建表時指定了主鍵列,建立完成後修改了兩個表指定外鍵屬性,形成一對一的關係。
編寫測試方法,採用單元測試,載入兩個類的對象,並分別從對象的一端擷取另一個對象
//載入對象,使用IdCard對象裝載person對象public void testLoad1(){Session session=null;try{session=HibernateUtils.getSession();session.beginTransaction();//擷取IdCard對象,在IdCard中擷取與該對象唯一關聯的person對象IdCard idcard=(IdCard)session.load(IdCard.class,1);System.out.println("person.Id= "+idcard.getPerson().getId());System.out.println("idCard.person.name= "+idcard.getPerson().getName());//擷取Person對象,在Person對象中擷取與它唯一關聯的IdCard對象Person person=(Person)session.load(Person.class,1);System.out.println("idCard.id: "+person.getIdCard().getId());System.out.println("idCard.cardNo: "+person.getIdCard().getCardNo());//提交事務session.getTransaction().commit();}catch(Exception e){e.printStackTrace();session.getTransaction().rollback();}finally{HibernateUtils.closeSession(session);}}
產生的內容:
對比兩種映射關係,主鍵和外鍵兩種映射,都是雙向的映射關係,需要在對象的兩端同時配置映射關係,不同的是主鍵只需要使用<one-to-one>因為它不需要產生屬性列,但是必須對錶的主鍵採用foreign的主鍵建置原則,並標示外鍵對象;外鍵的建置原則則需要採用<many-to-one>標籤來產生新的外鍵列。
結語
雙向關聯中的一對一映射至此已經討論完成,兩篇文章主要討論了雙向關聯中的兩種用法,其實還是很簡單的,記住一句話想要產生外鍵就使用<many-to-one>標籤,如果唯一那就添加unique屬性,<one-to-one>標籤只是指明了一對一的關係它只是指明一個對象如何載入另一個對象並不在關聯式模式中添加新列。下篇文章將會對一對多關聯展開討論。