如鹏网 大学生计算机学习社区

CowNew开源团队

http://www.cownew.com 邮件请联系 about521 at 163.com

  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理 ::
  363 随笔 :: 2 文章 :: 808 评论 :: 0 Trackbacks


CowNew开源团队网站 http://www.cownew.com
作者 杨中科 是CowNew开源团队发起人之一,邮箱about521  at 163 dot com
论坛 http://www.cownew.com/newpeng/
转载请注明此版权信息


   最近准备把进销存项目激活,这样一方面可以让更多的人有机会参与到开源开发中来,另一方面也把SQL翻译器、SQL优化器、JDBMonitor应用到这个项目中,这样这三个基础模块就可以在实际项目应用中得到验证和增强。
    我准备用hibernate实现持久层,于是到hibernate的网站上把hibernate3下载下来,看了看有个hibernatetools,是个hibernate在eclipse下的辅助工具,也down了下来,用了用感觉不错。可以直接从数据库表生成POJO和hbm.xml(其实我不是很喜欢这种开发方式,我更喜欢我用建模工具来写POJO,然后用工具生成hbm.xml和DDL,不过好像hibernate3现在还没有这种工具,如果哪位朋友知道有这种工具,希望赐教)。
美中不足的是它生成的javabean的字段名是完全和数据库字段名一致、生成的javabean的类名是完全和数据库表名一致。出于清晰以及可移植的考虑(也是公司的开发规范养成的习惯),我设计的表名全部以"T_"开头,中间再加上子系统名,最后才是表意的表名,比如用“T_PS_BOM”表示生产管理系统中的物料清单表;字段名全部以“F”开头,比如FId,FName。
这样就导致生成了如下的javabean:

public class TPSBOM
{
   .......
   public String getFID()
   ...
   public String getFNumber()
}


    看起来很不直观。我刚刚想放弃这个工具,想了想,“拿来就用,不好用就换”可不是做开源人该有的精神呀。钻研一下。
看看了Hibernate Code Generation页签中有一个“reveng Strategy”,什么意思?“反向工程策略”??好像有门儿,点击“Browse”弹出一个类选择对话框,竟然看到了它默认显示的“DefaultReverseEngineeringStrategy”类了,我在hibernatetools的安装目录找来找去,终于在plugins\org.hibernate.eclipse_3.2.0.beta6\lib\tools下的hibernate-tools.jar中找到了这个类的影子,用反编译工具反编译一下(懒得去网上下源码了,呵呵)。一个个方法名展现在我面前:
tableToClassName
columnToPropertyName
columnToHibernateTypeName
。。。
    这不就是在把数据库相应的项映射成java相应的项吗?
    开工!
    新建一个类CowNewReverseEngineeringStrategy,继承自DefaultReverseEngineeringStrategy,override  tableToClassName、
columnToPropertyName这两个方法,在这两个方法中写入自己的转换逻辑。
然后打包成jar包,放到plugins\org.hibernate.eclipse_3.2.0.beta6\lib\tools下,然后在plugins\org.hibernate.eclipse_3.2.0.beta6\lib\tools\MANIFEST.MF中把这个新增包的内容加上,关闭eclipse,加个-clean参数启动eclipse,然后点击“Hibernate Code Generation”,把“reveng Strategy”填成“com.cownew.DevTools.hibtools.RevEng.CowNewReverseEngineeringStrategy”,“Run”!!!
晕倒,竟然报错“com.cownew.DevTools.hibtools.RevEng.CowNewReverseEngineeringStrategy
Exception while generating code
Reason   org.hibernate.console.HibernateConsoleRunTimeException:Could not create or find com.   with one argument deleate constructor”

看来是反射调用的时候出了问题,重新打开hibernate-tools.jar,仔细观察,竟然发现了一个DelegatingReverseEngineeringStrategy,它多    了一个参数为“ReverseEngineeringStrategy delegate”的构造函数,而其他调用都是转发给ReverseEngineeringStrategy了,晕倒,搞不懂它在做什么,也没时间研究了,给CowNewReverseEngineeringStrategy也曾街一个参数为“ReverseEngineeringStrategy delegate”的构造函数,重新打包,重新启动eclipse,哈哈,一切搞定,终于生成我可爱的,
public class PersonInfo

  public String getNumber()。。。
  public String getId()。。。

了。
    附全部代码:

package com.cownew.DevTools.hibtools.RevEng;

import java.beans.Introspector;

import org.hibernate.cfg.reveng.DefaultReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.ReverseEngineeringSettings;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategy;
import org.hibernate.cfg.reveng.ReverseEngineeringStrategyUtil;
import org.hibernate.cfg.reveng.TableIdentifier;
import org.hibernate.util.StringHelper;

