zhyiwww
用平实的笔,记录编程路上的点点滴滴………
posts - 536,comments - 394,trackbacks - 0
先请参看上一篇文章

[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   
|----------------------------------------------------------------------------------------|
posted on 2008-12-25 18:08 zhyiwww 阅读(3477) 评论(4)  编辑  收藏 所属分类: j2eedatabase

FeedBack:
# re: 实战演练:Hibernate映射Oracle的XmlType到Document(xml)对象
2009-06-04 22:46 | lebaolam8891@yahoo.com
Sorry but I think i followed exactly the same with you, add a new type, change the mapping. Every thing was ok but I got the following error:
Exception in thread "main" java.lang.NoClassDefFoundError: oracle/xml/parser/v2/XMLParseException
at com.keys.dao.customtypes.HibernateXMLType.nullSafeSet(HibernateXMLType.java:72)
at org.hibernate.type.CustomType.nullSafeSet(CustomType.java:169)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2025)
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2002)
at org.hibernate.persister.entity.AbstractEntityPersister$3.bindValues(AbstractEntityPersister.java:2180)
at org.hibernate.id.insert.AbstractReturningDelegate.performInsert(AbstractReturningDelegate.java:56)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2186)
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2666)
at org.hibernate.action.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:71)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.event.def.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:321)
at org.hibernate.event.def.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:204)
at org.hibernate.event.def.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:130)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:210)
at org.hibernate.event.def.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:56)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:195)
at org.hibernate.event.def.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:50)
at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
at org.hibernate.impl.SessionImpl.fireSave(SessionImpl.java:562)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:550)
at org.hibernate.impl.SessionImpl.save(SessionImpl.java:546)
at test.LibraryTest.testCreateDomains(LibraryTest.java:50)
at test.LibraryTest.main(LibraryTest.java:34)
Could you please give me your source code so that I can compare with mine.
Thanks   回复  更多评论
  
# re: 实战演练:Hibernate映射Oracle的XmlType到Document(xml)对象
2009-06-04 23:04 | lebaolam8891@yahoo.com
I have other solution.
By default, hibernate will map XMLType as String, with this we can save or retrieve xml data as a string. Then, we can put the content of that string to a Document type and manipulate it.
Is it ok?  回复  更多评论
  
# re: 实战演练:Hibernate映射Oracle的XmlType到Document(xml)对象
2012-10-26 17:00 | 山猫
你好 我用hibernate运行 报错 无法将value传入到 nullSafeSet(PreparedStatement stmt, Object value的value中,this.getHibernateTemplate().saveOrUpdate(ircCusMetXml);用的是hibernatedao的这个方法 。可否帮助解决  回复  更多评论
  
# 实战演练:Hibernate映射Oracle的XmlType到Document(xml)对象
2013-03-25 19:07 | 节操掉了一地
你好,我在一个项目中使用XmlType的时候,结合SSh框架,应用你提供的方法,启动Tomcat报错XML解析的错误。
nested exception is javax.xml.parsers.ParserConfigurationException: Unable to validate using XSD: Your JAXP provider [oracle.xml.jaxp.JXDocumentBuilderFactory
我从网上搜了一下,是spring xml解析器和oracle的冲突了,但是不知道解决办法,请你帮我解决一下,谢谢。^_^  回复  更多评论
  

只有注册用户登录后才能发表评论。


网站导航: