随笔-6  评论-7  文章-2  trackbacks-0
    首先声明,这个名字如有雷同,纯属巧合。坦率说,这个工具由来已久,早在远古时代、大概去年就已经有了早期的雏形。形成的原因主要是因为我这个人比较懒,写了一些jdbc的程序发现我本可以生活的更轻松一些,而对现存的一些方案(BMP/CMP、JDO、Hibernate等)又有这样或那样的问题(其中也有一部分原因是我实在懒的去深入的学,而且我用到的也远没有那么深)。所以这个sdo工具诞生了!之所以我称它“简单”数据库对象化代码生成工具,是因为。。。。嗯,它的确太简单了,也只能适合简单应用。
    交代了一些背景,说点实在的吧,你可以从我的文件夹中下载它的首映式版本(http://www.blogjava.net/Files/kobe2000/sdo_0.6.rar),目前定价0.6,嗯,或许还高了些,让我们看看它能做什么:
    1、首先,你需要写一个xml形式的配置文件(说不定我以后会写一个桌面程序或者从数据源中抽取数据的程序简化这一步,但实际上徒手写也是很容易的),来描述数据库中表的结构(索引、视图、数据字典等等我并没有做什么处理,老实说,忽略了),如下面的例子
<?xml version="1.0" encoding="GBK"?>
<sdo package="testpkg" version="0.6" pool="dft" closestmt="false">
  
<table name="" type="ManKind" desc="抽象人类" serialize="1234567">
    
<pk name="ID" type="int" desc="主键"/>
    
<fd name="NAME" type="String" desc="姓名"/>
    
<fd name="BIRTHDAY" type="Date" desc="生日"/>
    
<fd name="GENDER" type="boolean" desc="性别(true:男;false:女)"/>
    
<find name="findByName" sql="WHERE NAME=?" multi="true" desc="通过名字找人">
      
<param name="name" type="String" desc="传入的参数:待查找的名字"/>
    
</find>
    
<find name="findFemale" sql="WHERE GENDER=0" multi="true" desc="查找所有女性"/>
    
<tostring name="NAME"/>
  
</table>
  
<table name="STUDENT" type="Student" extends="ManKind" desc="学生" serialize="12344321">
    
<fd name="SID" type="String" desc="学号"/>
    
<fk name="MASTER" type="Teacher" desc="班主任"/>
    
<custom name="getNumOfStudent" sql="SELECT COUNT(*) FROM STUDENT" multi="false" desc="计算学生总数">
      
<return name="num" type="int" desc="返回值"/>
    
</custom>
  
</table>
  
<table name="Teacher" type="Teacher" extends="ManKind"desc="教师">
    
<fd name="MARRIED" type="boolean" desc="已婚?"/>
       <fd name="IMAGE" type="byte[]" desc="照片"/>
    
<handwork location="class">public void test() {System.out.println("test");}</handwork>
  
</table>
</sdo>
encoding的设置是为了中文可以正确被解析
<sdo>元素是根元素,package属性为代码生成的包路径,pool属性的意义稍后叙述、closestmt是告诉工具是否需要关闭Statement。(有些连接池如果你关闭Statement会抛出异常,的确很bt)
<table>元素顾名思义是代表一个表了,name属性是数据表的名称,如果是空,那么就代表没有这个表,只是为抽象数据使用(或者说为继承使用)。type属性为映射到java源文件中的类名称,extends属性为父类的类名,子类可以继承父类的字段以及find方法(哈!看到了么?这个工具支持表间的继承!这才是对象化!)。
<pk><fd><fk>分别代表主键、字段和外键。name属性代表字段名,type属性代表类型。目前此工具只支持单一主键,并且类型只能为int、long或String。普通字段的类型可以是byte、short、int、long、float、double、BigDecimal、boolean、String、byte[]、Date、Time、Timestamp或者任意实现Serializable的可序列化的类名(比如Color),它们与数据库类型的对应关系见JDBC相关介绍,如果类型是可序列化类,则数据库类型要求是二进制类型。外键fk的类型为对应表所对应的类名称。
<find>元素生成查找本类的相关代码,name为方法名,sql为WHERE子句(可包含PreparedStatement的?符号),multi属性指定返回的个数为单个还是多个,如果多个,工具可生成分页查询方法。
<find>元素的子元素为<param>元素,代表传入的参数,name属性为参数名称,当name属性是以"this."开头的时候,代表这个参数由此对象的对象变量替代。
<custom>为自定义方法,name属性为方法名,sql属性为sql语句,multi属性同<find>元素
<custom>除了包含<param>子元素(同<find>)外,还可以指定一个或多个<return>元素,代表自定义方法的返回值。
<tostring>元素可生成toString方法,name属性代表对应字段。
<handword>元素为手写部分,location属性决定手写部分的位置。

2、这个表对应的数据库例如可以如下:
CREATE TABLE STUDENT (
  ID NUMBER,
  NAME VARCHAR2(30),
  BIRTHDAY DATE,
  GENDER BIT,
  SDI VARCHAR2(30),
  MASTER NUMBER
)
CREATE TABLE TEACHER (
  ID NUMBER,
  NAME VARCHAR2(30),
  BIRTHDAY DATE,
  GENDER BIT,
  MARRIED BIT,
  IMAGE BINARY
)
创建过程中可以省略主键限制和外键的关联关系,因为工具生成的代码保证了对应联系。

3、运行工具生成代码
用法: java kobe.util.sdo.SDOBuilder [选项] 描述文件
其中选项可能为:
-d <目录>    指定输出源文件目录
-i           打印输出详细信息

使用非常简单,不过抱歉-i选项目前只是个摆设

4、然后让我们看看如何使用
首先,先要实现这个接口已提供数据库连接
public interface ConPool {
  Connection getCon();
  void closeCon(Connection con);
}
public class MyPool implements ConPool {...}
然后来写测试代码
public void testSDO() {
//设置连接,请注意这里的"def"它和上面配置文件中的"def"所对应,意思是说我们生成的这两个对象使用
//这个连接进行数据库操作,如果不写的话,默认为_default(见工具源码或生成的代码)
  SDOContext.setPool("def", new MyPool());
  try {
    SDOContext.beginTransaction();//标志事务开始
    Student s = Student.create();//自动创建,创建机制见生成的代码
    System.out.println("create student: " + s.getId());
//设置相关字段并更新
    s.setName("小明");
    s.setGender(true);
    s.update();
//创建一个教师
    Master m = Master.create(1);//通过手动传入主键创建记录
    m.setName("四大名捕");
    m.setMarried(false);
    m.update();
//设置外键
    s.setMaster(m);
    s.update();
//简单操作
    List list = new ArrayList();
    int n = Student.findByName(list, "小明");//n 为符合要求的结果数量
    for(int i=0; i
<n; i++) {
      Student r 
= (Student)list.get(i);
      
System.out.println("找到小明:" + r.getId());
      System.out.println("班主任是:" + r.getMaster().getName());
    }
    System.out.println("学生总数为:" + Student.getNumOfStudent());
    SDOContext.commitTransaction();
  } catch(SDOException e) {
    SDOContext.rollbackTransaction();
    throw e;
  }
}
嘿嘿,如果我不告诉你这是数据库程序,你不会看出来吧?

我自己觉得这个工具是相当好用的,所以拿出来show一下,如果你有什么问题或者好的建议,I will be so appreciate~
(具体的使用方法请参考生成的代码和工具源码,关于文档的缺乏我深表歉意。。。)
posted on 2005-11-28 13:56 WebWheel 阅读(624) 评论(0)  编辑  收藏

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


网站导航: