隨筆 - 115  文章 - 481  trackbacks - 0
          <2006年11月>
          2930311234
          567891011
          12131415161718
          19202122232425
          262728293012
          3456789

          常用鏈接

          留言簿(19)

          隨筆檔案(115)

          文章檔案(4)

          新聞檔案(1)

          成員連接

          搜索

          •  

          最新評(píng)論

          閱讀排行榜

          評(píng)論排行榜

          在最近的一個(gè)項(xiàng)目中,使用了 hibernate+struts ,由于中間沒(méi)有使用 spring 來(lái)管理 bean ,所以我使用了 DAO+Service 來(lái)做持久層和業(yè)務(wù)層。受 spring 對(duì) hibernate template 的封裝的影響,我自己實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的 hibernateTemplate —— MHibernateTemplate 和調(diào)用接口 MHibernateCallback 。在其中包裝了錯(cuò)誤攔截等動(dòng)作。所以我的 DAO 就不能直接從 Myecipse 生成了。但由于 Domain bean 太多,而且 DAO 中又是簡(jiǎn)單的代碼重復(fù),所以想到了使用代碼生成。剛開始想直接在 Myeclipse 中生成 DAO 的時(shí)候使用自己的模版就可以了,但是在網(wǎng)上找了半天都沒(méi)有相關(guān)的信息。后來(lái)模仿 easyjtools 使用 velocity 自己做代碼生成,但感覺(jué)時(shí)間不夠,所以,就選擇了 XDoclet 。

          ?????? 網(wǎng)上相關(guān)的內(nèi)容不是很多,所以就只有啃 En 版的 XDoclet in Action 。由于我的需求很簡(jiǎn)單,所以只使用了簡(jiǎn)單的 template (就是 .xdt )來(lái)生成代碼,搞了兩天,效果還不錯(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)簽都很簡(jiǎn)單易懂;

          <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è)問(wèn)題,

          1 就是標(biāo)簽的嵌套,比如 <XDtPrimitive:upperName value='<XDtField:fieldTagValue tagName="ref.model" paramName="name" />' /> ,開始內(nèi)部標(biāo)簽都使用轉(zhuǎn)義符,結(jié)果搞不定,網(wǎng)上找沒(méi)有任何相關(guān)的內(nèi)容,后來(lái)直接在外層使用 (就象 js ),搞定。

          2 就是對(duì)于標(biāo)簽的內(nèi)容的首字符大寫,沒(mé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" /> 來(lái)應(yīng)用就直接能在模版文件中使用 <XDtPrimitive:upperName > 來(lái)使用了,

          下面是 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è)是代碼。

          于是我的工作就很簡(jiǎn)單了,適用 Myeclipse 直接從 DataExplor 中生成 Domain bean 和映射文件,改一下關(guān)聯(lián),在 domain 中添加必要的 XDoclet 標(biāo)記, build ,就可以專著于具體的業(yè)務(wù)了。

          但這個(gè)代碼還有點(diǎn)問(wè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 中有沒(méi)有直接使用標(biāo)簽來(lái)定義標(biāo)簽的功能,或者在模版內(nèi)定義變量??

          easyjweb 使用 XDoclet 來(lái)生成代碼也會(huì)是很簡(jiǎn)單而且穩(wěn)定的。

          (注:本文作者,EasyJF開源團(tuán)隊(duì) stef_wu,轉(zhuǎn)載請(qǐng)保留作者聲明!)

          posted on 2006-11-28 09:51 簡(jiǎn)易java框架 閱讀(1911) 評(píng)論(0)  編輯  收藏

          只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 子长县| 曲阜市| 门头沟区| 彝良县| 子长县| 台山市| 北辰区| 东丽区| 清原| 丰城市| 黄石市| 阳城县| 铜梁县| 富宁县| 图木舒克市| 石楼县| 九台市| 博白县| 嫩江县| 虎林市| 任丘市| 昭觉县| 全椒县| 沙河市| 环江| 沁阳市| 呼伦贝尔市| 安乡县| 秦皇岛市| 垫江县| 孟村| 从江县| 满城县| 林州市| 蒲城县| 泸水县| 乳源| 英超| 扶余县| 勃利县| 霸州市|