天天看點

【hibernate架構】繼承映射

a.繼承映射簡述

舉個執行個體:

person類、student類,teacher類。

person類裡面有幾個屬性:name<string>

student類裡面有幾個屬性:除了name還有分數score<int>

teacher類裡面有幾個屬性:除了name還有職稱title<string>

如何用資料庫表來表示這些關系呢?

下面說說繼承映射的三種主要設計

1.設計一

可以設定一張表:

id<pk> 

name

score

title

這是什麼意思呢?就是說我可以把父類和子類的資訊存在一張表裡。

打比方存一個學生,存name和score即可,title設為null。

但是,當我取出資料的時候還要判斷哪個為空,比較麻煩,是以我們設定第五個字段,也就是“區分器”字段,來區分是那個對象。

discriminate<int> 用1代表student類型,用2代表teacher對象。

問題又有了,如果資料比較多,那麼每條都會有備援的資料存在。

最嚴重的事情是假如還有第三個類,備援就更多了。

這種設計叫“single table”。

2.設計二

每個類一張表

t_student:id<int> name<string> score<int>

t_teacher:id<int> name<string> title<string>

在程式裡經常這麼寫:

person p = student(load(1));//多态

告訴它id是1,它會把子類的所有表全部搜尋一遍。

而且student和teacher的id不能重複(主鍵重複無法搜尋),這個時候就不能使用自動生成id的政策了。

這種設計叫“table per class”。

3.設計三

t_person:id<int> name<string>

t_student:id<int> score<int>

t_teacher:id<int> title<string>

如果person表裡id為1的記錄是student,那麼在student

表裡面id=1中就記錄了這個人的score。

如果person表裡id為2的記錄是teacher,那麼在teacher

表裡面id=2中就記錄了這個人的title。

這樣我取那個人的時候就先把那人的姓名從主表裡取出來,之後

将其他屬性從另外一個字表中取出來。

兩個表必須要做連接配接(id保持一緻,叫做主鍵連接配接)。

加限制(這個id要參考某個子表的id)。

好處:查詢的時候不要找那麼多表了。

缺點:

1.必須要做表連接配接,才能找到相應的對象

2.每次增加一個新的對象(比如boss),必須添加一張新的表。

這種設計叫“joined”。

工作中繼承用的非常少。

b.繼承映射測試

編寫測試實體類和測試方法:(這裡我們用注解來設定繼承映射關系)

1.single_table政策

person.java:

student.java:

teacher.java:

在hibernate.cfg.xml中配置:

建表語句:

  drop table if exists e_person

    create table e_person (

        discriminator varchar(31) not null,

        id integer not null auto_increment,

        name varchar(255),

        score integer,

        title varchar(255),

        primary key (id)

    )

我們看到有好多屬性在裡面:id、name、score、title、discriminator

測試方法:

測試結果:

hibernate: 

    insert 

    into

        e_person

        (name, score, discriminator) 

    values

        (?, ?, 'student')

        (name, title, discriminator) 

        (?, ?, 'teacher')

在表中分别插入了如下兩條資料:

id=1、name='s1'、score=80、title=null、discriminator='student'

id=2、name='中國'、score=null、title='中級'、discriminator='teacher'

測試讀取:

輸出的sql語句和sys結果:

    select

        student0_.id as id0_0_,

        student0_.name as name0_0_,

        student0_.score as score0_0_ 

    from

        e_person student0_ 

    where

        student0_.id=? 

        and student0_.discriminator='student'

80

        person0_.id as id0_0_,

        person0_.name as name0_0_,

        person0_.score as score0_0_,

        person0_.title as title0_0_,

        person0_.discriminator as discrimi1_0_0_ 

        e_person person0_ 

        person0_.id=?

中國

剩下的方法用到再說

2.table_per_class

3.joined

尊重開源精神,尊重勞動成果,轉載請注明出處:http://blog.csdn.net/acmman/article/details/43907215