使用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语句中别名的书写和根节点子节点的书写了,这样乏味的工作得到了简化,出错的几率也大大减小了。
以上代码可以从这里下载,需要的包请自行导入。