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

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