hk2000c技術專欄

          技術源于哲學,哲學來源于生活 關心生活,關注健康,關心他人

            BlogJava :: 首頁 :: 新隨筆 :: 聯系 :: 聚合  :: 管理 ::
            111 隨筆 :: 1 文章 :: 28 評論 :: 0 Trackbacks

          Hibernate 1.2.3 has built-in support for blobs. Hibernate natively maps blob columns to java.sql.Blob. However, it's sometimes useful to read the whole blob into memory and deal with it as a byte array.

          One approach for doing this to create a new UserType as follows.

          package mypackage;
          import java.sql.PreparedStatement;
          import java.sql.ResultSet;
          import java.sql.SQLException;
          import java.sql.Types;
          import java.sql.Blob;
          import cirrus.hibernate.Hibernate;
          import cirrus.hibernate.HibernateException;
          import cirrus.hibernate.UserType;
          public class BinaryBlobType implements UserType
          {
          public int[] sqlTypes()
          {
          return new int[] { Types.BLOB };
          }
          public Class returnedClass()
          {
          return byte[].class;
          }
          public boolean equals(Object x, Object y)
          {
          return (x == y)
          || (x != null
          && y != null
          && java.util.Arrays.equals((byte[]) x, (byte[]) y));
          }
          public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
          throws HibernateException, SQLException
          {
          Blob blob = rs.getBlob(names[0]);
          return blob.getBytes(1, (int) blob.length());
          }
          public void nullSafeSet(PreparedStatement st, Object value, int index)
          throws HibernateException, SQLException
          {
          st.setBlob(index, Hibernate.createBlob((byte[]) value));
          }
          public Object deepCopy(Object value)
          {
          if (value == null) return null;
          byte[] bytes = (byte[]) value;
          byte[] result = new byte[bytes.length];
          System.arraycopy(bytes, 0, result, 0, bytes.length);
          return result;
          }
          public boolean isMutable()
          {
          return true;
          }
          }
          

          The BinaryBlobType will convert a blob into a byte array and back again.

          Here's how to use it. First, define an entity that contains a byte[] property:

          public class ImageValue
          {
          private long id;
          private image byte[];
          public long getId() { return id; }
          public void setId(long id) { this.id = id; }
          public byte[] getImage() { return image; }
          public void setImage(byte[] image) { this.image = image; }
          }
          

          Then map a blob column onto the byte[] property:

          <class name="ImageValue" table="IMAGE_VALUE">
          <id name="id/>
          <property name="image" column="IMAGE" type="mypackage.BinaryBlobType"/>
          </class>
          

          Notes:

          1) Blobs aren't cachable. By converting the blob into a byte array, you can now cache the entity.

          2) This approach reads the whole blob into memory at once.

          3) The above type is known to work for reading blobs out of the db. Other usage patterns might also work.

          Comments (GK)

          I changed isMutable() to return true, since an array is a mutable object.

          The use of setBlob() will work on some drivers, but not all. I think its more portable to use setBytes() or even setBinaryStream().

          comments (db)

          db's comment above was right, setBlob() didn't work on Oracle, I used setBytes().

          comments (Chad Woolley)

          Below is a modified nullsafeset() that i needed to use to get it to work with tomcat 4.1.27 & oracle 8/9i - the normal calls don't work through the tomcat/dbcp connection pool wrapper objects... (this caused me great pain)

          pls note that the setBytes() doesn't seem to work with oracle driver & hibernate

          d.birch@eclipsegroup.com.au

          public void nullSafeSet(PreparedStatement st, Object value, int index)
          throws HibernateException, SQLException
          {
          if(st instanceof org.apache.commons.dbcp.DelegatingPreparedStatement &&
          ((org.apache.commons.dbcp.DelegatingPreparedStatement)st).getDelegate()
          instanceof oracle.jdbc.OraclePreparedStatement)
          {
          oracle.sql.BLOB blob = oracle.sql.BLOB.createTemporary(
          ((org.apache.commons.dbcp.PoolableConnection)st.getConnection()).getDelegate(), false, oracle.sql.BLOB.DURATION_SESSION);
          blob.open(BLOB.MODE_READWRITE);
          OutputStream out = blob.getBinaryOutputStream();
          try
          {
          out.write((byte[])value);
          out.flush();
          out.close();
          }
          catch(IOException e)
          {
          throw new SQLException("failed write to blob" + e.getMessage());
          }
          blob.close();
          ((oracle.jdbc.OraclePreparedStatement)((org.apache.commons.dbcp.DelegatingPreparedStatement)st).getDelegate()).setBLOB(index, blob);
          }
          else
          {
          st.setBlob(index, Hibernate.createBlob((byte[]) value));
          }
          }
          //and.. note the null check, oracle drivers return a null blob...
          public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
          throws HibernateException, SQLException
          {
          final Blob blob = rs.getBlob(names[0]);
          return blob != null?blob.getBytes(1, (int)blob.length()):null;
          }
          

          / comments Vanitha

          I had to use the user type to save pdfs as oraBLOBs in oracle 91 database. nullsafeSet

          needed a sligh modification , or else ther was a classcastexception. Used oracle Blob instead of Hibernate Blob type and it works.

           public void nullSafeSet(PreparedStatement st, Object value, int index)
          throws HibernateException, SQLException
          {
          oracle.sql.BLOB t_blob = oracle.sql.BLOB.createTemporary(((org.jboss.resource.adapter.jdbc.WrappedConnection) st.getConnection()).getUnderlyingConnection(),
          false, oracle.sql.BLOB.DURATION_SESSION);
          OutputStream t_out = null;
          t_blob.open(BLOB.MODE_READWRITE);
          t_out = t_blob.getBinaryOutputStream();
          try
          {
          t_out.write((byte[]) value);
          t_out.flush();
          t_out.close();
          }
          catch (IOException e)
          {
          throw new SQLException("failed write to blob" + e.getMessage());
          }
          t_blob.close();
          st.setBlob(index, t_blob);
          }
          

          </code>

          posted on 2007-11-16 17:46 hk2000c 閱讀(1399) 評論(0)  編輯  收藏 所屬分類: JMS
          主站蜘蛛池模板: 湖南省| 高阳县| 崇阳县| 枣庄市| 永寿县| 南汇区| 徐汇区| 屏南县| 新巴尔虎左旗| 临朐县| 湖南省| 灌阳县| 宜宾县| 胶南市| 陈巴尔虎旗| 瓦房店市| 桃园县| 揭东县| 连云港市| 同仁县| 宁津县| 应用必备| 济南市| 临潭县| 芮城县| 遂川县| 房产| 洪洞县| 海城市| 桃源县| 溆浦县| 兴义市| 赫章县| 满城县| 唐海县| 百色市| 通许县| 东宁县| 山阳县| 连平县| 铜山县|