浏览 8428 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2005-12-06
我在自己定义的用户类型中遇到下面的问题: 下面这个函数读出数据没有问题: public Object nullSafeGet(ResultSet resultSet, String[] stringArray, Object object) throws HibernateException, SQLException { Reader reader = resultSet.getCharacterStream(stringArray[0]); if (reader == null) return null; StringBuffer sb = new StringBuffer(); try { char[] charbuf = new char[4096]; //解决4096字节大小的限制 for (int i = reader.read(charbuf); i >0; i= reader.read(charbuf)) { sb.append(charbuf, 0, i); } } catch (IOException e) { throw new SQLException( e.getMessage() ); } return sb.toString(); } //下面的函数写入数据总是不正确 public void nullSafeSet(PreparedStatement preparedStatement, Object object, int _int) throws HibernateException, SQLException { try{ if (object != null) { // StringReader r = new StringReader( (String) object); //下面的方法写入太多的数据会使CLOB为空,几百个字节没有问题 /* preparedStatement.setCharacterStream(_int, r, ( (String) object).length());*/ preparedStatement.setCharacterStream(_int, new InputStreamReader(new ByteArrayInputStream(((String) object).getBytes())), ( (String) object).length()); System.out.println( (String) object+((String) object).length()); //下面的方法写入数据的长度有限制 // preparedStatement.setString(_int,(String) object); } else { preparedStatement.setNull(_int, sqlTypes()[0]); // preparedStatement.setClob(1,Hibernate.createClob(" ")); } }catch(Exception e){ e.printStackTrace(); } 我使用的是JB2005(编译器),Oracle 9.2.0.1.0(企业版),Hibernate 3.0,JDBC thin驱动 我也看过很多有关的贴(读取CLOB相关的),JAVA视线论坛,Hibernate官方站点的 (http://www.hibernate.org/76.html,http://www.hibernate.org/56.html) Oracle官方站点等等.都没有找到合适的解决方案(或许我的悟性太差了) 还有如果使用OCI驱动连接老是有问题: thin: jdbc:oracle:thin:@192.168.0.18:1521:plan 正确 OCI: jdbc:oracle:oci9:@192.168.0.18:1521:plan 找不到URL这个的错误 提示:我的机子其实装了oracle,由于内存太小(256M),所以数据库没有在本机上. 这还需要装oracle客户端吗? 另外我的配置有的也按照网上朋友所说的做了: <property name="hibernate.jdbc.batch_size">0</property> <property name="hibernate.jdbc.use_streams_for_binary">true</property> <property name="dialect"> org.hibernate.dialect.Oracle9Dialect </property> 请各位指点迷津,注意这里我只想使用自定义的用户类型方式实现CLOB到String的转换! 请看了此贴的朋友,如果可以解决说说解决办法,或是思想,不能解决的能给我一点建议! 初学JAVA时间不长,学HIBERNATE的时间就更短了,难免犯些低级的错误,请不要笑话! 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2005-12-06
第一种:
// StringReader r = new StringReader( (String) object); //下面的方法写入太多的数据会使CLOB为空,几百个字节没有问题 /* preparedStatement.setCharacterStream(_int, r, ( (String) object).length());*/ preparedStatement.setCharacterStream(_int, new InputStreamReader(new ByteArrayInputStream(((String) object).getBytes())), ( (String) object).length()); 第二种: //下面的方法写入数据的长度有限制 // preparedStatement.setString(_int,(String) object); 第三种: 会抛出无法从套接子读取太多数据的异常 我看了一些帖子说先要清楚,可在这里如何才能获得要清空的那个CLOB呢? 而下面的代码只是创建一个临时CLOB,然后对其写入数据,然后setClob(). DatabaseMetaData dbMetaData = ps.getConnection().getMetaData(); log.debug(dbMetaData.getDriverName()); log.debug(dbMetaData.getDriverMajorVersion() + " " + dbMetaData.getDriverMinorVersion()); log.debug(dbMetaData.getConnection().getClass().getName()); if (value == null) { ps.setNull(index, sqlTypes()[0]); } else if (ORACLE_DRIVER_NAME.equals(dbMetaData.getDriverName())) { if ((dbMetaData.getDriverMajorVersion() >= ORACLE_DRIVER_MAJOR_VERSION) && (dbMetaData.getDriverMinorVersion() >= ORACLE_DRIVER_MINOR_VERSION)) { try { // Code compliments of Scott Miller // support oracle clobs without requiring oracle libraries // at compile time // Note this assumes that if you are using the Oracle Driver. // then you have access to the oracle.sql.CLOB class // First get the oracle clob class Class oracleClobClass = Class.forName("oracle.sql.CLOB"); // Get the oracle connection class for checking Class oracleConnectionClass = Class.forName("oracle.jdbc.OracleConnection"); // now get the static factory method Class[] partypes = new Class[3]; partypes[0] = Connection.class; partypes[1] = Boolean.TYPE; partypes[2] = Integer.TYPE; Method createTemporaryMethod = oracleClobClass.getDeclaredMethod("createTemporary", partypes); // now get ready to call the factory method Field durationSessionField = oracleClobClass.getField("DURATION_SESSION"); Object[] arglist = new Object[3]; //changed from: Connection conn = ps.getConnection(); Connection conn = dbMetaData.getConnection(); // Make sure connection object is right type if (!oracleConnectionClass.isAssignableFrom(conn.getClass())) { throw new HibernateException("JDBC connection object must be a oracle.jdbc.OracleConnection. " + "Connection class is " + conn.getClass().getName()); } arglist[0] = conn; arglist[1] = Boolean.TRUE; arglist[2] = durationSessionField.get(null); //null is valid because of static field // Create our CLOB Object tempClob = createTemporaryMethod.invoke(null, arglist); //null is valid because of static method // get the open method partypes = new Class[1]; partypes[0] = Integer.TYPE; Method openMethod = oracleClobClass.getDeclaredMethod("open", partypes); // prepare to call the method Field modeReadWriteField = oracleClobClass.getField("MODE_READWRITE"); arglist = new Object[1]; arglist[0] = modeReadWriteField.get(null); //null is valid because of static field // call open(CLOB.MODE_READWRITE); openMethod.invoke(tempClob, arglist); // get the getCharacterOutputStream method Method getCharacterOutputStreamMethod = oracleClobClass.getDeclaredMethod("getCharacterOutputStream", null); // call the getCharacterOutpitStream method Writer tempClobWriter = (Writer) getCharacterOutputStreamMethod.invoke(tempClob, null); // write the string to the clob tempClobWriter.write((String) value); tempClobWriter.flush(); tempClobWriter.close(); // get the close method Method closeMethod = oracleClobClass.getDeclaredMethod("close", null); // call the close method closeMethod.invoke(tempClob, null); // add the clob to the statement ps.setClob(index, (Clob) tempClob); LobCleanUpInterceptor.registerTempLobs(tempClob); } catch (ClassNotFoundException e) { // could not find the class with reflection throw new HibernateException("Unable to find a required class.\n" + e.getMessage()); } catch (NoSuchMethodException e) { // could not find the metho with reflection throw new HibernateException("Unable to find a required method.\n" + e.getMessage()); } catch (NoSuchFieldException e) { // could not find the field with reflection throw new HibernateException("Unable to find a required field.\n" + e.getMessage()); } catch (IllegalAccessException e) { throw new HibernateException("Unable to access a required method or field.\n" + e.getMessage()); } catch (InvocationTargetException e) { throw new HibernateException(e.getMessage()); } catch (IOException e) { throw new HibernateException(e.getMessage()); } } else { throw new HibernateException("No CLOBS support. Use driver version " + ORACLE_DRIVER_MAJOR_VERSION + ", minor " + ORACLE_DRIVER_MINOR_VERSION); } } else { String str = (String) value; StringReader r = new StringReader(str); ps.setCharacterStream(index, r, str.length()); } 注意:LobCleanUpInterceptor我已经实现,并且在openSession()时这样写的openSession(new LobCleanUpInterceptor()) |
|
返回顶楼 | |
发表时间:2005-12-07
:( 怎么没人帮忙啊,难道......?
我也是考虑了很长时间实在是没法了才发贴的,如果问题大家觉得不难,不妨可以为我解开其中的迷惑. 按照Robbin的说法,也得先得到这个CLOB才能为它清空,然后再写入数据,可是在nullSafeSet中不知如何才能做到.给我的感觉是无法办到,因为前一个nullSafeSet如果是获取数据时执行,那么后一个就应该是更新数据时执行.这里看起来像是原子操作.要不然再在更新过程中再执行一次更新把它清空.我想这样是不合理的! 谁有好的想法可以一起讨论一下,虽然我是新的不能再新的新手(对于JAVA来说),就因为这样我希望得到更多高手帮助. |
|
返回顶楼 | |
发表时间:2005-12-14
Hibernate3我曾经尝试过映射为text,没有4096字节限制。不知道是不是我用Oracle10的JDBC驱动的原因,不过在Oracle9.2运行正常。
好像同一列如果有多个Clob字段,保存时候有bug,后来换spring的ClobStringType映射正常。 楼主可以试试。 |
|
返回顶楼 | |
发表时间:2005-12-14
没怎么看你的问题,不过Oracle Clob在映射到String下,做数据库操作时,跟Oracle JDBC驱动有狠大关系,前几天我还被这个问题搞叻一把。最后到oracle.com下载的Oracle 10g Release 2的最新驱动,换上去,什么毛病都没有。
|
|
返回顶楼 | |
发表时间:2005-12-15
难道非的换驱动吗?
我现在用最原始的办法去保存,取的话仍采用上面的方法没有问题. 但这样做已经没有利用到UserType带来的方便性了.期待有好的解决方案! 还有请问楼两位你们用的是UserType方式实现的吗,还是怎么做的? 我想的是如果使用UserType就可以在以后代码维护上面变的更加简单了. 期待使用UserType方式实现Clob到String的转换 最后感谢楼上两位给予的回复!!! |
|
返回顶楼 | |
发表时间:2005-12-15
3楼的朋友说spring的ClobStringType可以做到,我的一个新手,平时工作用的是Delphi,只是现在想转向使用JAVA开发,一下子没那么多经历学这么多新的东西,不过听说spring是开源的.不知是否可以通过它的源码找到一些灵感?
我只是这么想!有时间我也学学spring.看看它是如何实现的. JAVA的第三方产品太多了,学的真是很累很烦,不知何时可以跟的上大家.希望大家能与我共同探讨技术问题,同时也感谢能与我一起探讨问题的朋友与提出各种问题的朋友,从他们的回复与问题中让我学到了很多东西. |
|
返回顶楼 | |