Teambiz中從Sql到XML的轉(zhuǎn)化過程
作者:何楊
撰寫日期:2012年2月23日
版本:1.00
更新日期:2012年2月24日
第一部分:功能說明
將后臺(tái)編寫的SQL語(yǔ)句,向數(shù)據(jù)庫(kù)請(qǐng)求后獲得的數(shù)據(jù),整理成XML格式的文本。
第二部分:核心組件
名稱 | 路徑 | 說明 |
JdbcDao | com.ibm.heyang.dao.base.JdbcDao | 此類中的fetchRecords函數(shù)用來取得數(shù)據(jù)庫(kù)中的數(shù)據(jù), |
NameValueRowMapper | com.ibm.heyang.dao.rowmapper.NameValueRowMapper | 此類用于將進(jìn)行數(shù)據(jù)庫(kù)查詢得到的行集轉(zhuǎn)化為一個(gè)NameValue鏈表對(duì)象。 |
NameValue | com.ibm.heyang.domain.NameValue | 此類用于存儲(chǔ)行集中某字段的名稱和值,在將對(duì)象鏈表轉(zhuǎn)化為XML的過程中使用了它的函數(shù)asXML()。 |
NameValueList | com.ibm.heyang.domain.NameValueList | 內(nèi)含一個(gè)鏈表,用于容納NameValue對(duì)象鏈表,在將對(duì)象鏈表轉(zhuǎn)化為XML的過程中使用了它的函數(shù)asXML()。 |
第三部分:從SQL語(yǔ)句向XML的轉(zhuǎn)化過程
NameValueRowMapper負(fù)責(zé)查詢結(jié)果集一個(gè)行的轉(zhuǎn)換,對(duì)于其中的每個(gè)字段,會(huì)形成一個(gè)字段名和字段值的NamaValue對(duì)象,然后放到一個(gè)類型為L(zhǎng)ist<NameValue>的鏈表中。最終,這個(gè)鏈表對(duì)應(yīng)著這個(gè)行集,鏈表里面的每個(gè)元素對(duì)應(yīng)著一個(gè)字段(包含其名及值)。
NameValueList用于容納每個(gè)行形成的鏈表,它本身和查詢結(jié)果集是對(duì)應(yīng)的。
得到最終的NameValueList之后,調(diào)用其asXML方法,將遍歷其中的每個(gè)元素,得到行集鏈表,再遍歷其中的NameValue對(duì)象,再調(diào)用每個(gè)對(duì)象的asXML函數(shù),得到XML文本。
以下展示了兩個(gè)關(guān)鍵函數(shù):
NameValueList對(duì)象的asXML函數(shù)如下:
public String asXML() {
StringBuilder sb=new StringBuilder();
for(Object obj:list){
List<NameValue> ls=(List<NameValue>)obj;
sb.append("<node>");
for(NameValue nv:ls){
sb.append(nv.asXML());
}
sb.append("</node>");
}
return sb.toString();
}
以上粗體部分是每個(gè)行的標(biāo)志,在前臺(tái)頁(yè)面對(duì)XML進(jìn)行解析時(shí)還要使用到它,這已經(jīng)形成了前后臺(tái)之間的一個(gè)約定。
NameValue對(duì)象的asXML函數(shù)如下:
public String asXML() {
StringBuilder sb=new StringBuilder();
sb.append("<"+name+">");
sb.append(StringUtils.isBlank(value)?"-":value);
sb.append("</"+name+">");
return sb.toString();
}
第四部分:效果展示
SQL語(yǔ)句示例:
select text, url, level from teambiz_menu where level<=2 order by level
使用SQL語(yǔ)句從數(shù)據(jù)庫(kù)查詢出來的結(jié)果集:

