当柳上原的风吹向天际的时候...

真正的快乐来源于创造

  BlogJava :: 首页 :: 联系 :: 聚合  :: 管理
  368 Posts :: 1 Stories :: 201 Comments :: 0 Trackbacks

如果需要将表数据转化为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 何杨(heyang78@gmail.com)
 *
 * 
@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语句中别名的书写和根节点子节点的书写了,这样乏味的工作得到了简化,出错的几率也大大减小了。

以上代码可以从这里下载,需要的包请自行导入。
posted on 2009-10-27 10:13 何杨 阅读(283) 评论(0)  编辑  收藏