[轉]對象建模還是E-R建模
轉自:http://qiaomuren.blog.hexun.com/11855630_d.html
良好的模型對于高效的開發高性能的應用系統是至關重要的。每個團隊在進行設計時都必須得進行選擇:是用純OOD/OOA的思想進行對象建模或者用面向關系數據的思想進行E-R建模,這是個艱難的抉擇!選擇其中的每一種都會導致不同的開發流程,其中各有利弊。
2、 用對象建模工具從設計好的類圖中導出Java源代碼。
3、 導出源代碼后就可在源代碼中添加Xdoclet標簽了,這些標簽用于生成Hibernate的映射文件。在添加Xdoclet標簽時要注意的是:要把Xdoclet標簽加在每個屬性的getter()方法之前,如果只在屬性前加標簽生成映射文件時就會報錯。
舉個例子,有一個人的實體類,我們在加Xdoclet時要特別注意,不要只加在屬性之前,而是要加在每個屬性的getter()方法之前,事實上可以不在屬性之前加Xdoclet標簽,如下所示例子中有一個Set類型的address屬性,元素是Address對象(例子沒有給出),假設一個人有多個地址,這是一個一對多的關系,在配置一對多和多對多關系時有幾點要注意:
import java.io.Serializable;
import java.util.Set;
import java.util.HashSet;
/**
* @hibernate.class
* table="Tperson"
*
*/
public class Person implements Serializable {
private Long personId;
private String name;
private int age;
private Set address = new HashSet(); //在這一定要實例化address對象
//我們應該在這加Xdoclet
/**
* 年齡
* @hibernate.property
* type="int"
* column="age"
*/
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
/**
* 用戶ID
* @hibernate.id
* generator="native"
* type="java.lang.Long"
* column="personId"
*/
public Long getPersonId() {
return personId;
}
public void setPersonId(Long personId) {
this.personId = personId;
}
/**
* 用戶姓名
* @hibernate.property
* type="java.lang.String"
* column="name"
* length="32"
* not-null="true"
*/
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/**
* 用戶地址
* @hibernate.set
* table-"Taddress"
* class="Address"
*
* @hibernate.collection-key
* column="personId"
*
* 注意下面是collection-one-to-many而不是one-to-many
* 對于多對多關系也是這樣collection-many-to-many
* @hibernate.collection-one-to-many
* class="Person"
*/
public Set getAddress() {
return address;
}
public void setAddress(Set address) {
this.address = address;
}
}
加完了這些Xdoclet我們就可以用工具生成映射文件了。一般用得較多的Xdoclet的Hibernate標簽有:
@hibernate.class
@hibernate.id
@hibernate.property
@hibernate.set
@hibernate.many-to-one
以上只給出了一些經常用的標記,大家在開發時可參考Xdoclet手冊。
4、 在Myeclipse project的properties窗口,選擇左側的“MyEclipse-XDoclet”,“Add Standard...”,“Choose an entry”這兒選擇“Standard Hibernate”。如下圖:右鍵電擊你的工程,然后選擇屬性,你就會看到這個圖。然后選擇Myeclipse選項就會看到其中有一個子選項Xdoclet,點擊Xdoclet出現如下界面,然后點擊Add Standard按鈕,選擇其中的Standard Hibernate,我們可以看到,Xdoclet支持很多技術的代碼生成。
5、 右鍵點擊工程根目錄,選擇Myeclipse選項的Run Xdoclet,這樣就可以生成映射文件了生成的映射文件默認情況下是和你的POJO在同一目錄下。(在這我只舉了用Myeclipse工具生成映射文件,你也可以用其他方式生成,可選工具:Xdoclet—
import java.io.File;
import java.util.List;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.HibernateException;
import org.hibernate.cfg.Configuration;
import junit.framework.TestCase;
public class TestHibernate extends TestCase {
protected Session session;
public TestHibernate(String s) {
super(s);
}
protected void setUp() throws Exception {
super.setUp();
try {
Configuration config = new Configuration().configure(new File("C:\\hibernate.cfg.xml"));
SessionFactory factory = config.buildSessionFactory();
session = factory.openSession();
} catch(HibernateException e) {
e.printStackTrace();
}
}
protected void tearDown() throws Exception {
super.tearDown();
try {
session.close();
} catch(HibernateException e) {
e.printStackTrace();
}
}
public void testInsert() {
Transaction tx = null;
try {
tx = session.beginTransaction();
Course course = new Course();
course.setCourseName("computer");
course.setDescription("計算”);
session.save(course);
session.flush();
tx.commit();
} catch(HibernateException e) {
e.printStackTrace();
fail(e.getMessage());
if(tx != null) {
try {
tx.rollback();
} catch(HibernateException err) {
err.printStackTrace();
}
}
}
}
Hibernate配置文件hibernate.cfg.xml如下:
<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN" "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="connection.username">root</property>
<property name="connection.url">jdbc:mysql://localhost:3306/webstudy</property>
<property name="dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.show_sql">True</property>
<property name="hibernate.jdbc.batch_size">25</property>
<property name="hibernate.jdbc.fatch_size">25</property>
<property name="myeclipse.connection.profile">MySQL</property>
注意在這加上下面這一行:可選值:update,create,create-drop;Hibernate在加載該配置文件時會自動檢測數據庫表是否存在。如果設為update,如果數據庫表不存在,則Hibernate會使用SchemaExport工具導出該表的定義然后創建該表。
<property name="hibernate.hbm2ddl.auto">update</property>
<mapping resource="Person.hbm.xml"/>
</session-factory>
</hibernate-configuration>
(可選工具:Hibernate Synchronizer Eclipse插件(這個工具支持正向工程和反向工程))
7、 數據庫表自動創建完畢,單元測試順利通過。
8、日后如果對Java代碼進行重構時,如果修改量不大我們可以手動去修改映射文件和數據庫表的定義以達到三者之間的同步;而如果重構范圍很大,我們完全可以重復以上的過程來達到三者同步的目的。
<1> 優點:完全采用OOA/OOD的思想,完全以Java代碼為中心進行開發
<2>缺點:手工添加Xdoclet工作量大,而且容易出錯,并且要配置好一些關鍵性的東西,否則Hibernate的性能會很差。
下面是使用E-R建模的一些工具和方法步驟:
1、 用E-R建模工具(如Power Designer或者Erwin)把物理數據模型建好
2、 用這些工具導出數據庫表的定義,然后生成數據庫表
3、 表生成后我們可以用Middlegen來生成映射文件,Middlegen有一個專門的Hibernate的工具Middlegen—Hibernate-r5,它依賴于Ant(也有個eclipse插件),我們就用它來生成映射文件。下載了該工具后首先要修改config/database下面的mysql.xml文件,如果你用的是其他的數據庫,則修改對應的xml文件,它支持多種數據庫,修改后要把mysql的JDBC驅動程序加入CLASSPATH。
<property name="database.script.file" value="${src.dir}/sql/${name}-mysql.sql"/>
<property name="database.driver.file" value="${lib.dir}/mysql-connector-java-
<property name="database.driver.classpath" value="${database.driver.file}"/>
<property name="database.driver" value="com.mysql.jdbc.Driver"/>
<property name="database.url" value="jdbc:mysql://localhost/webstudy"/>
<property name="database.userid" value="root"/>
<property name="database.password" value="root"/>
<property name="database.schema" value=""/>
<property name="database.catalog" value=""/>
<property name="jboss.datasource.mapping" value="mySQL"/>
上面的一些參數你可以根據實際情況進行修改。
然后修改根目錄下的build.xml文件的開始部分,指定使用mysql.xml配置文件。
<!DOCTYPE project [
<!ENTITY database SYSTEM "file:./config/database/mysql.xml">
]>
為了在映射文件中生成Xdoclet,我們找到Middlegen任務的子任務Hibernate部分:
<hibernate
destination="${build.gen-src.dir}"
package="${name}.hibernate"
genXDocletTags="false"
genIntergratedCompositeKeys="false"
javaTypeMapper="middlegen.plugins.hibernate.HibernateJavaTypeMapper"
/>
其中destination是生成的映射文件的目錄,你可以自己修改到合適的路徑
Package屬性你指定你的類的包名,genXDocletTags是是否在映射文件中產生Xdoclet,如果為true,則在映射文件中會加人Xdoclet,生成Java源代碼時這些Xdoclet也會被抽取到Java源代碼中。
指定好以上參數后我們就可以運行build.xml文件了,你要先搭建好Ant構建環境。到達build.xml文件所在的目錄后從命令行輸入ant,middlegen就會自動運行了,如下圖:
我們可以改變兩個實體的關系和方向,默認它會生成雙向關系。點擊每個實體可以修改它的一些配置。修改好后點擊Generate就可以產生Hibernate映射文件了,全部生產在你之前指定的目錄下。查看它生成的文件我們會發現它生成的映射文件并不完美,它把那些多對多關系的交叉表也生成了,而且在生成的映射文件中的多對多的關系配置還有點問題,但是用工具生成比手工編寫出錯的幾率要小得多,而且效率也要高得多,在項目的初期我們可以使用這個工具大規模的生成映射文件,在中、后期如果我們對Java文件或者映射文件進行重構后我們就不應該使用Middlegen了,而是通過正向工程來同步三者。
4、 對上一步生成的映射文件做好修改后我們就可以生成Java源文件了。我們可以用Hibernate Synchronizer Eclipse插件來生成,也可以直接用Myeclipse生成(如果你已經裝了的話)。如果使用Myeclipse生成Java源代碼,我們只需要右鍵點擊映射文件,然后選擇Myeclipse選項的子選項Gen POJO,生成的Java源代碼默認和映射文件在同一目錄下。如果裝了Hibernate Synchronizer Eclipse插件,右鍵點擊映射文件你會看到Synchronizer選項,生成的方式與Myeclipse基本上一樣。
5、 生成的Java源代碼和上面用面向對象方法時我們在Java源代碼中加入Xdoclet后基本上一樣的。需要注意的是如果我們需要對數據庫表字段進行修改,我們不再使用Middlegen了,否則它重新生成的映射文件會把我們已經修改的映射文件給覆蓋掉,而我們應該用面向對象的方式從Java源代碼到映射文件在到數據庫表,或者我們完全可以以映射文件中的Xdoclet為中心,向上生成Java源代碼,向下生成數據庫表,這些根據你的喜好,兩者沒有太大的區別。
下面我來總結一下我對E-R建模的一些看法:
優點:工具生成代碼效率高,而且不易出錯,可用于項目初期大規模生成映射文件,在日常的項目中是用得最多的。
缺點:工具并不是萬能的,生成的代碼并不盡善盡美。而且在用Middlegen生成的那一步中,如果表很多時在它的那個圖形用戶界面顯示出來的實體將慘不忍睹,密密麻麻,可能你沒有耐心去調整那些實體的關系了。
綜上所訴,目前我們在開發面向對象應用時還不能完全拋棄E-R建模,因為目前還沒有哪個工具足夠強大從對象模型到Java源代碼在到映射文件和數據庫表的自動完美的構建,所以我們在開發項目時應該根據實際情況進行選擇,比如說如果公司有一批精通數據庫建模的精英隊伍,那我們就要充分利用這些寶貴的資源,而不是一味的采取面向對象的思想去開發。
posted on 2007-08-27 09:26 hijackwust 閱讀(552) 評論(0) 編輯 收藏