Hibernate上路_16-继承关系映射
2019獨(dú)角獸企業(yè)重金招聘Python工程師標(biāo)準(zhǔn)>>>
例:員工Employee分為正式工SalaryEmployee和臨時(shí)工HourEmployee。子類(lèi)表的字段都不能使用非空約束。
1.三種繼承關(guān)系的建表方式:
1)父類(lèi)、子類(lèi)在同一張表,表中有“辨別者列”。通過(guò)辨別者列值,區(qū)分父類(lèi)數(shù)據(jù)和子類(lèi)數(shù)據(jù)。
2)父類(lèi)、子類(lèi)各一張表。將公共數(shù)據(jù)放入父表,將個(gè)體數(shù)據(jù)存放子表,子表通過(guò)外鍵關(guān)聯(lián)父表的公共數(shù)據(jù)。
3)父子類(lèi)分別建表,父子表無(wú)關(guān)聯(lián),將父類(lèi)數(shù)據(jù)存放到父類(lèi)表,將子類(lèi)數(shù)據(jù)存放子類(lèi)表?,父子表采用連續(xù)增長(zhǎng)主鍵?
2.subClass方式:
父子類(lèi)數(shù)據(jù)在同一張表,引入辨別者列(discriminator)用來(lái)區(qū)分?jǐn)?shù)據(jù)記錄是父類(lèi)還是子類(lèi)。
1)父子類(lèi)POJO:
2)父類(lèi).hbm.xml配置:
對(duì)于繼承關(guān)系映射,不需要為每個(gè)類(lèi)建立hbm文件。只需要針對(duì)父類(lèi)編寫(xiě)hbm即可。
3)作為單表操作:
(1)插入:
public void test(){Session session = UtilGetSession.openSession();Transaction transaction = session.beginTransaction();PojoHuman human = new PojoHuman();human.setName("地球人");PojoWoman woman = new PojoWoman();woman.setName("女人");woman.setWaistline(36);woman.setBeauty("漂亮");PojoMan man = new PojoMan();man.setName("男人");man.setHeight(175);man.setSpeed(12);session.save(human);session.save(woman);session.save(man);transaction.commit();session.close();}
(2)查詢,通常使用HQL:
String hqlHuman="from PojoHuman";Query queryHuman = session.createQuery(hqlHuman);List listHuman = queryHuman.list();System.out.println(listHuman);
3.joined-subclass方式:
為每個(gè)父類(lèi)和子類(lèi)建立單獨(dú)數(shù)據(jù)表,將公共數(shù)據(jù)放入父表,?將個(gè)體信息存入子表,子表通過(guò)外鍵與父表關(guān)聯(lián)。
1)類(lèi)結(jié)構(gòu)相同:
2)父類(lèi).hbm.xml配置:
<hibernate-mapping package="cn.cvu.hibernate.domain"><class name="PojoHuman" table="tb_human" select-before-update="true"><id name="id" column="t_id" type="int"><generator class="native" /></id><!-- 父類(lèi)的通用屬性 --><property name="name" column="t_name" /><!-- 子類(lèi)配置name="子類(lèi)全路徑"table="子類(lèi)對(duì)應(yīng)的表" --><joined-subclass name="cn.cvu.hibernate.domain.PojoWoman" table="tb_woman"><!-- 子表主鍵,也是關(guān)聯(lián)父表的外鍵 --><key column="t_human_child"></key><!-- 子類(lèi)的個(gè)體屬性 --><property name="waistline"></property><property name="beauty"></property></joined-subclass><joined-subclass name="cn.cvu.hibernate.domain.PojoMan" table="tb_man"><key column="t_human_child"></key><property name="height"></property><property name="speed"></property></joined-subclass></class> </hibernate-mapping>
3)測(cè)試:
(1)測(cè)試保存:
代碼同上。
(2)測(cè)試查詢:
同上。
(3)測(cè)試刪除:?
org.hibernate.engine.jdbc.spi.SqlExceptionHelper?logExceptions?
WARN:?SQL?Error:?1451,?SQLState:?23000?
org.hibernate.engine.jdbc.spi.SqlExceptionHelper?logExceptions?
ERROR:?Cannot?delete?or?update?a?parent?row:?a?foreign?key?constraint?fails?
(`db_hibernate`.`tb_woman`,?CONSTRAINT?`FK_8n9ux8k3f9lja8fldi8om7cg0`?FOREIGN?KEY?
(`t_human_child`)?REFERENCES?`tb_human`?(`t_id`))?
4.union-subclass方式:
父類(lèi)和子類(lèi)單獨(dú)建表,父表和子表無(wú)關(guān)聯(lián);父類(lèi)數(shù)據(jù)插入父表,子類(lèi)數(shù)據(jù)插入子表,父表和子表的主鍵連續(xù)自增。
注意:不能使用identity、native,因?yàn)樾枰诙鄰埍硗瓿芍麈I連續(xù)自增;可以使用sequence(mysql不支持)、?increment?(hibernate實(shí)現(xiàn),max(id)+1)。
1)類(lèi)結(jié)構(gòu)相同:
2)父類(lèi).hbm.xml配置:
<hibernate-mapping package="cn.cvu.hibernate.domain"><class name="PojoHuman" table="tb_human" select-before-update="true"><id name="id" column="t_id" type="int"><generator class="increment" /></id><!-- 父類(lèi)的通用屬性 --><property name="name" column="t_name" /><!-- 子類(lèi)配置name="子類(lèi)全路徑"table="子類(lèi)對(duì)應(yīng)的表" --><union-subclass name="cn.cvu.hibernate.domain.PojoMan" table="tb_man"><!-- 子類(lèi)屬性 --><property name="height"/><property name="speed"/></union-subclass><union-subclass name="cn.cvu.hibernate.domain.PojoWoman" table="tb_woman"><property name="waistline"/><property name="beauty"/></union-subclass></class> </hibernate-mapping>
3)測(cè)試:
(1)測(cè)試保存:
(2)測(cè)試查詢:
(3)查詢刪除:
5.建表原則:
如果父子類(lèi)數(shù)據(jù)非常簡(jiǎn)單,可以使用subclass?,?重點(diǎn)推薦joinedsubclass?(性能最好),不推薦unionsubclass。
- end
?
轉(zhuǎn)載于:https://my.oschina.net/vigiles/blog/177520
總結(jié)
以上是生活随笔為你收集整理的Hibernate上路_16-继承关系映射的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: Lync Server 2010迁移至L
- 下一篇: H.264可伸缩编码SVC