在最近的一個(gè)項(xiàng)目中,使用了
hibernate+struts
,由于中間沒有使用
spring
來管理
bean
,所以我使用了
DAO+Service
來做持久層和業(yè)務(wù)層。受
spring
對(duì)
hibernate
的
template
的封裝的影響,我自己實(shí)現(xiàn)了一個(gè)簡單的
hibernateTemplate
——
MHibernateTemplate
和調(diào)用接口
MHibernateCallback
。在其中包裝了錯(cuò)誤攔截等動(dòng)作。所以我的
DAO
就不能直接從
Myecipse
生成了。但由于
Domain bean
太多,而且
DAO
中又是簡單的代碼重復(fù),所以想到了使用代碼生成。剛開始想直接在
Myeclipse
中生成
DAO
的時(shí)候使用自己的模版就可以了,但是在網(wǎng)上找了半天都沒有相關(guān)的信息。后來模仿
easyjtools
使用
velocity
自己做代碼生成,但感覺時(shí)間不夠,所以,就選擇了
XDoclet
。
??????
網(wǎng)上相關(guān)的內(nèi)容不是很多,所以就只有啃
En
版的
XDoclet in Action
。由于我的需求很簡單,所以只使用了簡單的
template
(就是
.xdt
)來生成代碼,搞了兩天,效果還不錯(cuò)。
??????
比如一個(gè)
model
:(這個(gè)項(xiàng)目的需求比較奇怪,由于要同步,所以每個(gè)對(duì)象都必須有一個(gè)
pkid
(包括中間表),
2
就是每個(gè)對(duì)象有個(gè)
dr
標(biāo)志,表示刪除(而不是真正的刪除))。
??????
package
com.my.xdoclet;
/**
?
*
PubCompproper
generated
by
MyEclipse
-
Hibernate
Tools
?
*
@hasRef
?
*
公司性質(zhì)
?
*/
?
public
class
PubCompproper
extends
BaseDomain
implements
java.io.Serializable {
?
???
// Fields
???
/**
???
?
*
@pkid
???
?
*/
???
private
String
cproPkid
;
???
//
系統(tǒng)類型信息
???
/**
???
?
*
@ref
.model
name="sytp"
???
?
*/
???
private
PubSystype
sytp
;
???
//
公司性質(zhì)編碼
???
private
String
cproCode
;
???
//
公司性質(zhì)名稱
???
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
;
??? }
}
?
其中有一些相關(guān)的對(duì)象,在
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);
???
??? //
得到一個(gè)對(duì)象
??? <XDtClass:className /> get(String pkid);
}
這個(gè)是
interface
的模版,其中的模版標(biāo)簽都很簡單易懂;
<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);
??? }
???
??? public List list(boolean withDr) {
?????? // TODO Auto-generated method stub
?????? if(withDr){
?????????? return HibernateCodeUtil.listWithDr("<XDtClass:className />","<XDtField:forAllFields><XDtField:ifHasFieldTag tagName="del"><XDtField:fieldName /></XDtField:ifHasFieldTag></XDtField:forAllFields>" );
?????? }else{
?????????? return this.template.getAll(<XDtClass:className />.class);
?????? }
??? }
???
??? public boolean update(<XDtClass:className /> instance) {
?????? // TODO Auto-generated method stub
?????? <XDtClass:ifHasClassTag tagName="hasRef">
?????? <XDtClass:className /> temp=this.get(instance.get<XDtField:forAllFields><XDtField:ifHasFieldTag tagName="pkid" ><XDtPrimitive:upperName value="<XDtField:fieldName />" /></XDtField:ifHasFieldTag></XDtField:forAllFields>());
?????? <XDtField:forAllFields>
?????????? <XDtField:ifHasFieldTag tagName="ref.model" paramName="name">????????
????????????? if(instance.get<XDtPrimitive:upperName value='<XDtField:fieldTagValue tagName="ref.model" paramName="name" />' />()==null){????????????????
????????????????? instance.set<XDtPrimitive:upperName value='<XDtField:fieldTagValue tagName="ref.model" paramName="name" />' />(temp.get<XDtPrimitive:upperName value='<XDtField:fieldTagValue tagName="ref.model" paramName="name" />' />());
????????????? }
?????????? </XDtField:ifHasFieldTag>
?????? </XDtField:forAllFields>
??????
?????? </XDtClass:ifHasClassTag>
?????? return this.template.update(instance);
??? }
}
這是個(gè)比較復(fù)雜的模版了,是
DAO
的具體實(shí)現(xiàn),
在寫這個(gè)模版的時(shí)候,我遇到了幾個(gè)問題,
1
就是標(biāo)簽的嵌套,比如
<XDtPrimitive:upperName value='<XDtField:fieldTagValue tagName="ref.model" paramName="name" />' />
,開始內(nèi)部標(biāo)簽都使用轉(zhuǎn)義符,結(jié)果搞不定,網(wǎng)上找沒有任何相關(guān)的內(nèi)容,后來直接在外層使用
’
(就象
js
),搞定。
2
就是對(duì)于標(biāo)簽的內(nèi)容的首字符大寫,沒有提供這個(gè)功能的標(biāo)簽,使用了自定義的:
package com.my.xdoclet.customTags;
?
import java.util.Properties;
?
import xdoclet.XDocletTagSupport;
?
public class UpperName extends XDocletTagSupport {
??? public String upperName(Properties attribute){
?????? String value=attribute.getProperty("value");
?????? String upper= upper(value);
?????? return upper;
??? }
???
??? private static String upper(String value){
?????? return value.toUpperCase().substring(0,1)+value.substring(1);
??? }
}
并在模版文件中使用
<XDtTagDef:tagDef namespace="Primitive" handler="com.my.xdoclet.customTags.UpperName" />
來應(yīng)用就直接能在模版文件中使用
<XDtPrimitive:upperName >
來使用了,
下面是
bulid.xml
文件:
<?xml version="1.0" encoding="UTF-8"?>
?
<project
name=
"xdocletExample"
default=
"doall"
basedir=
"."
>
???
<property
name=
"xdoclet.lib.dir"
location=
"${basedir}/lib"
/>
???
<property
name=
"gen.src.dir"
location=
"${basedir}/target"
/>
???
<property
name=
"src.dir"
location=
"${basedir}/src"
/>
???
<property
name=
"template.dir"
location=
"${basedir}/template"
/>
???
<property
name=
"customtag.dir"
location=
"${basedir}/bin"
/>
?
???
<path
id=
"xdoclet.lib.path"
>
??????
<fileset
dir=
"${xdoclet.lib.dir}"
includes=
"*.jar"
/>
???
</path>
?
???
<taskdef
name=
"xdoclet"
classname=
"xdoclet.DocletTask"
classpathref=
"xdoclet.lib.path"
/>
???
???
???
<target
name=
"init"
/>
?
???
<target
name=
"daogener"
depends=
"init"
>
??????
<xdoclet
destdir=
"${gen.src.dir}"
>
??????????
<fileset
dir=
"${src.dir}"
includes=
"**/*.java"
/>
??????????
<template
templateFile=
"${template.dir}/daointerface.xdt"
acceptInterfaces=
"false"
acceptAbstractClasses=
"false"
destinationfile=
"{0}DAO.java"
/>
??????
</xdoclet>
???
</target>
?
???
<target
name=
"daoimplgener"
depends=
"init"
>
??????
<xdoclet
destdir=
"${gen.src.dir}"
>
??????????
<fileset
dir=
"${src.dir}"
includes=
"**/*.java"
/>
??????????
<template
templateFile=
"${template.dir}/daoimpl.xdt"
acceptInterfaces=
"false"
acceptAbstractClasses=
"false"
destinationfile=
"{0}DAOImpl.java"
/>
??????
</xdoclet>
???
</target>
?
???
<target
name=
"doall"
depends=
"daogener,daoimplgener"
/>
</project>
?
build
一下:
生成的代碼如下:
package com.hycs.bs.client.itf;
?
import java.util.List;
?
import com.my.xdoclet.PubCompproper;
?
public interface PubCompproperDAO {
??? //
添加
??? boolean add(PubCompproper instance);
??? //
添加
??? boolean add(PubCompproper instance, String sytppkid);??
??? //
刪除
??? boolean del(String pkid);
??? //
更新
??? boolean update(PubCompproper instance);
??? //
列出所有
??? List list();
??? List list(boolean withDr);
??? //
得到一個(gè)對(duì)象
??? PubCompproper get(String pkid);
}
這個(gè)是接口
?
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 PubCompproperDAOImpl implements PubCompproperDAO{
??? private MHibernateTemplate template;
?????????? private final com.my.xdoclet.PubSystypeDAO sytpdao = new com.my.xdoclet.PubSystypeDAOImpl();
??? public PubCompproperDAOImpl(){
?????? this.template=new MHibernateTemplate(HibernateUtil.getSessionFactory());
??? }
??? public boolean add(PubCompproper 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);
??? }
??? public boolean add(PubCompproper instance,? String sytppkid) {
?????? // TODO Auto-generated method stub
????????????? com.my.xdoclet.PubSystype sytp=this.sytpdao.get(sytppkid);
????????????? if(sytp==null){
????????????????? return false;
????????????? }
????????????? instance.setSytp(sytp);
?????? return this.add(instance);
??? }
??? public boolean del(String pkid) {
?????? // TODO Auto-generated method stub
?????? PubCompproper instance =this.get(pkid);
?????? if(instance==null||instance.getCproPkid==null){
?????????? return false;
?????? }
?????? instance.setCproDr(Constant.MODEL_DEL);
?????? return this.template.update(instance);
??? }
??? public PubCompproper get(String pkid) {
?????? // TODO Auto-generated method stub
?????? return (PubCompproper)this.template.get(PubCompproper.class, pkid);
??? }
??? public List list() {
?????? // TODO Auto-generated method stub
?????? return this.list(true);
??? }
??? public List list(boolean withDr) {
?????? // TODO Auto-generated method stub
?????? if(withDr){
?????????? return HibernateCodeUtil.listWithDr("PubCompproper","cproDr" );
?????? }else{
?????????? return this.template.getAll(PubCompproper.class);
?????? }
??? }
??? public boolean update(PubCompproper instance) {
?????? // TODO Auto-generated method stub
?????? PubCompproper temp=this.get(instance.getCproPkid());
????????????? if(instance.getSytp()==null){????????????????
????????????????? instance.setSytp(temp.getSytp());
????????????? }
?????? return this.template.update(instance);
??? }
}
這個(gè)是代碼。
于是我的工作就很簡單了,適用
Myeclipse
直接從
DataExplor
中生成
Domain bean
和映射文件,改一下關(guān)聯(lián),在
domain
中添加必要的
XDoclet
標(biāo)記,
build
,就可以專著于具體的業(yè)務(wù)了。
但這個(gè)代碼還有點(diǎn)問題就是當(dāng)遇到一個(gè)類有多個(gè)關(guān)聯(lián)對(duì)象的時(shí)候,在生成的一些方法上,要自己手動(dòng)增加或者刪除一個(gè)
”,”
。這個(gè)還要繼續(xù)學(xué)習(xí)。
同時(shí)
XDoclet
提供了很好的擴(kuò)展機(jī)制,這個(gè)也要繼續(xù)研究。
再次就是我在想
XDoclet
中有沒有直接使用標(biāo)簽來定義標(biāo)簽的功能,或者在模版內(nèi)定義變量??
easyjweb
使用
XDoclet
來生成代碼也會(huì)是很簡單而且穩(wěn)定的。
(注:本文作者,EasyJF開源團(tuán)隊(duì) stef_wu,轉(zhuǎn)載請(qǐng)保留作者聲明!)
posted on 2006-11-28 09:51
簡易java框架 閱讀(1907)
評(píng)論(0) 編輯 收藏