使用Xdoclet和Ant構建Hibernate映射和配置文件
溫馨提示:由于文檔中含大量圖片,這里不方便一一上傳建議下載本文電子版文檔閱讀
Xdoclet.pdf
本文工程下載
svn地址:http://xdocletdemo.googlecode.com/svn/trunk/
功能描述:
在ssh項目中,你是否存在著這樣一種困惑,那就是需要手動去配置Hibernate的映射文件和配置文件。這個過程是相當痛苦的,需要寫一大堆的的xml文件。Xdoclet就是為了簡化這一工作的。它基于Ant或Maven,可以簡化你的工作,使你在使用Hibernate時,不用在手動去為每個pojo類寫對應的映射文件。當然你可以使用hibernate的注解完成同樣的工作,但具體在ssh的項目中到底是選擇注解方式還是選擇配置方式,這完全取決于你自己或項目經理。關于是否采用注解還是配置文件的來方式來完成hibernate的映射,這個在網上有著很大的爭議。這里我不做過多評價。個人更加傾向于使用配置文件。因為配置文件比較靈活,修改后不用重新編譯成Java字節(jié)碼文件,相反使用注解的話你需要及時的去編譯。好了,話不多說,我們進入正題。
環(huán)境描述:
Eclipse3.6 http://eclipse.org
Ant1.7.1 http://ant.apache.org/
Xdoclet-1.2.3 http://xdoclet.sourceforge.net/xdoclet/index.html
Mysql5.0.22 http://www.mysql.com/
Hibernate3.X http://www.hibernate.org/
WindowsXp sp3
溫馨提示:這里重點需要說明一下此處Xdoclet版本為1.2.3,網上有一些關于Xdoclet的配置是基于1.0.4以前的版本。這兩個版本之間存在著較大的區(qū)別,主要體現(xiàn)在Ant的構建文件build.xml中!請確保你的Xdoclet版本為1.2.3。
Eclipse的安裝就不介紹了。
Ant安裝:
將下載下來的Ant解壓到一個目錄(建議該目錄不含空格),筆者解壓到E:"JAR"apache-ant-1.7.1
Ant解壓后的目錄結構為:
設置環(huán)境變量:
要是Ant能夠正常使用,我們需要設置環(huán)境變量(通常這是在Windows下)
設置ANT_HOME
修改Path
ANT_HOME
Path
查看環(huán)境變量是否設置正確
打開命令行窗口
輸入set ANT_HOME查看ANT_HOME
輸入set Path查看Path
設置正確后在命令行下輸入ant
此時表示已將ant成功安裝到操作系統(tǒng)中了,你可以使用ant的各種功能
Xdoclet-1.2.3安裝
解壓Xdoclet-1.2.3文件
筆者這里解壓到E:"JAR"xdoclet"xdoclet-1.2.3
解壓后的文件格式為:
這里需要記住xdoclet的解壓路徑E:"JAR"xdoclet"xdoclet-1.2.3,因為在Ant構建腳本中需要用到它
Mysql的安裝不用介紹了,相信大家都不陌生。
準備Hibernate依賴的jar
打開eclipse,創(chuàng)建一個Java工程,名為xdoclet
在工程上右鍵添加一個名為build.xml的文件
在工程上右鍵添加一個名為lib的文件夾,拷貝hibernate依賴的jar包及mysql驅動,最后將該lib文件夾設置到classpath路徑下
兩個實體類一個為Group(組),一個為(User)
為了更好的顯示日志信息,添加log4j.properties文件到src路徑下
最后你看到的項目結構應該是這樣的:
配置實體類
User.java
package com.xdoclet.model;
/**
* @hibernate.class
* table="t_user"
* @author welcome
*
*/
publicclass User {
private String userId;
private String userName;
private Group group;
/**
* @hibernate.id column="userId"
* generator-class="assigned"
*/
public String getUserId() {
returnuserId;
}
publicvoid setUserId(String userId) {
this.userId = userId;
}
/**
* @hibernate.property
*/
public String getUserName() {
returnuserName;
}
publicvoid setUserName(String userName) {
this.userName = userName;
}
/**
* @hibernate.many-to-one
* column="groupId"
* cascade="all"
* class="com.xdoclet.model.Group"
* @param group
*/
public Group getGroup() {
returngroup;
}
publicvoid setGroup(Group group) {
this.group = group;
}
}
|
Group.java
package com.xdoclet.model;
import java.util.Set;
/**
* @hibernate.class
* table="t_group"
* @author welcome
*
*/
publicclass Group {
private String groupId;
private String groupName;
private Set userSets;
/**
* @hibernate.id
* column="groupId"
* generator-class="assigned"
* @return
*/
public String getGroupId() {
returngroupId;
}
publicvoid setGroupId(String groupId) {
this.groupId = groupId;
}
/**
* @hibernate.property
* column="groupName"
* @return
*/
public String getGroupName() {
returngroupName;
}
publicvoid setGroupName(String groupName) {
this.groupName = groupName;
}
/**
* @hibernate.set inverse="true"
* @hibernate.collection-key column="groupId"
* @hibernate.collection-one-to-many
* class="com.xdoclet.model.User"
* @return
*/
public Set getUserSets() {
returnuserSets;
}
publicvoid setUserSets(Set userSets) {
this.userSets = userSets;
}
}
|
注意:實體類中的注解,是xdoclet中的,這里不做解釋,具體可以去查看xdoclet關于hibernate的相關文檔
http://xdoclet.sourceforge.net/xdoclet/tags/hibernate-tags.html
log4j.properties配置文件詳情
#All level less than INFO will be logged
log4j.rootLogger=INFO,A1
#A1 is the output device
log4j.appender.A1=org.apache.log4j.FileAppender
log4j.appender.A1.File=e:/log4j.htm
#use html layout
log4j.appender.A1.layout=org.apache.log4j.HTMLLayout
|
此文件會將日志信息記錄為html格式的文件,然后輸出到E盤下,html格式的日志信息看起來更加舒服。不信你可以去你目錄下找找看。
最后我們來關注最重要的文件build.xml
<?xml version="1.0" encoding="UTF-8"?>
<projectname="使用xdoclet映射hibernate"basedir=".">
<!-- 定義源文件目錄變量 -->
<propertyname="src.dir"value="${basedir}/src"/>
<!-- 定義xdoclet的目錄 -->
<propertyname="xdoclet.home"value="E:/JAR/xdoclet/xdoclet-1.2.3"></property>
<!-- 定義構建路徑 -->
<pathid="xdoclet.classpath">
<filesetdir="${xdoclet.home}/lib">
<includename="*.jar"/>
</fileset>
</path>
<pathid="lib.classpath">
<pathelementpath="${java.class.path}"/>
<filesetdir="${xdoclet.home}/lib">
<includename="**/*.jar"/>
</fileset>
<filesetdir="${basedir}/lib">
<includename="**/*.jar"/>
</fileset>
</path>
<!-- 生成Hibernate的映射文件 -->
<targetname="生成Hibernate的映射文件"unless="hibernatedoclet.unnecessary"
description="Generate Hibernate mapping files">
<taskdefname="hibernatedoclet"classname="xdoclet.modules.hibernate.HibernateDocletTask"
classpathref="xdoclet.classpath"/>
<hibernatedocletdestdir="${src.dir}"mergedir="${src.dir}"
excludedtags="@version,@author,@todo,@see"verbose="false">
<filesetdir="${src.dir}">
<includename="com/xdoclet/model/*.java"/>
</fileset>
<hibernateversion="3.0"/>
</hibernatedoclet>
</target>
<!-- 生成Hibernate配置文件 -->
<targetname="生成Hibernate配置文件"depends="生成Hibernate的映射文件">
<taskdefname="hibernatedoclet"classname="xdoclet.modules.hibernate.HibernateDocletTask"
classpathref="xdoclet.classpath"/>
<hibernatedocletdestdir="${src.dir}">
<filesetdir="${src.dir}">
<includename="com/xdoclet/model/*.java"/>
</fileset>
<hibernatecfgdestDir="${src.dir}"version="3.0"
hbm2ddl="create-update"jdbcUrl="jdbc:mysql://localhost:3306/xdoclet"
driver="com.mysql.jdbc.Driver"userName="root"password="root"
dialect="org.hibernate.dialect.MySQL5Dialect"showSql="true">
<otherPropertyname="hbm2ddl"value="create-update"/>
<otherPropertyname="format_sql"value="true"/>
</hibernatecfg>
</hibernatedoclet>
</target>
<!-- 導出數(shù)據(jù)庫表結構 -->
<targetname="導出數(shù)據(jù)庫表結構"depends="生成Hibernate配置文件">
<taskdefname="schemaexport"classname="org.hibernate.tool.hbm2ddl.SchemaExportTask"
classpathref="lib.classpath"/>
<propertyname="hibernate.dialect"value="org.hibernate.dialect.MySQL5Dialect"/>
<propertyname="hibernate.format_sql"value="true"/>
<propertyname="hibernate.use_sql_comments true"value="true"/>
<schemaexport
output="schema-export.sql"
quiet="no"
text="yes"
drop="no"
delimiter=";"
>
<filesetdir="${basedir}/src">
<includename="com/xdoclet/model/*.hbm.xml"/>
</fileset>
</schemaexport>
</target>
</project>
|
關于此文件不想做過多解釋,細心的朋友可以自己去揣摩,前提是你要有ant的基礎知識。
這里需要注意的是這兩個元素
<otherProperty name="hbm2ddl" value="create-update" />
<otherProperty name="format_sql" value="true" />
在xdoclet1.0.4以后的版本中hbm2ddl需要以額外的方式來設置,之前我按照1.0.4版本中的方式去設置,此屬性死活不會出現(xiàn)在hibernate.cfg.xml中,最后得知這是xdoclet的一個bug
詳見:http://jira.codehaus.org/browse/MOJO-466
打開mysql,創(chuàng)建一個名為xdoclet的數(shù)據(jù)庫
在eclipse中運行ant
點window->show view->ant
添加我們的ant腳本到eclipse的ant視圖中
點擊,選擇build.xml文件
在導出數(shù)據(jù)庫表結構上點擊run as ant
此時控制臺輸出:
Buildfile: E:"JAR"jbpm"jbpm-4.3"workspace"xdoclet"build.xml
生成Hibernate的映射文件:
[hibernatedoclet] (XDocletMain.start 47 ) Running <hibernate/>
[hibernatedoclet] Generating mapping file for com.xdoclet.model.Group.
[hibernatedoclet] com.xdoclet.model.Group
[hibernatedoclet] Generating mapping file for com.xdoclet.model.User.
[hibernatedoclet] com.xdoclet.model.User
生成Hibernate配置文件:
[hibernatedoclet] addOtherProperty(): name=null, null
[hibernatedoclet] addOtherProperty(): name=null, null
[hibernatedoclet] (XDocletMain.start 47 ) Running <hibernatecfg/>
[hibernatedoclet] Generating hibernate.cfg.xml configuration file
導出數(shù)據(jù)庫表結構:
[schemaexport] (cfg.Environment 500 ) Hibernate 3.2.0
[schemaexport] (cfg.Environment 533 ) hibernate.properties not found
[schemaexport] (cfg.Environment 667 ) Bytecode provider name : cglib
[schemaexport] (cfg.Environment 584 ) using JDK 1.4 java.sql.Timestamp handling
[schemaexport] (cfg.Configuration 274 ) Reading mappings from file: E:"JAR"jbpm"jbpm-4.3"workspace"xdoclet"src"com"xdoclet"model"Group.hbm.xml
[schemaexport] (cfg.HbmBinder 300 ) Mapping class: com.xdoclet.model.Group -> t_group
[schemaexport] (cfg.Configuration 274 ) Reading mappings from file: E:"JAR"jbpm"jbpm-4.3"workspace"xdoclet"src"com"xdoclet"model"User.hbm.xml
[schemaexport] (cfg.HbmBinder 300 ) Mapping class: com.xdoclet.model.User -> t_user
[schemaexport] (dialect.Dialect 141 ) Using dialect: org.hibernate.dialect.MySQL5Dialect
[schemaexport] (cfg.HbmBinder 2375) Mapping collection: com.xdoclet.model.Group.userSets -> t_user
[schemaexport] (hbm2ddl.SchemaExport 154 ) Running hbm2ddl schema export
[schemaexport] (hbm2ddl.SchemaExport 174 ) writing generated schema to file: E:"JAR"jbpm"jbpm-4.3"workspace"xdoclet"schema-export.sql
[schemaexport]
[schemaexport] alter table t_user
[schemaexport] drop
[schemaexport] foreign key FKCB63CCB6CEAB0634;
[schemaexport]
[schemaexport] drop table if exists t_group;
[schemaexport]
[schemaexport] drop table if exists t_user;
[schemaexport]
[schemaexport] create table t_group (
[schemaexport] groupId varchar(255) not null,
[schemaexport] groupName varchar(255),
[schemaexport] primary key (groupId)
[schemaexport] );
[schemaexport]
[schemaexport] create table t_user (
[schemaexport] userId varchar(255) not null,
[schemaexport] userName varchar(255),
[schemaexport] groupId varchar(255),
[schemaexport] primary key (userId)
[schemaexport] );
[schemaexport]
[schemaexport] alter table t_user
[schemaexport] add index FKCB63CCB6CEAB0634 (groupId),
[schemaexport] add constraint FKCB63CCB6CEAB0634
[schemaexport] foreign key (groupId)
[schemaexport] references t_group (groupId);
[schemaexport] (hbm2ddl.SchemaExport 196 ) schema export complete
BUILD SUCCESSFUL
Total time: 1 second
|
再觀察項目目錄結構
是不是奇跡出現(xiàn)了?不錯,我們做了一大堆工作要的就是這個結果
Group.hbm.xml文件內容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
>
<class
name="com.xdoclet.model.Group"
table="t_group"
>
<id
name="groupId"
column="groupId"
type="java.lang.String"
>
<generator class="assigned">
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-Group.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<property
name="groupName"
type="java.lang.String"
update="true"
insert="true"
column="groupName"
/>
<set
name="userSets"
lazy="false"
inverse="true"
cascade="none"
sort="unsorted"
>
<key
column="groupId"
>
</key>
<one-to-many
class="com.xdoclet.model.User"
/>
</set>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-Group.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
|
User.hbm.xml文件內容
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping
>
<class
name="com.xdoclet.model.User"
table="t_user"
>
<id
name="userId"
column="userId"
type="java.lang.String"
>
<generator class="assigned">
<!--
To add non XDoclet generator parameters, create a file named
hibernate-generator-params-User.xml
containing the additional parameters and place it in your merge dir.
-->
</generator>
</id>
<property
name="userName"
type="java.lang.String"
update="true"
insert="true"
column="userName"
/>
<many-to-one
name="group"
class="com.xdoclet.model.Group"
cascade="all"
outer-join="auto"
update="true"
insert="true"
column="groupId"
/>
<!--
To add non XDoclet property mappings, create a file named
hibernate-properties-User.xml
containing the additional properties and place it in your merge dir.
-->
</class>
</hibernate-mapping>
|
生成的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">
<!-- Generated file - Do not edit! -->
<hibernate-configuration>
<!-- a SessionFactory instance listed as /jndi/name -->
<session-factory>
<!-- properties -->
<property name="dialect">org.hibernate.dialect.MySQL5Dialect</property>
<property name="show_sql">true</property>
<property name="use_outer_join">false</property>
<property name="connection.username">root</property>
<property name="connection.password">root</property>
<property name="connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="connection.url">jdbc:mysql://localhost:3306/xdoclet</property>
<property name="hbm2ddl">create-update</property>
<property name="format_sql">true</property>
<!-- mapping files -->
<mapping resource="com/xdoclet/model/Group.hbm.xml"/>
<mapping resource="com/xdoclet/model/User.hbm.xml"/>
</session-factory>
</hibernate-configuration>
|
是不是跟預期的效果一樣呢?
更為激動的是sql腳本
altertable t_user
drop
foreignkey FKCB63CCB6CEAB0634;
droptable if exists t_group;
droptable if exists t_user;
createtable t_group (
groupId varchar(255) notnull,
groupName varchar(255),
primarykey (groupId)
);
createtable t_user (
userId varchar(255) notnull,
userName varchar(255),
groupId varchar(255),
primarykey (userId)
);
altertable t_user
addindex FKCB63CCB6CEAB0634 (groupId),
addconstraint FKCB63CCB6CEAB0634
foreignkey (groupId)
references t_group (groupId);
|
緊接著就來介紹ExportTable.java文件
package com.xdoclet.export;
import org.hibernate.cfg.Configuration;
import org.hibernate.tool.hbm2ddl.SchemaExport;
public class ExportTable {
public static void main(String[] args) {
Configuration configuration=new Configuration().configure("hibernate.cfg.xml");
SchemaExport export=new SchemaExport(configuration);
export.create(true, true);
}
}
|
很簡單,一看就明白了,趕緊run一把吧!
查看生成的數(shù)據(jù)庫表結構
T_user
T_group
哈哈,終于寫完了。
現(xiàn)在你可以任意刪除*.hbm.xml和hibernate.cfg.xml文件,只需重新運行ant就會再次生成*.hbm.xml和hibernate.cfg.xml文件,是不是很方便?