在最近的一个项目中,使用了
hibernate+struts
,由于中间没有使用
spring
来管理
bean
,所以我使用了
DAO+Service
来做持久层和业务层。受
spring
对
hibernate
的
template
的封装的影响,我自己实现了一个简单的
hibernateTemplate
——
MHibernateTemplate
和调用接口
MHibernateCallback
。在其中包装了错误拦截等动作。所以我的
DAO
就不能直接从
Myecipse
生成了。但由于
Domain bean
太多,而且
DAO
中又是简单的代码重复,所以想到了使用代码生成。刚开始想直接在
Myeclipse
中生成
DAO
的时候使用自己的模版就可以了,但是在网上找了半天都没有相关的信息。后来模仿
easyjtools
使用
velocity
自己做代码生成,但感觉时间不够,所以,就选择了
XDoclet
。
网上相关的内容不是很多,所以就只有啃
En
版的
XDoclet in Action
。由于我的需求很简单,所以只使用了简单的
template
(就是
.xdt
)来生成代码,搞了两天,效果还不错。
比如一个
model
:(这个项目的需求比较奇怪,由于要同步,所以每个对象都必须有一个
pkid
(包括中间表),
2
就是每个对象有个
dr
标志,表示删除(而不是真正的删除))。
package
com.my.xdoclet;
/**
*
PubCompproper
generated
by
MyEclipse
-
Hibernate
Tools
*
@hasRef
*
公司性质
*/
public
class
PubCompproper
extends
BaseDomain
implements
java.io.Serializable {
// Fields
/**
*
@pkid
*/
private
String
cproPkid
;
//
系统类型信息
/**
*
@ref
.model
name="sytp"
*/
private
PubSystype
sytp
;
//
公司性质编码
private
String
cproCode
;
//
公司性质名称
private
String
cproName
;
//
删除表示
/**
*
@del
*/
private
String
cproDr
;
// Constructors
/**
default
constructor
*/
public
PubCompproper() {
this
.setCproDr(
"0"
);
}
// Property accessors
public
String getCproPkid() {
return
this
.
cproPkid
;
}
public
void
setCproPkid(String
cproPkid
) {
this
.
cproPkid
=
cproPkid
;
}
public
String getCproCode() {
return
this
.
cproCode
;
}
public
void
setCproCode(String
cproCode
) {
this
.
cproCode
=
cproCode
;
}
public
String getCproName() {
return
this
.
cproName
;
}
public
void
setCproName(String
cproName
) {
this
.
cproName
=
cproName
;
}
/**
*
@return
the
sytp
*/
public
PubSystype getSytp() {
return
sytp
;
}
/**
*
@param
sytp
the
sytp
to
set
*/
public
void
setSytp(PubSystype
sytp
) {
this
.
sytp
=
sytp
;
}
/**
*
@return
the
cproDr
*/
public
String getCproDr() {
return
cproDr
;
}
/**
*
@param
cproDr
the
cproDr
to
set
*/
public
void
setCproDr(String
cproDr
) {
this
.
cproDr
=
cproDr
;
}
}
其中有一些相关的对象,在
DAO
中要使用到。
看看模版文件
package com.hycs.bs.client.itf;
import java.util.List;
import <XDtPackage:packageName />.<XDtClass:className />;
public interface <XDtClass:className />DAO {
//
添加
boolean add(<XDtClass:className /> instance);
<XDtClass:ifHasClassTag tagName="hasRef">
//
添加
boolean add(<XDtClass:className /> instance,<XDtField:forAllFields><XDtField:ifHasFieldTag tagName="ref.model" paramName="name"> String <XDtField:fieldTagValue tagName="ref.model" paramName="name" />pkid</XDtField:ifHasFieldTag></XDtField:forAllFields>);
</XDtClass:ifHasClassTag>
//
删除
boolean del(String pkid);
//
更新
boolean update(<XDtClass:className /> instance);
//
列出所有
List list();
List list(boolean withDr);
//
得到一个对象
<XDtClass:className /> get(String pkid);
}
这个是
interface
的模版,其中的模版标签都很简单易懂;
<XDtTagDef:tagDef namespace="Primitive" handler="com.my.xdoclet.customTags.UpperName" />
package com.hycs.bs.client.call;
import com.hycs.bs.sys.MHibernateTemplate;
import com.hycs.util.Constant;
import com.hycs.util.OidHelper;
import com.hycs.bs.sys.HibernateCodeUtil;
import com.hycs.bs.sys.HibernateUtil;
public class <XDtClass:className/>DAOImpl implements <XDtClass:className/>DAO{
private MHibernateTemplate template;
<XDtField:forAllFields>
<XDtField:ifHasFieldTag tagName="ref.model" paramName="name">
private final <XDtField:fieldType/>DAO <XDtField:fieldTagValue tagName="ref.model" paramName="name"/>dao = new <XDtField:fieldType/>DAOImpl();
</XDtField:ifHasFieldTag>
</XDtField:forAllFields>
public <XDtClass:className/>DAOImpl(){
this.template=new MHibernateTemplate(HibernateUtil.getSessionFactory());
}
public boolean add(<XDtClass:className/> instance) {
// TODO Auto-generated method stub
// add your code and pkid generhere;
//instance.setCproCode(HibernateCodeUtil.getLastCode("PubCompproper", "cproCode", "cproPkid"));
//instance.setCproPkid(OidHelper.oidSingle());
return this.template.save(instance);
}
<XDtClass:ifHasClassTag tagName="hasRef">
public boolean add(<XDtClass:className/> instance, <XDtField:forAllFields><XDtField:ifHasFieldTag tagName="ref.model" paramName="name"> String <XDtField:fieldTagValue tagName="ref.model" paramName="name" />pkid</XDtField:ifHasFieldTag></XDtField:forAllFields>) {
// TODO Auto-generated method stub
<XDtField:forAllFields>
<XDtField:ifHasFieldTag tagName="ref.model" paramName="name">
<XDtField:fieldType/> <XDtField:fieldTagValue tagName="ref.model" paramName="name" />=this.<XDtField:fieldTagValue tagName="ref.model" paramName="name"/>dao.get(<XDtField:fieldTagValue tagName="ref.model" paramName="name" />pkid);
if(<XDtField:fieldTagValue tagName="ref.model" paramName="name" />==null){
return false;
}
instance.set<XDtPrimitive:upperName value='<XDtField:fieldTagValue tagName="ref.model" paramName="name" />' />(<XDtField:fieldTagValue tagName="ref.model" paramName="name" />);
</XDtField:ifHasFieldTag>
</XDtField:forAllFields>
return this.add(instance);
}
</XDtClass:ifHasClassTag>
public boolean del(String pkid) {
// TODO Auto-generated method stub
<XDtClass:className /> instance =this.get(pkid);
if(instance==null||instance.get<XDtField:forAllFields><XDtField:ifHasFieldTag tagName="pkid" ><XDtPrimitive:upperName value="<XDtField:fieldName />" /></XDtField:ifHasFieldTag></XDtField:forAllFields>==null){
return false;
}
instance.set<XDtField:forAllFields><XDtField:ifHasFieldTag tagName="del" ><XDtPrimitive:upperName value="<XDtField:fieldName />" /></XDtField:ifHasFieldTag></XDtField:forAllFields>(Constant.MODEL_DEL);
return this.template.update(instance);
}
public <XDtClass:className /> get(String pkid) {
// TODO Auto-generated method stub
return (<XDtClass:className />)this.template.get(<XDtClass:className />.class, pkid);
}
public List list() {
// TODO Auto-generated method stub
return this.list(true);