其它技术和Hibernate-XDoclet
使用Hibernate,对实体类,需要Map 文件,XDoclet在写类时加入类似Javadoc的@hibernate.xxx 指示,然后用XDoclet自动生成Map 文件,使写程序更加方便。
使用XDoclet一般使用Ant,在build.xml中加入XDoclet的部分。XDoclet需要有相应的jar文件支持,不过,因为XDoclet是在Ant运行时使用的,所以XDoclet的jar可以不放在webapps\..\WEB-INF\lib下,可另外放一个目录(有时XDoclet的jar会和其它的jar冲突)
从XDoclet网上下 xdoclet.zip 或tar.gz,可放在一个单独的目录,如lib-xdoc下,一般需要:(以1.2版本为例)
xdoclet-1.2.jar
xdoclet-xdoclet-module-1.2.jar
xdoclet-hibernate-module-1.2.jar
xjavadoc-1.0.2.jar
其它的通用的jar,Hibernate等也用到,如commons-logging-x.x.x.jar,xerces-x.x.x.jar,可放在lib目录下。
目录结构WEB-INF
lib
lib-xdoc
src
classes
build.xml
web.xml
这样,在Ant 的build.xml中同时加入lib 和 lib-xdoc下的jars,编译时用到 XDoclet,运行时就不用XDoclet了。
build.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project name="Test" default="compile" basedir=".">
<property name="classes" location="./classes"/>
<property name="src" value="src" />
<property name="db" value="db" />
<property name="lib" value="lib" />
<property name="lib-xdoc" value="lib-xdoc" />
<property name="build" value="classes" />
<path id="myclasspath">
<fileset dir="${lib}">
<include name="*.jar"/>
</fileset>
<fileset dir="${lib-xdoc}">
<include name="*.jar"/>
</fileset>
<pathelement location="${build}"/>
</path>
<target name="init">
<mkdir dir="${classes}"/>
</target>
<target name="compile" depends="init">
<javac executable="jikes" classpathref="myclasspath" srcdir="${src}" destdir="${classes}"/>
</target>
<target name="clean">
<delete dir="${classes}"/>
</target>
<target name="xdoc" description="Generates Hibernate class descriptor files.">
<taskdef name="hibernatedoclet"
classname="xdoclet.modules.hibernate.HibernateDocletTask">
<classpath refid="myclasspath"/>
</taskdef>
<hibernatedoclet
destdir="${classes}"
excludedtags="@version,@author,@todo"
force="true"
verbose="true">
<fileset dir="${src}">
<include name="**/*.java"/>
</fileset>
<hibernate version="2.0"/>
</hibernatedoclet>
</target>
<!-- Other target omited -->
</project>
使用XDoclet 的例子:
例1.Org.java 表示一个公司的各个组织,组成一个树形结构,就是一个Org 可能有一个父的Org
用many-to-one/one-to-many,用同一个column(parent) 指向本身(bean.Org),有一个用inverse
package bean;
import java.util.*;
/**
* @hibernate.class table="test_org"
*/
public class Org extends Persistent{
//注:id在Persistent中
private String name;
private Org parent;
private Set children=new TreeSet();
/**
* @hibernate.property length="60"
*/
public String getName(){
return name;
}
public void setName(String value){
name=value;
}
/**
* @hibernate.many-to-one class="bean.Org" column="parent"
*/
public Org getParent(){
return parent;
}
public void setParent(Org value){
parent=value;
}
/**
* @hibernate.set inverse="true" lazy="true" cascade="all"
* @hibernate.collection-key column="parent"
* @hibernate.collection-one-to-many class="bean.Org"
*/
public Set getChildren(){
return children;
}
public void setChildren(Set value){
children=value;
}
}
Persistent.java
package bean;
import net.sf.hibernate.Validatable;
import net.sf.hibernate.ValidationFailure;
/**
* @hibernate.class table="test_persistent"
*/
public class Persistent implements Validatable{
protected int id;
/**
* @hibernate.id generator-class="increment" type="int" unsaved-value="null"
*/
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public void validate() throws ValidationFailure {
}
}
自动生成的Map 文件如下:
Org.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 2.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">
<hibernate-mapping>
<class
name="bean.Org"
table="test_org"
dynamic-update="false"
dynamic-insert="false">
<id
name="id"
column="id"
type="int"
unsaved-value="null">
<generator class="increment">
</generator>
</id>
<property
name="name"
type="java.lang.String"
update="true"
insert="true"
column="name"
length="60"/>
<many-to-one
name="parent"
class="bean.Org"
cascade="none"
outer-join="auto"
update="true"
insert="true"
column="parent"/>
<set
name="children"
lazy="true"
inverse="true"
cascade="all"
sort="unsorted">
<key
column="parent"/>
<one-to-many
class="bean.Org"/>
</set>
</class>
</hibernate-mapping>
例2.用户(User)和职位(Position),一个用户可有多个职位,可用many-to-may 关系
用的表是同一个(test_user_position),在Position中用"inverse",实现双向关联(Bidirectional Associations)
Users.java:
package bean;
import java.util.*;
/**
* @hibernate.class table="test_user"
*/
public class User extends Persistent{
//......
private Set positions=new TreeSet();
/**
* @hibernate.set table="test_user_position" lazy="true"
* @hibernate.collection-key column="user_id"
* @hibernate.collection-many-to-many class="bean.Position" column="position_id"
*/
public Set getPositions(){
return positions;
}
public void setPositions(Set value){
positions=value;
}
}
Position.java
package bean;
import java.util.*;
/**
* @hibernate.class table="test_position"
*/
public class Position extends Persistent{
//......
private Set users=new TreeSet();
/**
* @hibernate.set inverse="true" lazy="true" table="test_user_position"
* @hibernate.collection-key column="position_id"
* @hibernate.collection-many-to-many class="bean.User" column="user_id"
*/
public Set getUsers(){
return users;
}
public void setUsers(Set value){
users=value;
}
}
小结:
使用XDoclet,可方便生成Hibernate 的Map文件,加快开发。
注意事项:使用双向关联(Bidirectional Associations)时相应的column一定要正确,否则XDoclet不会报错,但是生成的数据库表不正确。
参考:
Hibernate 主站:www.hibernate.org
Hibernate Xdoclet:http://www.chinaunix.net/jh/26/92019.html
XDoclet 主站:http://xdoclet.sourceforge.net/