随笔-72  评论-63  文章-0  trackbacks-0
在网上闲逛找到了解决方案:
     现在3.x中对blob和clob增加了org.hibernate.lob.SerializableBlob和org.hibernate.lob.SerializableClob类的封装。

其次如果你将前面的测试程序放到weblogic的容器中通过weblogic的数据源得到连接的话,你会发现oracle.sql.BLOB blob = (oracle.sql.BLOB)person.getImage();和 oracle.sql.CLOB clob = (oracle.sql.CLOB)person.getArticle();这俩行会出错,原因就是weblogic进行了包装。

现在将以上两个问题的综合解决方案用以下代码说明:



            for (int i = 0; i < 10; i++) {
                LargeObject large = new LargeObject();
                large.setId(i + "");
                large.setName("林意炜");

                // 插入一个小数据数据
                large.setImage(Hibernate.createBlob(new byte[1]));
                large.setArticle(Hibernate.createClob(" "));

                session.save(large);
                session.flush();

                // 锁定该记录
                session.refresh(large, LockMode.UPGRADE);

                // 插入图片数据
                String fileName = "E:/AAA/" + i + ".jpg";
                SerializableBlob sb = (SerializableBlob)large.getImage();
                java.sql.Blob wrapBlob = sb.getWrappedBlob();
                // 通过非weblogic容器中数据源获得连接的情况
                if(wrapBlob instanceof oracle.sql.BLOB){
                    oracle.sql.BLOB blob = (oracle.sql.BLOB) wrapBlob;
                    OutputStream out = blob.getBinaryOutputStream();
                    out.write(getData(fileName));
                    out.close();
                }
                // 使用weblogic的Oracle Thin driver类型连接池,驱动类名:oracle.jdbc.OracleDriver
                else if(wrapBlob instanceof weblogic.jdbc.vendor.oracle.OracleThinBlob){
                    OracleThinBlob blob = (OracleThinBlob)wrapBlob;
                    OutputStream out = blob.getBinaryOutputStream();
                    out.write(getData(fileName));
                    out.close();
                }


                // 插入文章数据
                fileName = "E:/AAA/" + i + ".java";
                SerializableClob cb = (SerializableClob)large.getArticle();
                java.sql.Clob wrapClob = cb.getWrappedClob();
                // 通过非weblogic容器中数据源获得连接的情况
                if(wrapClob instanceof oracle.sql.CLOB){
                    oracle.sql.CLOB clob = (oracle.sql.CLOB) wrapClob;
                    Writer writer = clob.getCharacterOutputStream();
                    String article = new String(getData(fileName));
                    writer.write(article);
                    writer.close();
                }
                // 使用weblogic的Oracle Thin driver类型连接池,驱动类名:oracle.jdbc.OracleDriver
                else if(wrapClob instanceof weblogic.jdbc.vendor.oracle.OracleThinClob){
                    OracleThinClob clob = (OracleThinClob)wrapClob;
                    Writer writer = clob.getCharacterOutputStream();
                    String article = new String(getData(fileName));
                    writer.write(article);
                    writer.close();
                }
            }


***************************************************
采用得是ORACLE9i数据库,Jboss或Weblogic。
JDBC采用ORACLE9i自带的Class12.jar
-------------
数据库结构:
java代码: 


CREATE TABLE SNCPARAMETERS
(
  ID     NUMBER(19)                             NOT NULL,
  SNCID  NUMBER(19),
  NAME   VARCHAR2(255),
  VALUE  CLOB
)


--------------
BO采用xdoclet建立的:
java代码: 


