hibernate繼承關係映射大概有5種,這5種繼承關係映射裏面,我覺得最有效最常用的一種方式非常好.就說說這種吧.先來說說hibernate繼承關係什麼時候使用.
(1) hibernate繼承關係什麼時候使用?
很多例子都是說一個動物類,然後是老虎類啊,獅子類啊之類去繼承動物類.例子很好,但是實際應用中我根據這個提出了一個完全可行的解決方案,很有成就感!
在項目裏面,遇到這樣一個問題,大概有30多張表,裏面都有共性的字段,每張表都需要走審覈流程,如果針對每張表都做相應的審覈模塊,代碼重複不說,那工作量就大了.針對這個就需要用到hibernate繼承關係映射了,所有共性的字段都提取出來,把審覈模塊做成公共的模塊!這中間又涉及用到了java反射機制.
(2)開始例子
先把30多張表共性的字段整理出來, id主鍵字段(String 類型的 主鍵生成方式是uuid),因爲uuid按着計算,據說得300年才能出現重複的數據,300年以後我早就入古了,軟件維護找我,嘿嘿,連骨灰都沒嘍!得了,跑題了.......繼續!
共有的字段:
id varchar 32
fileName varchar 100
audState varchar 2
tableName varchar 50 (這個字段存表名,表1的名字table1,就存table1,表2的名字table2,就存table2......反射時候用)
上面是所有表中共有的字段.再拿30多張表中的一張table1表來舉例子吧.table1表裏面自己特有的字段如下:
isDel varchar 2
fileTypeId int 4
code1 varchar 50
code2 varchar 50
code3 varchar 50
hibenrate繼承關係映射開始了
把共有的字段提出來做一個配置文件TcommTable.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<class name="com.hibernate.po.TcommTable" abstract="true" dynamic-insert="true">
<id name="id" type="string">
<column name="id" />
<generator class="uuid" />
</id>
<property name="fileName" type="string">
<column name="fileName" length="100" />
</property>
<property name="audState" type="string">
<column name="audState" length="2" />
</property>
<property name="tableName" type="string" insert="false">
<column name="tableName" length="32" />
</property>
</class>
</hibernate-mapping>
上面的配置文件是抽象的abstract="true" .
要生成相應的po:
public abstract class TcommTable implements Serializable {
private String id;
private String fileName;
private String tableName;
//生成set/get()方法
}
table1表特有的字段生成配置文件和po,都是TcommTable 的子類
table1表的配置文件Table1.hbm.xml
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse - Hibernate Tools
-->
<hibernate-mapping>
<union-subclass name="com.hibernate.po.Table1" table="Table1" extends="com.hibernate.po.TcommTable ">
<property name="isDel" type="string">
<column name="isDel" length="2" />
</property>
<column name="fileTypeId" />
</property>
<column name="code1" length="50" />
</property>
<column name="code2" length="50" />
</property>
<column name="code3" length="50" />
</property>
</union-subclass>
</hibernate-mapping>
table1的po:
public class Table1 extends TcommTable {
private String isDel;
private String fileTypeId;
private String code1;
private String code2;
private String code3;
//生成set/get()方法
}
(2)運用java的反射機制實現模塊的共用性
當30多張表公用一個審覈模塊的時候,把抽象類TcommTable傳到審覈模塊,如何知道這個抽象類是那張具體的表呢?就用到了java反射機制了,因爲抽象類無法new出對象來,所以就要用java反射機制.
在審覈的action裏面實現java的反射機制,主要代碼如下:
String tableName = request.getParameter("tableName");
String allName = "com.hibernate.po." + tableName;
TcommTable tomm = (TcommTable) Class.forName(allName).newInstance();
這樣,就能得到table1所有的字段(公共字段和table1特有的字段),然後把要審覈的內容放進tomm這個對象裏面就行了.注意,java反射機制必須要帶上類的完整包名,否則反射出錯.tableName字段是區分30多張表的識別字段,通過這個字段,hibernate就自動可以判斷出是哪個表和相應的類了,然後通過反射就能得到相應類的所有字段了,因爲公共字段放在一個抽象類裏面,抽象類無法new對象,所以只能通過反射機制來實現了.