实战演练:Hibernate映射Oracle的XmlType到Document(xml)对象

实战演练:Hibernate映射Oracle的XmlType到Document(xml)对象
先请参看 上一篇文章

[1]POJO
package com.csc.poimanager.dao;
import org.dom4j.Document;
public class XmlTest implements java.io.Serializable {
    private Long itemId;
    private Long poiId;
    private String itemName;
    private Document itemValue;
    public XmlTest() {
    }
    public XmlTest(String itemName) {
        this.itemName = itemName;
    }
    public Long getItemId() {
        return this.itemId;
    }
    public void setItemId(Long itemId) {
        this.itemId = itemId;
    }
    public Long getPoiId() {
        return this.poiId;
    }
    public void setPoiId(Long poiId) {
        this.poiId = poiId;
    }
    public String getItemName() {
        return this.itemName;
    }
    public void setItemName(String itemName) {
        this.itemName = itemName;
    }
    public Document getItemValue() {
        return this.itemValue;
    }
    public void setItemValue(Document itemValue) {
        this.itemValue = itemValue;
    }
}

[2]自定义映射类型
package com.csc.poimanager.dao.type;
import java.io.Serializable;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import oracle.jdbc.OraclePreparedStatement;
import oracle.jdbc.OracleTypes;
import oracle.jdbc.driver.OracleResultSet;
import oracle.sql.OPAQUE;
import oracle.xdb.XMLType;
import org.dom4j.Document;
import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;
import com.csc.poimanager.util.XmlUtil;
public class PoiAdditionalXmlType implements UserType, Serializable {
    private static final Class returnedClass = String.class; // 属性的java类型
    private static final int[] SQL_TYPES = new int[] { oracle.xdb.XMLType._SQL_TYPECODE }; // 数据中类型
    public int[] sqlTypes() {
        return SQL_TYPES;
    }
    public Class returnedClass() {
        return returnedClass;
    }
    public boolean equals(Object arg0, Object arg1) throws HibernateException {
        if (arg0 == null || arg1 == null) {
            throw new HibernateException("None of the arguments can be null.");
        }
        if (arg0 instanceof oracle.xdb.XMLType
                && arg1 instanceof oracle.xdb.XMLType) {
            return arg0.equals(arg1);
        }
        return false;
    }
    public int hashCode(Object arg0) throws HibernateException {
        return 0;
    }
    public Object nullSafeGet(ResultSet rs, String[] names, Object arg2)
            throws HibernateException, SQLException {
           XMLType xmlType = null;
              Document doc = null;
              try {        
                 OPAQUE value = null;
                 OracleResultSet ors = null;
                 if (rs instanceof OracleResultSet) {
                    ors = (OracleResultSet)rs;
                 } else {
                    throw new UnsupportedOperationException("ResultSet needs to be of type OracleResultSet");
                 }
                 value = ors.getOPAQUE(names[0]);
                 xmlType = XMLType.createXML(value);
                 Clob xmlClob = xmlType.getClobVal();
                 doc = XmlUtil.create(xmlClob.getCharacterStream());
              }finally {
                 if (null != xmlType) {
                    xmlType.close();
                 }
              }
              return doc;
    }
    public void nullSafeSet(PreparedStatement stmt, Object value, int index)
            throws HibernateException, SQLException {
          XMLType xmlType = null;
          try {
             //If the value is null then set NULL and return
             if (null == value) {
                stmt.setNull(index, OracleTypes.OPAQUE, "SYS.XMLTYPE");
                return;
             }
             if (stmt instanceof OraclePreparedStatement) {
                xmlType = XMLType.createXML(stmt.getConnection(), XmlUtil.toPlanString((Document)value));
                OraclePreparedStatement oracleStmt = (OraclePreparedStatement)stmt;
                oracleStmt.setObject(index, xmlType);
             }else {
                throw new HibernateException("PreparedStatement object must be a OraclePreparedStatement");
             }
          }finally {
             if (null != xmlType) {
                xmlType.close();
             }
          }

    }
    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }
    public boolean isMutable() {
        return false;
    }
    public Serializable disassemble(Object arg0) throws HibernateException {
        return null;
    }
    public Object assemble(Serializable arg0, Object arg1)
            throws HibernateException {
        return null;
    }
    public Object replace(Object arg0, Object arg1, Object arg2)
            throws HibernateException {
        return null;
    }
}