publicclass SNCParameters extends BaseObject
{

    /**
     * Returns the id.
     *
     * @return      long
     * @hibernate.id
     *          column = "id"
     *          type = "long"
     *          generator-class = "native"
     *          unsaved-value = "null"
     */

    publicLong getId()
    {
        return id;
    }

    /**
     *    Sets the Id attribute of the SNCParameters object
     *
     * @param    id  The new Id value
     */

    publicvoid setId(Long id)
    {
        this.id = id;
    }


    /**
     * Returns the name.
     *
     * @return      String
     *
     * @hibernate.property
     *          column = "name"
     *          type = "string"
     *          not-null = "true"
     *          unique = "false"
     */


    publicString getName()
    {
        return name;
    }

    /**
     *    Sets the Name attribute of the SNCParameters object
     *
     * @param    name  The new Name value
     */

    publicvoid setName(String name)
    {
        this.name = name;
    }

    /**
     * Returns the sncId.
     *
     * @return      Long
     *
     * @hibernate.property
     *          column = "sncId"
     *          type = "long"
     *          not-null = "true"
     *          unique = "false"
     */


    publicLong getSncId()
    {
        return sncId;
    }

    /**
     *    Sets the SncId attribute of the SNCParameters object
     *
     * @param    sncId  The new SncId value
     */

    publicvoid setSncId(Long sncId)
    {
        this.sncId = sncId;
    }

    /**
     * Returns the values.
     *
     * @return      Clob
     *
     * @hibernate.property
     *          column = "value"
     *          type = "clob"
     *          not-null = "true"
     *          unique = "false"
     */


    publicClob getValue()
    {
        return value;
    }

    /**
     *    Sets the Values attribute of the SNCParameters object
     *
     * @param    values  The new Values value
     */

    publicvoid setValue(Clob value)
    {
        this.value = value;
    }
    privateLong id;
    privateLong sncId;
    privateString name;
    privateClob value;
    privateString valueString;
    publicString getValueString()
    {
        return valueString;
    }
        publicvoid setValueString(String  valueString)
    {
        this.valueString = valueString;
    }
}



注:valueString并不映射到数据库的CLOB字段,只是方便需要使用这个BO的人用GET、SET 处理这个巨长的CLOB字段
------------
xdocLet生成的XML文件:
java代码: 


<?xml version="1.0"?>

<!DOCTYPE hibernate-mapping PUBLIC
    "-//Hibernate/Hibernate Mapping DTD 2.0//EN"
    "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
    <class
        name="com.idncn.mc.bo.SNCParameters"
        table="SNCParameters"
        dynamic-update="false"
        dynamic-insert="false"
    >

        <id
            name="id"
            column="id"
            type="long"
            unsaved-value="null"
        >
            <generator class="native">
            </generator>
        </id>

        <property
            name="name"
            type="string"
            update="true"
            insert="true"
            column="name"
            not-null="true"
            unique="false"
        />

        <property
            name="sncId"
            type="long"
            update="true"
            insert="true"
            column="sncId"
            not-null="true"
            unique="false"
        />

        <property
            name="value"
            type="clob"
            update="true"
            insert="true"
            column="value"
            not-null="true"
            unique="false"
        />
    </class>

</hibernate-mapping>


--------------------
insert的代码:
java代码: 


    publicList batchAddSncParameters(List sncParametersList, Long sncId)throws DbAccessException
    {
        logger.enterMethod();
        List ret = newArrayList();
        try
        {
            sess = getSession();
            if(sncParametersList != null && sncParametersList.size() > 0)
            {
                for(int i = 0; i < sncParametersList.size(); i++)
                {
                    SNCParameters cp = (SNCParameters) sncParametersList.get(i);
                    long newId = -1;
                    if(cp != null)
                    {
                        SNCParameters cpNew = new SNCParameters();
                        cpNew.setSncId(sncId);
                        cpNew.setName(cp.getName());
                        cpNew.setValue(Hibernate.createClob(" "));
                        newId = ((Long) sess.save(cpNew)).longValue();
                        sess.flush();

                        sess.refresh(cpNew, LockMode.UPGRADE);
                        String content = cp.getValueString();

                        String appserver = System.getProperty("appserver", "jboss");
                        if(!appserver.equalsIgnoreCase("jboss"))
                        {
                            //weblogic
                            OracleThinClob clob = (OracleThinClob) cpNew.getValue();
                            java.io.Writer pw = clob.getCharacterOutputStream();
                            pw.write(content);
                            pw.flush();
                            pw.close();
                        }
                        else
                        {
                            //jboss
                            oracle.sql.CLOB clob = (oracle.sql.CLOB) cpNew.getValue();
                            java.io.Writer pw = clob.getCharacterOutputStream();
                            pw.write(content);
                            pw.flush();
                            pw.close();
                        }
                        ret.add(newLong(newId));
                    }
                }
            }
        }
        catch(Exception e)
        {
            logger.error(e);
            ErrorReason errorReason = new ErrorReason(ErrorReason.INSERT_OBJECT_FAILED_REASON);
            throw new DbAccessException(DbAccessException.DBA_OPERATE_EXCEPTION, errorReason);
        }
        finally
        {
            closeSession(sess);
            logger.exitMethod();
        }
        return ret;
    }


