項目用的是SSH基礎(chǔ)框架,其中有一些信息很類似,但又不盡相同。如果每一個建一個實體的話,那樣實體會太多,如果分組抽象,然后繼承,又不是特別有規(guī)律。鑒于這種情況,就打算讓用戶自己配置要添加的字段,然后生成對應(yīng)的表。
需要動態(tài)配置的部分實例:
上圖只是一小部分,一個一個組合起來大概有三百多。每一項對應(yīng)一個實體,顯然不好,就算是按照規(guī)律歸歸類還是有不少,于是就想到了在運行期來確定這些東西。開始有嘗試過動態(tài)編譯生成實體類,后來發(fā)現(xiàn)在數(shù)據(jù)存取上都存在問題,因為是后來生成的,所以只能用反射來獲取,這樣一來無法事先確定類型,也就沒法用注入的方式接收前端傳過來的數(shù)據(jù),也不能向前端提供數(shù)據(jù)了。后來決定用Hibernate的動態(tài)模型來處理這個問題,可能有的人不是很了解Hibernate的動態(tài)模型,下面我們就來介紹一下。
我們通常用實體類來跟表進行映射,當(dāng)我們需要一個user表的時候,通常都需要寫一個類似下面的實體類:
public class User {
private Long id;
private String name;
private String password;
// setter、getter...
}
然后用配置文件或注解來描述映射關(guān)系,如果使用動態(tài)模型的話,則不需要編寫實體類,只需要寫一個配置文件即可:
<?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映射實體與數(shù)據(jù)庫
Map user = new HashMap();
user.put("name", "動態(tài)模型");
user.put("password", "123456");
session.save("User", user);
session.getTransaction().commit();
session.close();
發(fā)出的SQL語句:insert into User (name, password) values (?, ?)
有人說動態(tài)映射存入數(shù)據(jù)很方便, 但是從數(shù)據(jù)取出數(shù)據(jù)好像比較難處理,其實這個問題可以通過事先做好約定來解決。
上一篇博客介紹了JRebel,它可以讓Tomcat支持熱部署。JRebel+Hibernate動態(tài)模型雙劍合璧,就可以實現(xiàn)我們動態(tài)建表的要求了。
在Spring的配置文件中加入:
<property name="mappingLocations">
<list>
<value>classpath:/com/tgb/entitycfg/*.hbm.xml</value>
</list>
</property>
采用通配符來配置hbm.xml文件,就是為了兼容運行期生成的動態(tài)模型配置文件,而JRebel可以檢測到配置文件的變化,從而將新增的配置加載進來,需要說明的是JRebel的動態(tài)加載屬于懶加載,即在你用到修改的東西是,才會將你修改的內(nèi)容重新加載進來。
我也是初次使用Hibernate動態(tài)模型,目前也算是嘗試階段吧,如果各位誰用過或者對動態(tài)模型感興趣歡迎留言交流。
更多建議: