隨筆 - 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ù),所以想到了使用代碼生成。剛開(kāi)始想直接在 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)類(lèi)型信息

          ??? /**

          ??? ? * @ref .model name="sytp"

          ??? ? */

          ??? private PubSystype sytp ;

          ??? // 公司性質(zhì)編碼

          ??? private String cproCode ;

          ??? // 公司性質(zhì)名稱(chēng)

          ??? 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),

          在寫(xiě)這個(gè)模版的時(shí)候,我遇到了幾個(gè)問(wèn)題,

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

          2 就是對(duì)于標(biāo)簽的內(nèi)容的首字符大寫(xiě),沒(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 ,就可以專(zhuān)著于具體的業(yè)務(wù)了。

          但這個(gè)代碼還有點(diǎn)問(wèn)題就是當(dāng)遇到一個(gè)類(lèi)有多個(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開(kāi)源團(tuán)隊(duì) stef_wu,轉(zhuǎn)載請(qǐng)保留作者聲明!)

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

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


          網(wǎng)站導(dǎo)航:
           
          主站蜘蛛池模板: 石城县| 集安市| 阳山县| 上栗县| 昌江| 莎车县| 石屏县| 永平县| 舟曲县| 贵州省| 海南省| 江油市| 从化市| 克山县| 积石山| 金乡县| 高清| 鹤峰县| 镇安县| 阜阳市| 贵阳市| 库尔勒市| 辰溪县| 观塘区| 读书| 乾安县| 山东省| 高台县| 沙河市| 阜平县| 阜新市| 宁安市| 红桥区| 城固县| 宝兴县| 兖州市| 河间市| 壤塘县| 淄博市| 新竹县| 蓬安县|