public class CowNewReverseEngineeringStrategy extends
DefaultReverseEngineeringStrategy
{

 public CowNewReverseEngineeringStrategy(ReverseEngineeringStrategy delegate)
 {  
  super();
 }

 private ReverseEngineeringSettings settings = new ReverseEngineeringSettings();

 public String tableToClassName(TableIdentifier table)
 {
  String tableName = table.getName();
  if (tableName != null && tableName.toUpperCase().startsWith("T_"))
  {
   String pkgName = settings.getDefaultPackageName();
   int lastIndex = tableName.lastIndexOf('_');
   tableName = tableName.substring(lastIndex + 1, tableName.length())
     + "Info";

   String className = toUpperCamelCase(tableName);

   if (pkgName.length() > 0)
    return StringHelper.qualify(pkgName, className);
   return className;

  } else
  {
   return super.tableToClassName(table);
  }
 };

 public String columnToPropertyName(TableIdentifier table, String column)
 {
  if (column != null && column.toUpperCase().startsWith("F"))
  {
   String cownewColName = column.substring(1, column.length());
   
   String decapitalize = Introspector
     .decapitalize(toUpperCamelCase(cownewColName));
   return keywordCheck(decapitalize);
  } else
  {
   return super.columnToPropertyName(table, column);
  }
 }

 private String keywordCheck(String possibleKeyword)
 {
  if (ReverseEngineeringStrategyUtil
    .isReservedJavaKeyword(possibleKeyword))
   possibleKeyword += "_";
  return possibleKeyword;
 }

 public void setSettings(ReverseEngineeringSettings settings)
 {
  super.setSettings(settings);
  this.settings = settings;
 }

 public static void main(String[] args)
 {
  TableIdentifier table = new TableIdentifier("T_BD_Person");
  //TableIdentifier table = new TableIdentifier("T_Person");
  //TableIdentifier table = new TableIdentifier("Person");
  CowNewReverseEngineeringStrategy revEng = new CowNewReverseEngineeringStrategy(null);
  String className = revEng.tableToClassName(table);
  System.out.println(className);
  System.out.println(revEng.columnToPropertyName(table, "FId"));
  System.out.println(revEng.columnToPropertyName(table, "Id"));
 }
}


 

posted on 2006-07-16 22:27 CowNew开源团队 阅读(1501) 评论(4)  编辑  收藏

评论

# re: cownew开源-给hibernateTools写个插件 2006-07-17 01:08 原创专栏 开源学习
你们太孤陋寡闻了。
轮子轮子轮子。

你们这个团队应该多考察考察,跟得上时代。与时俱进呀

不过好像hibernate3现在还没有这种工具,如果哪位朋友知道有这种工具,希望赐教

XDoclet
XDoclet
XDoclet
XDoclet
XDoclet
  回复  更多评论
  

# re: cownew开源-给hibernateTools写个插件 2006-07-17 08:26 mixlee11
这种东西还是自己写一个的好。
我刚开始的时候也是在网上找,找了好几个都不如意。
自己写一个一晚上搞定,结果找插件的时间都浪费好几天。
用freemarker做模板自己开发,可以在建模的时候把注释也写进数据库,
然后可以把字段的remark读出来写进自己的pojo里,中文注释在生成代码的时候就同时搞定。当然类名字段名你想怎么生成都可以啦,所以靠别人不如靠自己。  回复  更多评论
  

# re: cownew开源-给hibernateTools写个插件 2006-07-17 16:44 霉干菜
@原创专栏 开源学习

我觉得作者说的不是XDoclet这个意思,我估计他想要达到的是通过UML建摸直接通过工具生成数据库表,猜测而已  回复  更多评论
  

# re: cownew开源-给hibernateTools写个插件 2006-07-17 19:47 CowNew开源团队
感谢各位指教.在公司一直是用公司自己开发的ORMMaping引擎,所以开源的ORM工具用的机会少一些,hibernate也是去年评估各个开源ORM工具的优劣的时候简单用了一下,所以难免才疏学浅.
正如霉干菜说的,我真正想要的工具是我画类图就可以了,然后所有的我不关心的java代码和配置文件都自动生成,这样能有更多精力投入业务开发和整体技术 业务框架的搭建。
如果再找不到能满足要求的开源工具的话,也许自己写一个也不错,呵呵,先做成codegenerate工具,然后逐步转化成一个元数据驱动的东西,呵呵美极美极,这一直都是我的梦想却没时间去做的东西。  回复  更多评论
  


只有注册用户登录后才能发表评论。


网站导航: