使用Metadata簡化表數據向XML形式轉化的實現
如果需要將表數據轉化爲XML形式數據的話,如果我們使用Spring的JDBC Template,那麼常需要做的工作是創建一個RowMapper匿名類,在其中將字段與領域對象的某個屬性匹配上,然後得到領域對象鏈表形式的結果,此後展開這個集合,再將字段轉化爲XML數據,其中進行了兩次名稱和值之間的匹配,硬編碼較多,比較費時間。如果我們利用Metadata(Metadata是解釋數據的數據,如果我們的研究對象是表格中的數據,那麼表頭就是表格中數據的Metadata)則可以有效簡化這一過程。
下面先看需求,有一個emp僱員表,表中包括id,姓名name,年齡age和地址addr四個字段,如下所示:
我們需要把表中的記錄取出並變成如下格式的字符串:
<employees>
<employee>
<id>1</id>
<name>andy</name>
<age>31</age>
<address>54435454</address>
</employee>
<employee>
<id>2</id>
<name>bill</name>
<age>32</age>
<address>rwerewrqeqw</address>
</employee>
<employee>
<id>3</id>
<name>cindy</name>
<age>33</age>
<address>342554345</address>
</employee>
<employee>
<id>4</id>
<name>douglas</name>
<age>34</age>
<address>rtwetr23423</address>
</employee>
<employee>
<id>5</id>
<name>edin</name>
<age>35</age>
<address>rfwsr34223</address>
</employee>
</employees>
下面是負責取出數據的DAO類:
package com.heyang.dao;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.List;
import org.springframework.jdbc.core.RowMapper;
import com.heyang.dao.base.Dao;
import com.heyang.domain.NameValue;
/** *//**
* 用於行業和類別的Dao
* @author
*
* @since 2008-8-27 上午10:24:38
* @version 1.00
*/
public class EmpDao extends Dao{
/** *//**
* 取得僱員鏈表
* @return
*/
@SuppressWarnings("unchecked")
public List<List<NameValue>> getAll(){
String sql = " select id, name, age, addr as address from emp ";
class EmpRowMapper implements RowMapper {
public Object mapRow(ResultSet rs, int index) throws SQLException {
List<NameValue> ls=new ArrayList<NameValue>();
int n=rs.getMetaData().getColumnCount();
for(int i=1;i<=n;i++){
NameValue nv=new NameValue(rs.getMetaData().getColumnName(i),rs.getString(i));
ls.add(nv);
}
return ls;
}
}
return jdbcTemplate.query(sql, new EmpRowMapper());
}
}
這裏沒有用硬編碼的方式從行集中逐個取出字段,而是通過行集的Metadata得到字段的個數,再依次遍歷下去,在循環中得到的字段名稱和字段值放到對象NameValue中,它的代碼如下:
package com.heyang.domain;
/** *//**
* 名稱-值 結構
* @author
* @date 2009-10-26
* @time 下午02:02:00
*/
public class NameValue{
private String name;
private String value;
public NameValue(){
this("","");
}
public NameValue(String name,String value){
this.name=name;
this.value=value;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getValue() {
return value;
}
public void setValue(String value) {
this.value = value;
}
}
將返回的表格數據鏈表變成最終的XML形式字符串的代碼如下:
package com.heyang;
import java.util.List;
import com.heyang.dao.EmpDao;
import com.heyang.domain.NameValue;
import com.heyang.util.SpringUtil;
/** *//**
* 僱員服務類
*
* @author
* @date 2009-10-26
* @time 下午01:35:41
*/
public class EmpService implements IEmp{
/** *//**
* 取得XML形式的僱員列表
*/
public String fetchEmps() {
EmpDao dao=(EmpDao)SpringUtil.getBean("empDao");
StringBuilder sb=new StringBuilder();
List<List<NameValue>> ls=dao.getAll();
sb.append("<employees>");
for(List<NameValue> lsItem:ls){
sb.append("<employee>");
for(NameValue nv:lsItem){
sb.append("<"+nv.getName()+">");
sb.append(nv.getValue());
sb.append("</"+nv.getName()+">");
}
sb.append("</employee>");
}
sb.append("</employees>");
return sb.toString();
}
}從上述代碼中可以見到,除了根節點名employees和子節點名employee外,其它子節點名都不是硬編碼而是從NameValue中取出,這樣就大大減少了硬編碼和逐個匹配的工作量。
綜上所述,由於引入了Metadata的幫助,剩下的主要是sql語句中別名的書寫和根節點子節點的書寫了,這樣乏味的工作得到了簡化,出錯的機率也大大減小了。
以上代碼可以從這裏下載,需要的包請自行導入。