CRUD(Create, Read,Update, Delete)操作中最難處理的是查詢。因?yàn)椴樵兛偸嵌鄻踊模绻總€(gè)特定查詢調(diào)用都編制一個(gè)對(duì)象方法,則維護(hù)量太大且擴(kuò)展性很差。如果編制一個(gè)通用的
查詢接口,一般的做法是直接以SQL文本作為參數(shù),但這樣就幾乎喪失了封裝的意義。這里的核心問(wèn)題是Query本身是復(fù)雜的,我們應(yīng)該將它對(duì)象化為一個(gè)
類,在程序中控制Query的結(jié)構(gòu),而一個(gè)文本對(duì)象與一個(gè)復(fù)雜的Java結(jié)構(gòu)對(duì)象的差異就在于對(duì)于文本對(duì)象我們很難有什么假定,因而在程序中也很難編制通
用的程序?qū)ζ溥M(jìn)行處理,一般只能對(duì)它進(jìn)行傳遞。實(shí)際上,文本中描述的結(jié)構(gòu)存在于java程序之外!當(dāng)然,我們可以利用Parser來(lái)重新發(fā)現(xiàn)這種結(jié)構(gòu),那
最容易使用的Parser就是xml parser了,所以我們應(yīng)該將Query的結(jié)構(gòu)建立在xml描述的基礎(chǔ)上。
edu.thu.search.Query類直接體現(xiàn)了對(duì)主題域的通用查詢條件。(對(duì)比我對(duì)數(shù)據(jù)倉(cāng)庫(kù)模型的描述)
class Query{
List getFields();
TreeNode getCondition();
}
查
詢條件主要通過(guò)TreeNode進(jìn)行顯式建模,使得程序有可能對(duì)它進(jìn)行進(jìn)一步的處理。例如,在DataSource處理Query之前,權(quán)限配置模塊可以
將附加約束直接追加到現(xiàn)有查詢條件之后,實(shí)現(xiàn)對(duì)數(shù)據(jù)權(quán)限的行級(jí)控制。因?yàn)榘袴ields明確分離出來(lái),我們也可以做到對(duì)權(quán)限的列級(jí)控制。
Query類的使用示例如下:
Query.begin().fields(TEST_FIELDS)
.condition().eq(ID,"3")
.end().resultType(IQueriable.TYPE_ROW_MAP)
.findOne(dataSource).mapValue();
這里的調(diào)用接口的設(shè)計(jì)基本遵循與SQL類相同的風(fēng)格,只是面向主題域而不是直接針對(duì)SQL語(yǔ)言的封裝。