首先聲明,這個(gè)名字如有雷同,純屬巧合。坦率說,這個(gè)工具由來已久,早在遠(yuǎn)古時(shí)代、大概去年就已經(jīng)有了早期的雛形。形成的原因主要是因?yàn)槲疫@個(gè)人比較懶,寫了一些jdbc的程序發(fā)現(xiàn)我本可以生活的更輕松一些,而對現(xiàn)存的一些方案(BMP/CMP、JDO、Hibernate等)又有這樣或那樣的問題(其中也有一部分原因是我實(shí)在懶的去深入的學(xué),而且我用到的也遠(yuǎn)沒有那么深)。所以這個(gè)sdo工具誕生了!之所以我稱它“簡單”數(shù)據(jù)庫對象化代碼生成工具,是因?yàn)椤!!!`牛拇_太簡單了,也只能適合簡單應(yīng)用。
交代了一些背景,說點(diǎn)實(shí)在的吧,你可以從我的文件夾中下載它的首映式版本(
http://www.aygfsteel.com/Files/kobe2000/sdo_0.6.rar),目前定價(jià)0.6,嗯,或許還高了些,讓我們看看它能做什么:
1、首先,你需要寫一個(gè)xml形式的配置文件(說不定我以后會(huì)寫一個(gè)桌面程序或者從數(shù)據(jù)源中抽取數(shù)據(jù)的程序簡化這一步,但實(shí)際上徒手寫也是很容易的),來描述數(shù)據(jù)庫中表的結(jié)構(gòu)(索引、視圖、數(shù)據(jù)字典等等我并沒有做什么處理,老實(shí)說,忽略了),如下面的例子
<?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="傳入的參數(shù):待查找的名字"/>
</find>
<find name="findFemale" sql="WHERE GENDER=0" multi="true" desc="查找所有女性"/>
<tostring name="NAME"/>
</table>
<table name="STUDENT" type="Student" extends="ManKind" desc="學(xué)生" serialize="12344321">
<fd name="SID" type="String" desc="學(xué)號"/>
<fk name="MASTER" type="Teacher" desc="班主任"/>
<custom name="getNumOfStudent" sql="SELECT COUNT(*) FROM STUDENT" multi="false" desc="計(jì)算學(xué)生總數(shù)">
<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的設(shè)置是為了中文可以正確被解析
<sdo>元素是根元素,package屬性為代碼生成的包路徑,pool屬性的意義稍后敘述、closestmt是告訴工具是否需要關(guān)閉Statement。(有些連接池如果你關(guān)閉Statement會(huì)拋出異常,的確很bt)
<table>元素顧名思義是代表一個(gè)表了,name屬性是數(shù)據(jù)表的名稱,如果是空,那么就代表沒有這個(gè)表,只是為抽象數(shù)據(jù)使用(或者說為繼承使用)。type屬性為映射到j(luò)ava源文件中的類名稱,extends屬性為父類的類名,子類可以繼承父類的字段以及find方法(哈!看到了么?這個(gè)工具支持表間的繼承!這才是對象化!)。
<pk><fd><fk>分別代表主鍵、字段和外鍵。name屬性代表字段名,type屬性代表類型。目前此工具只支持單一主鍵,并且類型只能為int、long或String。普通字段的類型可以是byte、short、int、long、float、double、BigDecimal、boolean、String、byte[]、Date、Time、Timestamp或者任意實(shí)現(xiàn)Serializable的可序列化的類名(比如Color),它們與數(shù)據(jù)庫類型的對應(yīng)關(guān)系見JDBC相關(guān)介紹,如果類型是可序列化類,則數(shù)據(jù)庫類型要求是二進(jìn)制類型。外鍵fk的類型為對應(yīng)表所對應(yīng)的類名稱。
<find>元素生成查找本類的相關(guān)代碼,name為方法名,sql為WHERE子句(可包含PreparedStatement的?符號),multi屬性指定返回的個(gè)數(shù)為單個(gè)還是多個(gè),如果多個(gè),工具可生成分頁查詢方法。
<find>元素的子元素為<param>元素,代表傳入的參數(shù),name屬性為參數(shù)名稱,當(dāng)name屬性是以"this."開頭的時(shí)候,代表這個(gè)參數(shù)由此對象的對象變量替代。
<custom>為自定義方法,name屬性為方法名,sql屬性為sql語句,multi屬性同<find>元素
<custom>除了包含<param>子元素(同<find>)外,還可以指定一個(gè)或多個(gè)<return>元素,代表自定義方法的返回值。
<tostring>元素可生成toString方法,name屬性代表對應(yīng)字段。
<handword>元素為手寫部分,location屬性決定手寫部分的位置。
2、這個(gè)表對應(yīng)的數(shù)據(jù)庫例如可以如下:
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
)
創(chuàng)建過程中可以省略主鍵限制和外鍵的關(guān)聯(lián)關(guān)系,因?yàn)楣ぞ呱傻拇a保證了對應(yīng)聯(lián)系。
3、運(yùn)行工具生成代碼
用法: java kobe.util.sdo.SDOBuilder [選項(xiàng)] 描述文件
其中選項(xiàng)可能為:
-d <目錄> 指定輸出源文件目錄
-i 打印輸出詳細(xì)信息
使用非常簡單,不過抱歉-i選項(xiàng)目前只是個(gè)擺設(shè)
4、然后讓我們看看如何使用
首先,先要實(shí)現(xiàn)這個(gè)接口已提供數(shù)據(jù)庫連接
public interface ConPool {
Connection getCon();
void closeCon(Connection con);
}
public class MyPool implements ConPool {...}
然后來寫測試代碼
public void testSDO() {
//設(shè)置連接,請注意這里的"def"它和上面配置文件中的"def"所對應(yīng),意思是說我們生成的這兩個(gè)對象使用
//這個(gè)連接進(jìn)行數(shù)據(jù)庫操作,如果不寫的話,默認(rèn)為_default(見工具源碼或生成的代碼)
SDOContext.setPool("def", new MyPool());
try {
SDOContext.beginTransaction();//標(biāo)志事務(wù)開始
Student s = Student.create();//自動(dòng)創(chuàng)建,創(chuàng)建機(jī)制見生成的代碼
System.out.println("create student: " + s.getId());
//設(shè)置相關(guān)字段并更新
s.setName("小明");
s.setGender(true);
s.update();
//創(chuàng)建一個(gè)教師
Master m = Master.create(1);//通過手動(dòng)傳入主鍵創(chuàng)建記錄
m.setName("四大名捕");
m.setMarried(false);
m.update();
//設(shè)置外鍵
s.setMaster(m);
s.update();
//簡單操作
List list = new ArrayList();
int n = Student.findByName(list, "小明");//n 為符合要求的結(jié)果數(shù)量
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("學(xué)生總數(shù)為:" + Student.getNumOfStudent());
SDOContext.commitTransaction();
} catch(SDOException e) {
SDOContext.rollbackTransaction();
throw e;
}
}嘿嘿,如果我不告訴你這是數(shù)據(jù)庫程序,你不會(huì)看出來吧?
我自己覺得這個(gè)工具是相當(dāng)好用的,所以拿出來show一下,如果你有什么問題或者好的建議,I will be so appreciate~
(具體的使用方法請參考生成的代碼和工具源碼,關(guān)于文檔的缺乏我深表歉意。。。)
posted on 2005-11-28 13:56
WebWheel 閱讀(631)
評論(0) 編輯 收藏