-----------------
注:Weblogic必须使用weblogic.jdbc.vendor.oracle.OracleThinClob
---------------------
读取CLOB字段:
java代码: 


    publicList selectSncParametersBySncId(long sncId)throws DbAccessException
    {
        logger.enterMethod();
        List ret = newArrayList();
        try
        {
            sess = getSession();
            String query = "select cp from cp in class com.idncn.mc.bo.SNCParameters where cp.sncId = ?";
            logger.debug("SQL=" + query);
            List iter = sess.find(query, newLong(sncId), Hibernate.LONG);
            for(int i = 0; i < iter.size(); i++)
            {
                SNCParameters newCp = new SNCParameters();
                SNCParameters cp = (SNCParameters)(iter.get(i));
                logger.debug("after fetch:" + cp);
                newCp.setId(cp.getId());
                newCp.setSncId(cp.getSncId());
                newCp.setName(cp.getName());
                java.sql.Clob clob = cp.getValue();
                if(clob != null)
                {
                    logger.debug("b===" + clob.length());
                    String b = clob.getSubString(1, (int) clob.length());
                    //logger.debug("b==="+b);
                    newCp.setValueString(b);
                }
                ret.add(newCp);
            }
        }
        catch(Exception e)
        {
            logger.error(e);
            ErrorReason errorReason = new ErrorReason(ErrorReason.SELECT_FAILED_REASON);
            throw new DbAccessException(DbAccessException.DBA_OPERATE_EXCEPTION, errorReason);
        }
        finally
        {
            closeSession(sess);
            logger.exitMethod();
        }
        return ret;
    }


---------------
更新这个字段的代码:
java代码: 


    publicvoid updateSncParameters(SNCParameters newParam)throws DbAccessException
    {
        logger.enterMethod();
        try
        {
            sess = getSession();

            Long id = newParam.getId();
            SNCParameters pp = (SNCParameters) sess.load(SNCParameters.class, id, net.sf.hibernate.LockMode.UPGRADE);

            pp.setSncId(newParam.getSncId());
            pp.setName(newParam.getName());
            pp.setId(newParam.getId());

            String newValue = newParam.getValueString();
            logger.debug("Update Length =" + newValue.length());

            String appserver = System.getProperty("appserver", "jboss");
            logger.debug("appserver: " + appserver);
            if(!appserver.equalsIgnoreCase("jboss"))
            {
                //weblogic
                OracleThinClob clob = (OracleThinClob) pp.getValue();
                if(pp != null)
                {
                    java.io.Writer pw = clob.getCharacterOutputStream();
                    pw.write(newValue);
                    pw.flush();
                    pw.close();
                }
            }
            else
            {
                //jboss
                oracle.sql.CLOB clob = (oracle.sql.CLOB) pp.getValue();
                if(pp != null)
                {
                    java.io.Writer pw = clob.getCharacterOutputStream();
                    pw.write(newValue);
                    pw.flush();
                    pw.close();
                }
            }
        }
        catch(Exception e)
        {
            logger.error(e);
            ErrorReason errorReason = new ErrorReason(ErrorReason.UPDATE_OBJECT_FAILED_REASON);
            throw new DbAccessException(DbAccessException.DBA_OPERATE_EXCEPTION, errorReason);
        }
        finally
        {
            closeSession(sess);
            logger.exitMethod();
        }
    }


posted on 2006-07-11 11:07 船长 阅读(1775) 评论(0)  编辑  收藏 所属分类: J2EE

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


网站导航: