将XML结点转换成JAVABEAN并存入数据库

http://tech.ddvip.com   2007年07月03日    社区交流

内容摘要:动解析的过程中,我们仍然发现各个结点的解析和入库中有很多东西是共同的,或者有共同的规律,这些东西可以抽出来作为一个准框架,然后再将结点中不同的部分开放出来,允许具体的结点做具体的实现,并最终形成一个半自动的解析/入库框架。

  b.默认的实现

import java.lang.reflect.Field;
import java.util.*;
import org.apache.commons.beanutils.PropertyUtils;
import org.dom4j.Attribute;
import org.dom4j.Element;
/**
* 默认的BUSI NODE。 继承此类的BUSI NODE 需满足 所有不可分属性集=String类型的属性集
* MyUtils类的代码欠奉
*
*/
public abstract class DefaultBusiNode implements BusiNode {
  public List getAtomicPropNames() {
    return MyUtils.getFieldNamesOfClass(this.getClass(), String.class);
  }
  public List getBusiNodePropNames() {
    return MyUtils.getFieldNamesOfClass(this.getClass(), BusiNode.class);
  }
  /*
   * 所有子元素的父元素。有时是本结点,有时是本结点下的元素。变态
   */
  public abstract Element getXmlElementParent(Element rootElement);
  /*
   * 类集子结点根元素的Iterator 。 假设一个pig有多个pighead,
   * 那结构可能为 pig--pighead,pighead,...,
   * 也可能为pig--pigheads--content,content....
   * 必须让程序知道某个具体结点用的是哪种模式
   *
 
   * 如果为空则返回一个空类集的Iterator ,不要返回NULL
   */
  public abstract Iterator getCollectionElementIterator(
      Element xmlElementParent, String attName);
  /**
   * 解析XML属性
   *
   * @param rootElement
   */
  protected void parseAttributesFromXml(Element rootElement) {
    List xmlAttributes = this.getXmlAttributes();
    for (int i = 0; i < this.getXmlAttributes().size(); i++) {
      String attName = (String) xmlAttributes.get(i);
      Attribute att = rootElement.attribute(attName);
      if (att != null) {
        try {
          PropertyUtils.setProperty(this, attName, att.getValue());
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
    }
  }
  /**
   * 解析不可分的Element
   *
   * @param rootElement
   */
  protected void parseAtomicElementFromXml(Element rootElement) {
    Element xmlElementParent = getXmlElementParent(rootElement);
    if (xmlElementParent == null) {
      return;
    }
    List xmlElements = this.getXmlAtomicElements();
    for (int i = 0; i < xmlElements.size(); i++) {
      String attName = (String) xmlElements.get(i);
      Element elmt = xmlElementParent.element(attName);
      if (elmt != null) {
        try {
          PropertyUtils.setProperty(this, attName, elmt.getText());
        } catch (Exception e) {
          throw new RuntimeException(e);
        }
      }
    }
  }
  /**
   * 解析BusiNode属性
   *
   * @param rootElement
   */
  protected void parseBusiNodeElementFromXml(Element rootElement) {
    Element xmlElementParent = getXmlElementParent(rootElement);
    if (xmlElementParent == null) {
      return;
    }
    // 再解析BusiNode属性
    List busiNodePropNames = this.getBusiNodePropNames();
    for (int i = 0; i < busiNodePropNames.size(); i++) {
      try {
        String attName = (String) busiNodePropNames.get(i);
        Element elmt = xmlElementParent.element(attName);
        if (elmt != null) {
          Field field = this.getClass().getDeclaredField(attName);
          BusiNode att = (BusiNode) field.getType().newInstance();
          att.parseFromXML(elmt);
          PropertyUtils.setProperty(this, attName, att);
        }
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
  }
  /**
   * 解析类集属性
   *
   * @param rootElement
   */
  protected void parseCollectionPropsFromXml(Element rootElement) {
    // 先解析XML属性
    Element xmlElementParent = getXmlElementParent(rootElement);
    if (xmlElementParent == null) {
      return;
    }
    // 最后解析类集属性
    Map collectionPropsMap = this.getCollectionPropsMap();
    for (Iterator it = collectionPropsMap.keySet().iterator(); it.hasNext();) {
      try {
        String attName = (String) it.next();
        Collection coll = (Collection) PropertyUtils.getProperty(this,
            attName);
        Class attType = (Class) collectionPropsMap.get(attName);
        Iterator collElementsIt = this.getCollectionElementIterator(
            xmlElementParent, attName);
        // xmlElementParent.elementIterator(attName);
        while (collElementsIt.hasNext()) {
          Element collElmt = (Element) collElementsIt.next();
          BusiNode sinlgeAtt = (BusiNode) attType.newInstance();
          sinlgeAtt.parseFromXML(collElmt);
          coll.add(sinlgeAtt);
        }
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
  }
  /**
   * 从XML中解析出结点。此方法可能抛出RumtimeException
   */
  public void parseFromXML(Element rootElement) {
    
    this.parseAttributesFromXml(rootElement);
    this.parseAtomicElementFromXml(rootElement);
    this.parseBusiNodeElementFromXml(rootElement);
    this.parseCollectionPropsFromXml(rootElement);
  }
}
/**
* 入库
* JdbcUtil,MyUtils的代码欠奉
*
*/
public class BusiNodeDAO {
  
  private Long saveBusiNode(BusiNode node, Long parentNodeId) {
    // 先存储原子属性
    Long id = saveBareBusiNode(node, parentNodeId);
    // 再存储类集属性
    Map collectionPropsMap = node.getCollectionPropsMap();
    for (Iterator it = collectionPropsMap.keySet().iterator(); it.hasNext();) {
      String attName = (String) it.next();
      Collection coll = null;
      try {
        coll = (Collection) PropertyUtils.getProperty(node, attName);
      } catch (Exception e) {        
        throw new RuntimeException("编码错误");
      }
      for (Iterator iitt = coll.iterator(); iitt.hasNext();) {
        BusiNode subNode = (BusiNode) iitt.next();
        saveBusiNode(subNode, id);
      }
    }
    // 最后存储所有BusiNode属性
    Iterator iitt = node.getBusiNodePropNames().iterator();
    while (iitt.hasNext()) {
      BusiNode subNode = null;
      try {
        subNode = (BusiNode) PropertyUtils.getProperty(node,
            (String) iitt.next());
      } catch (Exception e) {        
        throw new RuntimeException("编码错误");
      }
      if (subNode != null) {
        saveBusiNode(subNode, id);
      }
    }
    return id;
  }
  /**
   * 插入某个BusiNode的根结点,此方法可能抛出RuntimeException
   *
   * @param node
   * @return
   */
  private Long saveBareBusiNode(BusiNode node, Long parentNodeId) {
    StringBuffer sbForSql = new StringBuffer();
    List paramValues = new ArrayList();
    genInsertSqlAndParam(node, parentNodeId, node.getAtomicPropNames(),
        sbForSql, paramValues);
    return new Long(JdbcUtil.queryForLong(
        sbForSql.toString(), paramValues.toArray()));
  }
  /**
   * 生成某个结点的插入语句和paramValues数组,此方法可能抛出RuntimeException
   *
   * @param node
   * @param columnNames
   * @param sbForSql
   * @param paramValues
   */
  private void genInsertSqlAndParam(BusiNode node, Long parentNodeId,
      List columnNames, StringBuffer sbForSql, List paramValues) {
    sbForSql.append(" insert into ");
    sbForSql.append(MyUtils.getClassBareName(node.getClass()));
    List cns = new ArrayList();
    cns.addAll(columnNames);
    cns.add("parentNodeId");
    sbForSql.append(MyUtils.encloseWithCurve(MyUtils
        .joinCollectionStrings(cns, ",")));
    sbForSql.append(" values ");
    List qms = new ArrayList(); // 问号
    for (Iterator it = columnNames.iterator(); it.hasNext();) {
      qms.add("?");
      String cn = (String) it.next();
      try {
        paramValues.add(PropertyUtils.getProperty(node, cn));
      } catch (Exception e) {
        throw new RuntimeException(e);
      }
    }
    qms.add("?"); // parentNodeId
    paramValues.add(parentNodeId);
    sbForSql.append(MyUtils.encloseWithCurve(MyUtil
        .joinCollectionStrings(qms, ",")));
    sbForSql.append(";select @@identity");
  }
}

责编:豆豆技术应用

正在加载评论...