天天看點

hibernate系列(四)一對一關聯關系

以person類和idcard類為例,這裡僅僅說一種一對一關聯關系,即person類擁有idcard,但是idcard不含person類,資料庫庫的表如下: 

<a href="http://my.oschina.net/pingpangkuangmo/blog/376314#">?</a>

1

2

3

4

5

6

<code>create</code> <code>table</code> <code>`hibernate`.`person` (</code>

<code>  </code><code>`id`</code><code>int</code> <code>not</code> <code>null</code> <code>auto_increment,</code>

<code>  </code><code>`</code><code>name</code><code>`</code><code>varchar</code><code>(45)</code><code>null</code><code>,</code>

<code>  </code><code>`age`</code><code>int</code> <code>null</code><code>,</code>

<code>  </code><code>`idcard_id`</code><code>int</code> <code>null</code><code>,</code>

<code>  </code><code>primary</code> <code>key</code> <code>(`id`));</code>

<code>create</code> <code>table</code> <code>`hibernate`.`idcard` (</code>

<code>  </code><code>`number`</code><code>int</code> <code>null</code><code>,</code>

<code>  </code><code>`content`</code><code>varchar</code><code>(45)</code><code>null</code><code>,</code>

person類如下: 

7

8

<code>public</code> <code>class</code> <code>person {</code>

<code>    </code><code>private</code> <code>long id;</code>

<code>    </code><code>private</code> <code>string name;</code>

<code>    </code><code>private</code> <code>long age;</code>

<code>    </code><code>private</code> <code>idcard idcard;</code>

<code>//省略get、set方法</code>

<code>}</code>

person類對應的person.hbm.xml映射檔案為: 

9

10

<code>&lt;</code><code>hibernate-mapping</code><code>&gt;</code>

<code>    </code><code>&lt;</code><code>class</code> <code>name</code><code>=</code><code>"com.ligang.domain.person"</code> <code>table</code><code>=</code><code>"person"</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>id</code> <code>name</code><code>=</code><code>"id"</code> <code>column</code><code>=</code><code>"id"</code> <code>type</code><code>=</code><code>"long"</code><code>&gt;</code>

<code>            </code><code>&lt;</code><code>generator</code> <code>class</code><code>=</code><code>"identity"</code><code>/&gt;</code>

<code>        </code><code>&lt;/</code><code>id</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"name"</code> <code>column</code><code>=</code><code>"name"</code> <code>type</code><code>=</code><code>"string"</code><code>/&gt;</code>

<code>        </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"age"</code> <code>column</code><code>=</code><code>"age"</code> <code>type</code><code>=</code><code>"long"</code><code>/&gt;</code>

<code>        </code><code>&lt;</code><code>many-to-one</code> <code>name</code><code>=</code><code>"idcard"</code> <code>class</code><code>=</code><code>"com.ligang.domain.idcard"</code> <code>column</code><code>=</code><code>"idcard_id"</code> <code>cascade</code><code>=</code><code>"save-update"</code><code>&gt;&lt;/</code><code>many-to-one</code><code>&gt;</code>

<code>    </code><code>&lt;/</code><code>class</code><code>&gt;</code>

<code>&lt;/</code><code>hibernate-mapping</code><code>&gt;</code>

雖然是一對一但是,這種形式的一對一就是多對一的特例,是以仍然使用&lt;many-to-one&gt;的标簽,其中的name指的是person類的idcard屬性,column指的是person表中的字段名為idcard_id,class指的是将idcard類對應的表的主鍵的值作為idcard_id的值。cascade字段表示儲存person類時級聯的儲存idcard類。 

下面看下idcard類: 

<code>public</code> <code>class</code> <code>idcard {</code>

<code>    </code><code>private</code> <code>long number;</code>

<code>    </code><code>private</code> <code>string content;</code>

idcard類對應的idcard.hbm.xml映射檔案為: 

<code>    </code><code>&lt;</code><code>class</code> <code>name</code><code>=</code><code>"com.ligang.domain.idcard"</code> <code>table</code><code>=</code><code>"idcard"</code><code>&gt;</code>

<code>        </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"number"</code> <code>column</code><code>=</code><code>"number"</code> <code>type</code><code>=</code><code>"long"</code><code>/&gt;</code>

<code>        </code><code>&lt;</code><code>property</code> <code>name</code><code>=</code><code>"content"</code> <code>column</code><code>=</code><code>"content"</code> <code>type</code><code>=</code><code>"string"</code><code>/&gt;</code>

然後就是測試增添方法: 

11

12

13

14

15

16

17

18

19

20

<code>@test</code>

<code>    </code><code>public</code> <code>void</code> <code>addperson(){</code>

<code>        </code><code>session session=hibernatedao.getsession();</code>

<code>        </code><code>transaction tx=session.begintransaction();</code>

<code>        </code> 

<code>        </code><code>person p=</code><code>new</code> <code>person();</code>

<code>        </code><code>p.setname(</code><code>"張三"</code><code>);</code>

<code>        </code><code>p.setage(122l);</code>

<code>        </code><code>idcard idcard=</code><code>new</code> <code>idcard();</code>

<code>        </code><code>idcard.setnumber(123445l);</code>

<code>        </code><code>idcard.setcontent(</code><code>"你是一個人"</code><code>);</code>

<code>        </code><code>p.setidcard(idcard);</code>

<code>        </code><code>session.save(p);</code>

<code>        </code><code>tx.commit();</code>

<code>        </code><code>session.close();</code>

<code>    </code><code>}</code>

此時就會先儲存idcard對象,然後擷取其主鍵并指派給person表的idcard_id字段,然後增添person對象。如下sql: 

<code>hibernate:</code><code>insert</code> <code>into</code> <code>hibernate.idcard (number, content)</code><code>values</code> <code>(?, ?)</code>

<code>hibernate:</code><code>insert</code> <code>into</code> <code>hibernate.person (</code><code>name</code><code>, age, idcard_id)</code><code>values</code> <code>(?, ?, ?)</code>

更新如下: 

<code>    </code><code>public</code> <code>void</code> <code>updateperson(){</code>

<code>        </code><code>person p=(person) session.get(person.</code><code>class</code><code>,6l);</code>

此時的sql如下: 

<code>hibernate:</code><code>select</code> <code>person0_.id</code><code>as</code> <code>id1_3_0_, person0_.</code><code>name</code> <code>as</code> <code>name2_3_0_, person0_.age</code><code>as</code> <code>age3_3_0_, person0_.idcard_id</code><code>as</code> <code>idcard_i4_3_0_</code><code>from</code> <code>hibernate.person person0_</code><code>where</code> <code>person0_.id=?</code>

<code>hibernate:</code><code>update</code> <code>hibernate.person</code><code>set</code> <code>name</code><code>=?, age=?, idcard_id=?</code><code>where</code> <code>id=?</code>

此時并沒有删除原有的idcard,隻是根據person再也找不到它了。目前我還不知道怎麼設定來删除無用的idcard。 

擷取:由person的主鍵擷取idcard比較容易,但是如果想從idcard主鍵擷取person呢? 

首先更改idcard類,添加person屬性: 

<code>    </code><code>private</code> <code>person person;</code>

<code>//略get、set方法</code>

然後更改上述的idcard.hbm.xml映射檔案如下: 

<code>        </code><code>&lt;</code><code>one-to-one</code> <code>name</code><code>=</code><code>"person"</code> <code>property-ref</code><code>=</code><code>"idcard"</code><code>&gt;&lt;/</code><code>one-to-one</code><code>&gt;</code>

添加了&lt;one-to-one&gt;标簽,同時使用了property-ref屬性,看下查詢再解釋: 

<code>    </code><code>public</code> <code>void</code> <code>getperson(){</code>

<code>        </code><code>idcard idcard=(idcard) session.get(idcard.</code><code>class</code><code>,2l);</code>

<code>        </code><code>system.out.println(idcard.getperson().getname());</code>

查詢的sql如下: 

<code>hibernate:</code><code>select</code> <code>idcard0_.id</code><code>as</code> <code>id1_1_0_, idcard0_.number</code><code>as</code> <code>number2_1_0_, idcard0_.content</code><code>as</code> <code>content3_1_0_, person1_.id</code><code>as</code> <code>id1_3_1_, person1_.</code><code>name</code> <code>as</code> <code>name2_3_1_, person1_.age</code><code>as</code> <code>age3_3_1_, person1_.idcard_id</code><code>as</code> <code>idcard_i4_3_1_</code><code>from</code> <code>hibernate.idcard idcard0_</code><code>left</code> <code>outer</code> <code>join</code> <code>hibernate.person person1_</code><code>on</code> <code>idcard0_.id=person1_.idcard_id</code><code>where</code> <code>idcard0_.id=?</code>

<code>張三</code>

将person查出來了,然後看下他是怎麼查的,看下idcard的&lt;one-to-one name="person" property-ref="idcard"&gt;,name指的是idcard的person屬性,而property-ref指向了另一個類的屬性,這裡就是person類的idcard屬性,要想查出person總要告訴hibernate idcard表的哪個字段和person表的哪個字段相連接配接吧,這裡的property-ref="idcard",即指定了要和person類的idcard屬性所對應的字段相連接配接,預設是采用主鍵來和該字段相連接配接的,我不知道能否指定。即idcard表的主鍵id和person類的idcard屬性對應的字段idcard_id相連接配接,來查詢person,看sql語句:hibernate.idcard idcard0_ left outer join hibernate.person person1_ on idcard0_.id=person1_.idcard_id 

上述一對一的關聯關系是通過外鍵來連接配接,他們也可以使用相同的主鍵實作一對一。這裡不再講述。 

上一篇:
下一篇: 哈夫曼樹