前面說(shuō)過(guò)所謂的業(yè)務(wù)大多數(shù)是crud。那從這個(gè)入手,我發(fā)現(xiàn)要把這個(gè)配置出來(lái),配置的結(jié)果不言而喻,能生成crud的頁(yè)面。我們其實(shí)只需要一些元數(shù)據(jù)(meta information)。元數(shù)據(jù)就相當(dāng)于我們平常用的hibernate 里面的cfg.xml之類的東西。用來(lái)描述實(shí)體/字段的一些信息。從業(yè)務(wù)的需要來(lái)講,單憑這個(gè)xml的配置還不能生成crud的頁(yè)面。還需要很多的信息。下面是這些字段信息的整理。
TABLENAME | 表名 |
TCOLUMNSNAME | 表字段名 |
TCOLUMNSTYPE | 表字段類型 |
ECOLUMNSNAME | 實(shí)體字段名 |
ECOLUMNSTYPE | 實(shí)體字段java類型 |
COLUMNSLENGTH | 字段長(zhǎng)度 |
COLUMNSNULLABLE | 是否允許為空 |
ISPRIMARYKEY | 是否主鍵 |
STATE | 啟用狀態(tài) |
DESCRIPTION | 描述 |
COLUMNID | 字段序號(hào) |
LABELTEXT | 字段label名稱 |
DEFAULTVALUE | 字段默認(rèn)值 |
CANSEARCH | 是否為查詢字段 |
SEARCHINPUTTYPE | 查詢呈現(xiàn)方式,文本框/下拉框/.. |
SEARCHOPERATOR | 默認(rèn)查詢運(yùn)算符,等于/大于/.. |
FORMAT | 字段顯示格式,日期格式/小數(shù)格式/貨幣格式 |
CSSCLASS | 呈現(xiàn)css class |
READONLY | 編輯時(shí)是否只讀 |
EDITINPUTTYPE | 編輯呈現(xiàn)方式 文本框/下拉框/.. |
CREATESHOW | 新增時(shí)是否顯示 |
UPDATESHOW | 更新時(shí)是否顯示 |
VIEWSHOW | 查看時(shí)是否顯示 |
BLANKMSG | 值為空警告 |
VALIDATETYPE | 校驗(yàn)類型,小數(shù)/整數(shù)/正整數(shù)/.. |
INVALIDMSG | 校驗(yàn)不通過(guò)警告 |
MAPPING | 數(shù)據(jù)字典,其實(shí)就是配置下拉框的通用的數(shù)據(jù)源。比如通常{1:是,0:否}。 |
MAXVALUE | 最大值 |
MINVALUE | 最小值 |
VALIDATEOP | 校驗(yàn)比較類型 |
VALIDATETO | 校驗(yàn)比較對(duì)象表達(dá)式 |
VALIDATEREGEXP | 校驗(yàn)正則表達(dá)式 |
VALIDATEIF | 校驗(yàn)禁用條件 |
CTABLE | 約束表,這4個(gè)屬性生成下拉框數(shù)據(jù)源。 |
CCOEDECOLUMN | 約束值字段 |
CVALUECOLUMN | 約束文本字段 |
CCONDITION | 約束文本字段 |
我估計(jì)很多人看了這些屬性后笑了,的確,很多人這么做過(guò)。后來(lái)發(fā)現(xiàn)這樣做很不靈活,無(wú)法滿足需要,其實(shí)這個(gè)問(wèn)題很簡(jiǎn)單,為什么不應(yīng)用一種表達(dá)式,ognl,el之類的表達(dá)式放在配置項(xiàng)里,這些屬性就靈活很多。siebel這樣的產(chǎn)品,不也有一些地方需要些一個(gè)腳本,比如escript之類的東西么。想想我們天天琢磨的業(yè)務(wù),不就是這些東西么。把它配置到數(shù)據(jù)庫(kù)里面,接下來(lái)就是怎么生成頁(yè)面的么。我看到的目前大多數(shù)的做法是做一個(gè)代碼生成器,我認(rèn)為這種做法很不好,代碼生成器本身是解決了很多機(jī)械活,但是關(guān)鍵還是你生成的代碼本身的質(zhì)量。沒(méi)錯(cuò),你可以用代碼生成器去免去上萬(wàn)行代碼要手寫的尷尬,我不僅要問(wèn),為什么會(huì)弄成上萬(wàn)行的代碼?有的人還喜歡吹噓我寫過(guò)上萬(wàn)行的Java代碼,我更是嗤之以鼻,這不是你的驕傲,這恰是你的悲哀。上萬(wàn)行的代碼,我見(jiàn)過(guò)的有兩種可能性,一個(gè)是java/jsp代碼沒(méi)有重構(gòu),沒(méi)有封裝。二是數(shù)據(jù)庫(kù)的設(shè)計(jì)有問(wèn)題,一個(gè)表200個(gè)字段,頁(yè)面能不復(fù)雜么。第一種是架構(gòu)師要解決的問(wèn)題,第二種那據(jù)是設(shè)計(jì)時(shí)要注意的事情了。扯遠(yuǎn)了。界面是怎么出來(lái)的。至少不是用代碼生成器跑出來(lái)的。接觸過(guò)ruby on rails 或者grails的朋友肯定知道里面的activerecord/scanffold組合快速實(shí)現(xiàn)crud。不過(guò)他說(shuō)白了也是在生成頁(yè)面+改代碼,我還是不喜歡。因?yàn)榻缑娲_實(shí)是太靈活。我的思路分兩個(gè)個(gè)方面入手:1.封裝字段,根據(jù)上述字段屬性封裝成jsp的tag。這個(gè)tag通過(guò)字段名讀取元數(shù)據(jù)屬性,生成瀏覽器執(zhí)行的html,javascript。2:所謂頁(yè)面不久是指定這個(gè)頁(yè)面有哪幾個(gè)字段不就得了。查詢頁(yè)面,那幾個(gè)字段是查詢條件,讀取字段的查詢屬性。編輯頁(yè)面,無(wú)非是指定編輯哪些字段就行,在這個(gè)基礎(chǔ)上做一個(gè)小工具,頁(yè)面就很容易出來(lái)。當(dāng)然,好的框架還要解決一個(gè)問(wèn)題,就是變更。怎樣能以最少的代價(jià)做變更。這個(gè)我是這么想的。比如說(shuō),某個(gè)表刪除一個(gè)字段,我們可以提供一個(gè)工具查詢哪些頁(yè)面引用了這個(gè)字段,然后用程序一并刪除,其實(shí)這個(gè)實(shí)現(xiàn)也不難,因?yàn)槊總€(gè)字段無(wú)非就是jsp頁(yè)面的一個(gè)tag么。大不了用個(gè)全文搜索。用正則一替換就完了。
上面是我總結(jié)的快速實(shí)現(xiàn)crud的一些想法。這部分其實(shí)是很多重復(fù)性勞動(dòng)的根源,把這些工夫省下來(lái)了。開(kāi)發(fā)效率高很多。