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 閱讀(1403) 評論(0)  編輯  收藏 所屬分類: JMS
          主站蜘蛛池模板: 朔州市| 色达县| 平阴县| 密云县| 广元市| 垫江县| 通州区| 鸡东县| 铅山县| 皮山县| 磐安县| 诸城市| 靖远县| 武邑县| 靖江市| 大竹县| 金塔县| 连南| 大同县| 山阳县| 长寿区| 衡南县| 昆山市| 鄂温| 湾仔区| 郸城县| 漳浦县| 汉沽区| 贵阳市| 泾源县| 珠海市| 英超| 泰安市| 迭部县| 建昌县| 灌阳县| 柞水县| 五原县| 海门市| 淮北市| 眉山市|