專案用的是SSH基礎框架,其中有一些資訊很類似,但又不盡相同。如果每一個建一個實體的話,那樣實體會太多,如果分組抽象,然後繼承,又不是特別有規律。鑑於這種情況,就打算讓使用者自己配置要新增的欄位,然後生成對應的表。
需要動態配置的部分例項:
上圖只是一小部分,一個一個組合起來大概有三百多。每一項對應一個實體,顯然不好,就算是按照規律歸歸類還是有不少,於是就想到了在執行期來確定這些東西。開始有嘗試過動態編譯生成實體類,後來發現在資料存取上都存在問題,因為是後來生成的,所以只能用反射來獲取,這樣一來無法事先確定型別,也就沒法用注入的方式接收前端傳過來的資料,也不能向前端提供資料了。後來決定用Hibernate的動態模型來處理這個問題,可能有的人不是很瞭解Hibernate的動態模型,下面我們就來介紹一下。
我們通常用實體類來跟表進行對映,當我們需要一個user表的時候,通常都需要寫一個類似下面的實體類:
public class User { private Long id; private String name; private String password; // setter、getter... }
然後用配置檔案或註解來描述對映關係,如果使用動態模型的話,則不需要編寫實體類,只需要寫一個配置檔案即可:
<?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN" "http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd"> <hibernate-mapping> <!-- 此處不需要類名,和包名 --> <class entity-name="User"> <id name="id" type="java.lang.Long" column="ID"> <generator class="native"/> </id> <property name="name" type="java.lang.String" column="name"/> <property name="password" type="java.lang.String" column="password"/> </class> </hibernate-mapping>
然後通過Map進行操作:
session.beginTransaction(); //通過Map對映實體與資料庫 Map user = new HashMap(); user.put("name", "動態模型"); user.put("password", "123456"); session.save("User", user); session.getTransaction().commit(); session.close();
發出的SQL語句:insert into User (name, password) values (?, ?)
有人說動態對映存入資料很方便, 但是從資料取出資料好像比較難處理,其實這個問題可以通過事先做好約定來解決。
上一篇部落格介紹了JRebel,它可以讓Tomcat支援熱部署。JRebel+Hibernate動態模型雙劍合璧,就可以實現我們動態建表的要求了。
在Spring的配置檔案中加入:
<property name="mappingLocations"> <list> <value>classpath:/com/tgb/entitycfg/*.hbm.xml</value> </list> </property>
採用萬用字元來配置hbm.xml檔案,就是為了相容執行期生成的動態模型配置檔案,而JRebel可以檢測到配置檔案的變化,從而將新增的配置載入進來,需要說明的是JRebel的動態載入屬於懶載入,即在你用到修改的東西是,才會將你修改的內容重新載入進來。
我也是初次使用Hibernate動態模型,目前也算是嘗試階段吧,如果各位誰用過或者對動態模型感興趣歡迎留言交流。