Re: Hibernate:使用用户定义的类型转换CLOB到String(setCharacte...

终于可以发贴了,在http://www.matrix.org.cn/thread.shtml?topicId=32938&forumId=23上给出问题,竞没人回话,先说问题吧!
我在自己定义的用户类型中遇到下面的问题:
下面这个函数读出数据没有问题:
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的时间就更短了,难免犯些低级的错误,请不要笑话!
------------------------------------------------------------------------------------------------------------------------------------------

第一种:
// 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())
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值