该帖已经被评为精华帖
|
|
---|---|
作者 | 正文 |
发表时间:2005-10-11
在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 <?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> =============================================== [color=blue] 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);{ } } } }[/color] 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2005-10-14
[color=blue]
<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>[/color] 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 [color=blue] //.....省略某些方法 void setBlobAsBytes(PreparedStatement ps, int paramIndex, byte[] content);throws SQLException; void setBlobAsBinaryStream(PreparedStatement ps, int paramIndex, InputStream contentStream, int contentLength);throws SQLException;[/color] 接口LobHandler [color=blue] //.....省略某些方法 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;[/color] 我现在自定义一个BinaryBlobType类型,请问怎么同时使用LobHandler和Hibernate UserType实现。它们两者的关联怎么配置才算正确呢?是不是UserType和LobHandler两者只能选择一个? [color=blue] 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; } }[/color] |
|
返回顶楼 | |
发表时间: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: 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; } 示例代码调用: 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);; |
|
返回顶楼 | |
发表时间:2005-10-17
denis 写道 pojo blob字段的xdoclet: 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; } 示例代码调用: 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);; 嗯,多谢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-08
8I也可以的,我试过
配置差不多的 |
|
返回顶楼 | |
发表时间:2005-11-11
xiang 写道 8I也可以的,我试过
配置差不多的 能否详细介绍一下?我的OS用过RHCE AS2.1、中软3.1,数据库是oracle8.1.7 for linux。 hibernate试过2.1.7,3.0.5。spring用过1.1、1.2.5,都不成功啊。 |
|
返回顶楼 | |