|
该帖已经被评为精华帖
|
|
|---|---|
| 作者 | 正文 |
|
最后更新时间:2005-10-14
===============================================
在spring中如何处理oracle大字段 在spring中采用OracleLobHandler来处理oracle大字段(包括clob和blob),则在程序中不需要引用oracle的特殊类,从而能够保证支持我们的代码支持多数据库。 1、首先数据表中的clob类型对应java持久化类的String类型;而blob类型对应byte[]类型 2、定义hibernate标签时,持久化类中对应clob类型的属性的hibernate type应为org.springframework.orm.hibernate.support.ClobStringType;而对应blob类型的属性的hibernate type应为org.springframework.orm.hibernate.support.BlobByteArrayType。 3、以后访问这些对应clob和blob类型的属性时,按普通属性处理,不需要特别编码。 =============================================== 请问大家有没有试上面方法在spring中处理Oracle的blob?有这方面经验的朋友说一下怎么实现! 我现在用hibernate操作oracle的blog存取基本是按传统的jdbc方式处理的,如下例子所示。如果用spring提供的org.springframework.jdbc.support.lob.OracleLobHandler类,应该怎么修改! 如果大家有自已更好的方法,请不吝赐教! 3q 例: Customer.hbm.xml [code:1] <?xml version="1.0"?> <hibernate-mapping package="com.jandar.bo"> <class name="Customer" table="CUSTOMER"> <id column="ID" name="Id" type="integer" > <generator class="vm" /> </id> <property column="NAME" length="25" name="Name" not-null="false" type="string" /> <property column="IMAGES" name="Images" not-null="false" type="blob" /> </class> </hibernate-mapping>[/code:1] =============================================== [code:1]import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.sql.SQLException; import java.util.List; import net.sf.hibernate.Hibernate; import net.sf.hibernate.LockMode; import org.springframework.orm.hibernate.support.HibernateDaoSupport; import weblogic.jdbc.vendor.oracle.OracleThinBlob; import com.jandar.bean.ImageBean; import com.jandar.bo.Customer; import com.jandar.services.dao.ImageDAO; public class ImageDAOImpl extends HibernateDaoSupport implements ImageDAO{ byte[] buffer = new byte[10]; public Customer findImage(Customer customer) { String getId = "select max(cu.id) from Customer as cu"; List list = (List)getHibernateTemplate().find(getId); Customer customerBean = (Customer)getHibernateTemplate().load (Customer.class,Integer.valueOf(list.get(0).toString())); return customerBean; } public void saveImages(Object object){ Customer customer = new Customer(); ImageBean imageBean = (ImageBean)object; OutputStream out = null; InputStream fin = null; try{ //Session session = getSession(); //session.connection().prepareStatement("insert into "); //Connection connection = null; //connection = (Connection)session.connection(); //PreparedStatement ps = connection.createStatement(); customer.setName("jack"); customer.setImages(Hibernate.createBlob(buffer)); getHibernateTemplate().save(customer); getHibernateTemplate().flush(); getHibernateTemplate().refresh(customer, LockMode.UPGRADE); //since: weblogic8.2 lib OracleThinBlob blob = (OracleThinBlob)customer.getImages(); out = blob.getBinaryOutputStream(); String fileName = imageBean.getImageName(); File f = new File(fileName); fin = new FileInputStream(f); //int count = -1, total = 0; //fin.read(data); byte[] data = new byte[ (int) fin.available()]; int bytesReaded = 0; while((bytesReaded=fin.read(data,0,data.length)) != -1) { out.write(data, 0, bytesReaded); } //out.write(data); customer.setName(imageBean.getName()); out.flush(); getHibernateTemplate().flush(); }catch(SQLException sqlError){ System.out.println("sql error: "+ sqlError.getMessage()); }catch(Exception notFound){ System.out.println("sql error: "+ notFound.getMessage()); }finally{ try{ out.close(); fin.close(); }catch(IOException error){ } } } }[/code:1] 声明:JavaEye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
|
|
| 返回顶楼 | |
|
最后更新时间:2005-10-14
[code:1]
<bean id="mySessionFactory2" class="org.springframework.orm.hibernate.LocalSessionFactoryBean"> <property name="dataSource"> <ref bean="myDataSource2"/> </property> <property name="lobHandler"> <ref bean="oracleLobHandle"/> </property> </bean> <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.SimpleNativeJdbcExtractor"/> <bean id="oracleLobHandle" class="org.springframework.jdbc.support.lob.OracleLobHandler" Lazy-init="true"> <property name="nativeJdbcExtractor"> <ref local="nativejdbcExtractor"/> </property> </bean>[/code:1] Spring为处理数据库Lob字段,特别提供了LobHandler接口。在操作Oracle RDBMS过程中,由于Oracle JDBC Driver实现的问题,应用必须采用Oracle原生的数据库连接(比如,oracle.jdbc.OracleConnection)、LOB原生实现(比如,oracle.sql.BLOB、oracle.sql.CLOB)。因此,LobHandler接口存在上述两种实现。简而言之,为操作Oracle数据库,必须使用OracleLobHandler实现。如果操作其他RDBMS类型,则使用DefaultLobHandler。NativeJdbcExtractor是个接口,通过它能够抽象各种连接池。另外Spring还提供两个接口存取Blob,LobCreator及LobHandler 接口LobCreator [code:1] //.....省略某些方法 void setBlobAsBytes(PreparedStatement ps, int paramIndex, byte[] content)throws SQLException; void setBlobAsBinaryStream(PreparedStatement ps, int paramIndex, InputStream contentStream, int contentLength)throws SQLException;[/code:1] 接口LobHandler [code:1] //.....省略某些方法 byte[] getBlobAsBytes(ResultSet rs, String columnName)throws SQLException; byte[] getBlobAsBytes(ResultSet rs, int columnIndex)throws SQLException; InputStream getBlobAsBinaryStream(ResultSet rs,String columnName) throws SQLException; InputStream getBlobAsBinaryStream(ResultSet rs, int columnIndex) throws SQLException; [/code:1] 我现在自定义一个BinaryBlobType类型,请问怎么同时使用LobHandler和Hibernate UserType实现。它们两者的关联怎么配置才算正确呢?是不是UserType和LobHandler两者只能选择一个? [code:1] 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 { InputStream blobReader = rs.getBinaryStream(names[0]); if (blobReader == null) return null; byte[] b = new byte[1024]; ByteArrayOutputStream os = new ByteArrayOutputStream(); try { while ((blobReader.read(b)) != -1) os.write(b); } catch (IOException e) { throw new SQLException(e.toString()); } finally { try { os.close(); } catch (IOException e) { } } return os.toByteArray(); } 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; } } [/code:1] |
|
| 返回顶楼 | |
|
最后更新时间:2005-10-14
哪有这么麻烦?不好意思,你贴的实在是太多了,让我失去了看下去的耐心。
spring的sample里面专门有-个操作blob和clob的例子,非常详尽,你看了自然知道如何处理了,我不用在此废话。 |
|
| 返回顶楼 | |
|
最后更新时间:2005-10-14
denis 写道 哪有这么麻烦?不好意思,你贴的实在是太多了,让我失去了看下去的耐心。
spring的sample里面专门有-个操作blob和clob的例子,非常详尽,你看了自然知道如何处理了,我不用在此废话。 spring那个imagedb用的是JdbcDaoSupport里的getJdbcTemplate()实现的!没有用hibernate |
|
| 返回顶楼 | |
|
最后更新时间:2005-10-14
sigh.....
楼主,我可以告诉你,如果使用hibernate,那么处理这个问题会更简单更透明,你目前最关键的是要学会如何举一反三。 也罢,贴一些片断,明白就明白了,再不明白俺也帮不了你了,我不多做解释。 另:这些配置片断以及代码片段仅在spring1.1.3,hibernate2.1.3上测试通过。理由嘛,这些都是今年初的一个项目中采用的解决方法,而项目结束时使用的spring的版本是1.1.3,hibernate2.13。现在很久没碰spring以及hibernate了,不知道是不是有了更优雅的解决方法? LocalSessionFactoryBean配置: 引用 <bean id="sessionFactory"
class="org.springframework.orm.hibernate.LocalSessionFactoryBean"> <property name="dataSource"> <ref local="dataSource" /> </property> <property name="lobHandler"> <ref local="oracleLobHandler" /> </property> <property name="mappingResources"> <list>...</list> </property> <property name="hibernateProperties">...</property> </bean> lobHandler: 引用 <bean id="oracleLobHandler"
class="org.springframework.jdbc.support.lob.OracleLobHandler" lazy-init="true"> <property name="nativeJdbcExtractor"> <ref local="nativeJdbcExtractor" /> </property> </bean> nativeJdbcExtractor: 引用 <!--使用dbcp连接池时启用-->
<bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.CommonsDbcpNativeJdbcExtractor" lazy-init="true" /> <!--使用websphere连接池时启用 <bean id="nativeJdbcExtractor" class="org.springframework.jdbc.support.nativejdbc.WebSphereNativeJdbcExtractor" lazy-init="true"/> --> pojo blob字段的xdoclet: [code:1] public Class BinaryFile private byte[] content; /** * @hibernate.property * column="content" * type="org.springframework.orm.hibernate.support.BlobByteArrayType" * * @return binary array content */ public byte[] getContent() { return content; }[/code:1] 示例代码调用: [code:1]File file = some file get from anywhere......... byte[] fileArray = org.springframework.util.FileCopyUtils.copyToByteArray(file); BinaryFile bFile = new BinaryFile(); bFile.setContent(fileArray); getHibernateTemplate().save(bFile);[/code:1] |
|
| 返回顶楼 | |
|
最后更新时间:2005-10-17
denis 写道 pojo blob字段的xdoclet: [code:1] public Class BinaryFile private byte[] content; /** * @hibernate.property * column="content" * type="org.springframework.orm.hibernate.support.BlobByteArrayType" * * @return binary array content */ public byte[] getContent() { return content; }[/code:1] 示例代码调用: [code:1]File file = some file get from anywhere......... byte[] fileArray = org.springframework.util.FileCopyUtils.copyToByteArray(file); BinaryFile bFile = new BinaryFile(); bFile.setContent(fileArray); getHibernateTemplate().save(bFile);[/code:1] 嗯,多谢denis的指导。在spring1.2和hibernate2.1中也可以通过。看了一下spring和hibernate的源码,无论是自定义的type还是用spring提供的oracleLobHandler最终都要实现org.hibernate.usertype.UserType这个接口。 |
|
| 返回顶楼 | |
|
最后更新时间:2005-11-01
denis 用的数据库是8.1.7?
我想应该是9i以上版本吧?我照着denis贴的内容,jdbc driver用过8.1.7、9.2.0.1、9.2.0.3、9.2.0.4、9.2.0.4、9.2.0.5、10.1.0.2、10.1.0.4、10.2.0.1.0,都没办法往CLOB、BLOB里面弄数据进去。之前google或是javaeye上搜到的资料,无一例外的出错。 似乎对于8i来说,唯一有效的,就是先empty_lob(),然后再for update了。 |
|
| 返回顶楼 | |
|
最后更新时间:2005-11-02
mmwy 写道 denis 用的数据库是8.1.7?
我想应该是9i以上版本吧?我照着denis贴的内容,jdbc driver用过8.1.7、9.2.0.1、9.2.0.3、9.2.0.4、9.2.0.4、9.2.0.5、10.1.0.2、10.1.0.4、10.2.0.1.0,都没办法往CLOB、BLOB里面弄数据进去。之前google或是javaeye上搜到的资料,无一例外的出错。 似乎对于8i来说,唯一有效的,就是先empty_lob(),然后再for update了。 我的版本是9.0.1.0.0用denis的方法是可以,另外我在mysql4.1上也用该方法通过了!是可以直接往数据库插入CLOB、BLOB的,而不用先empty_lob(),然后再for update |
|
| 返回顶楼 | |
|
最后更新时间:2005-11-02
好贴,长见识了
|
|
| 返回顶楼 | |
|
最后更新时间:2005-11-08
8I也可以的,我试过
配置差不多的 |
|
| 返回顶楼 | |