最終得到的XML文本:
<node>
<text>登出</text>
<url>Logout.do</url>
<level>0</level>
</node>
<node>
<text>修改自己信息</text>
<url>Goto.do?page=/page/jsp/user/modify/index.jsp</url>
<level>1</level>
</node>
<node>
<text>建立聯(lián)系</text>
<url>Goto.do?page=/page/jsp/relation/create/index.jsp</url>
<level>1</level>
</node>
<node>
<text>我發(fā)出去的聯(lián)系</text>
<url>Goto.do?page=/page/jsp/relation/sent/index.jsp</url>
<level>1</level>
</node>
<node>
<text>發(fā)給我的聯(lián)系</text>
<url>Goto.do?page=/page/jsp/relation/received/index.jsp</url>
<level>1</level>
</node>
<node>
<text>創(chuàng)建任務(wù)</text>
<url>Goto.do?page=/page/jsp/task/create/index.jsp</url>
<level>1</level>
</node>
<node>
<text>我發(fā)出去的任務(wù)</text>
<url>Goto.do?page=/page/jsp/task/sent/index.jsp</url>
<level>1</level>
</node>
<node>
<text>發(fā)給我的任務(wù)</text>
<url>Goto.do?page=/page/jsp/task/received/index.jsp</url>
<level>1</level>
</node>
<node>
<text>今日待辦任務(wù)/已辦任務(wù)</text>
<url>Goto.do?page=/page/jsp/task/tododone/index.jsp</url>
<level>1</level>
</node>
<node>
<text>用戶管理</text>
<url>#</url>
<level>2</level>
</node>
第五部分:使用步驟
步驟 | 說明 | 參照 |
編寫SQL語(yǔ)句 | 編寫一個(gè)正確的查詢語(yǔ)句,建議使用SqlToolBox進(jìn)行整形工作。 | 類com.ibm.heyang.dao.MenuDao中的函數(shù)getMenuByUserLevel中的SQL語(yǔ)句。 |
使用fetchRecords函數(shù)得到結(jié)果集。 | 這個(gè)函數(shù)處于com.ibm.heyang.dao.base.JdbcDao類中,無(wú)需改動(dòng),只需要傳入正確的sql語(yǔ)句和RowMapper即可。 | 類com.ibm.heyang.dao.MenuDao中的函數(shù)getMenuByUserLevel中的List<?> ls=super.fetchRecords(sql,new NameValueRowMapper());一句。 |
將結(jié)果集用NameValueList包裝起來 | 將結(jié)果集傳入NameValueList類的構(gòu)造函數(shù)即可。 | 類com.ibm.heyang.dao.MenuDao中的函數(shù)getMenuByUserLevel中的return new NameValueList(ls);一句。 |
將結(jié)果集轉(zhuǎn)化為XML | 使用NameValueList類的asXML函數(shù)。 | com.ibm.heyang.service.MenuService的getMenuByUserLevel函數(shù)。 |
第六部分:小結(jié)
編寫SQL語(yǔ)句并將其轉(zhuǎn)化為前臺(tái)可以辨識(shí)的格式是程序員的主要工作負(fù)擔(dān),采用以上方式的好處有:
1.整個(gè)過程中,一個(gè)函數(shù)fetchRecords和三個(gè)對(duì)象NameValueRowMapper,NameValue,NameValueList都是系統(tǒng)提供的,程序員無(wú)需編碼,而只需把SQL語(yǔ)句寫好,放到DAO類的一個(gè)函數(shù)中就可以了。
2.任何查詢類的SQL語(yǔ)句,無(wú)論字段類型如何,都可以用如上方式處理。
3.如果有特殊的查詢方式,com.ibm.heyang.dao.rowmapper下還提供了很多類供使用,如針對(duì)select count(*) from tb的IntegerRowMapper類,針對(duì)select * from tb where id=XX 的MapRowMapper類,及將將一行記錄轉(zhuǎn)化成一個(gè)包含鍵值對(duì)的鏈表的StringRowMapper等,用戶也可參照UserRowMapper來書寫自己的RowMapper類。這些類的使用將給編碼帶來較大遍歷,關(guān)于它們將另行文詳述。