[3]映射文件
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
    Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
    <class name="com.csc.poimanager.dao.XmlTest" table="XML_TEST">

        <id name="itemId" type="java.lang.Long">
            <column name="ITEM_ID" precision="10" scale="0" />
            <generator class="increment" />
        </id>

        <property name="poiId" type="java.lang.Long">
            <column name="POI_ID" precision="10" scale="0" />
        </property>

        <property name="itemName" type="java.lang.String">
            <column name="ITEM_NAME" />
        </property>         

        <property name="itemValue" type="com.csc.poimanager.dao.type.PoiAdditionalXmlType" >
            <column name="ITEM_VALUE" />
        </property>

    </class>
</hibernate-mapping>

[4]XmlUtil定义
/**
 *
 */
package com.csc.poimanager.util;

import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.io.StringWriter;

import org.dom4j.Document;
import org.dom4j.DocumentException;
import org.dom4j.DocumentFactory;
import org.dom4j.io.DOMWriter;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.SAXReader;
import org.dom4j.io.XMLWriter;


/**
 * @author zhangyi
 *
 */
public class XmlUtil {

    public static Document create() {
        Document doc = null;
        doc = DocumentFactory.getInstance().createDocument();

        return doc;
    }

    public static Document create(String xmlString) {
       
        StringReader source = new StringReader(xmlString);
       
        return create(source);
    }

    public static Document create(Reader sourceReader) {

        SAXReader reader = new SAXReader();
        Document doc = null;
        try {
            doc = reader.read(sourceReader);
            doc.setXMLEncoding("UTF-8");
        } catch (DocumentException e) {
            e.printStackTrace();
        }


        return doc;
    }

    /**
     * get xml document text
     *
     * @param xmlDoc
     * @return
     */
    public static String toPlanString(Document xmlDoc) {

        StringWriter destWriter = new StringWriter();
       
        XMLWriter writer = new XMLWriter(destWriter,OutputFormat.createPrettyPrint());
       
        try {
            writer.write(xmlDoc);           
           
        } catch (IOException e) {
            e.printStackTrace();
        }
       
        String xmlStr = destWriter.getBuffer().toString();
       
        return xmlStr;
    }

   
   
}

[5]实现insert
       
        XmlTest xt = new XmlTest();
        xt.setItemName("sfsdfsfsdfds");
        xt.setItemValue(XmlUtil.create("<a><b>zhang yi ass</b></a>"));
       
       
        XmlTestDAO xtdao = new XmlTestDAO();
        Session sess = xtdao.getSession();
        Transaction tx = sess.beginTransaction();
       
        xtdao.save(xt);
       
        tx.commit();
        sess.close();
       
        System.out.println("saving xmltest ok ");
       
        执行结果:
        saving xmltest ok

[6]实现查询
                XmlTestDAO xtdao = new XmlTestDAO();
        Session sess = xtdao.getSession();
        Transaction tx = sess.beginTransaction();
        XmlTest xt =xtdao.findById((long)9);
       
        System.out.println("xt item_value : " + xt.getItemName());
        System.out.println("xt item_value : " + xt.getItemValue());
        System.out.println("xt item_value : " + xt.getItemValue().getRootElement().getName());

        tx.commit();
        sess.close();
       
        System.out.println("getting xmltest ok ");
       
        结果如下:
        xt item_value : sfsdfsfsdfds
        xt item_value : org.dom4j.tree.DefaultDocument@4ee70b [Document: name null]
        xt item_value : a
        getting xmltest ok
       
        xt.getItemValue()取得的值是一个org.dom4j.Document对象,这样,就可以用dom4j的东西去实现你要的所有的操作。所以,所有的东西就只有对象,而不需要,去考虑操作XmlType的东西了。
       
       
[7]总结
      我觉得值得说的难点有两个,一个是自定义类型里面的nullSafeSet和nullSafeGet方法,另一个是映射的时候,要根据你nullSafeGet的返回值的类型来确定。
      一定注意,映射的不是你的自定义类型的对象,如上面的PoiAdditionalXmlType,而是你的解析后的对象org.dom4j.Document。







|----------------------------------------------------------------------------------------|
                           版权声明  版权所有 @zhyiwww
            引用请注明来源 http://www.blogjava.net/zhyiwww   
|----------------------------------------------------------------------------------------|

你可能感兴趣的:(实战演练:Hibernate映射Oracle的XmlType到Document(xml)对象)