on the road

working hard

 
 Blog首页我的首页 我的文章我的像册我的圈子后台管理给我留言聚合
当前位置:首页-on the road->文章内容
使用XDoclet生成代码
评论数(3) 阅读次数(754)发布时间:2006-11-27 15:33

使用XDoclet生成代码

在最近的一个项目中,使用了hibernate+struts,由于中间没有使用spring来管理bean,所以我使用了DAO+Service来做持久层和业务层。受springhibernatetemplate的封装的影响,我自己实现了一个简单的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);

    }

   

    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);

    }

}

这是个比较复杂的模版了,是DAO的具体实现,

在写这个模版的时候,我遇到了几个问题,

1 就是标签的嵌套,比如<XDtPrimitive:upperName value='<XDtField:fieldTagValue tagName="ref.model" paramName="name" />' />,开始内部标签都使用转义符,结果搞不定,网上找没有任何相关的内容,后来直接在外层使用(就象js),搞定。

2 就是对于标签的内容的首字符大写,没有提供这个功能的标签,使用了自定义的:

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" />来应用就直接能在模版文件中使用<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" />