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 閱讀(1402) 評論(0)  編輯  收藏 所屬分類: JMS
          主站蜘蛛池模板: 涞水县| 密云县| 普安县| 深水埗区| 辉南县| 凯里市| 务川| 五峰| 鄂伦春自治旗| 安溪县| 仪征市| 沂源县| 秦安县| 永定县| 新乡县| 溧阳市| 常州市| 永清县| 泸西县| 丰城市| 西宁市| 汶川县| 宁武县| 怀化市| 侯马市| 无棣县| 保定市| 海丰县| 康保县| 临沂市| 尼玛县| 吴江市| 株洲县| 福泉市| 渭源县| 岐山县| 丁青县| 松潘县| 佛冈县| 建瓯市| 大丰市|