如何将字符串与列表转为CLOB并存入Oracle TimesTen?创建CLOB时出错
问题描述
我需要将字符串与列表数组存储到Oracle TimesTen数据库的CLOB类型列中,尝试将字符串与列表转换为CLOB对象时,创建CLOB对象环节出现错误,相关代码如下,请提供解决方案。
原代码片段
创建CLOB对象
//Create RecordObject ro and then write into Clob object . Copy method used to get field list. public RecordObject convertToRecordObject(EventRecord er) throws SQLException, IOException { Clob clob = null; RecordObject ro = new RecordObject(er.getOriginalFilename().toString(), new ArrayList<RecordField>()); copy(er, ro.getFieldsList()); ObjectOutputStream out = new ObjectOutputStream(clob.setAsciiStream(0)); out.writeObject(ro); logger.info("Record Object :: " + ro.getFieldsList()); return ro; }
存储CLOB到数据库
//Connected to Timesten DB , Prepared Statement and then psmt.setString(1, key); psmt.setClob(1, key); psmt.executeUpdate();
RecordObject.java
//Record Object having string and no. of fields in list public class RecordObject implements Serializable { private String file_name; private List<RecordField> fieldsList; public RecordObject(String file_name, List<RecordField> fieldsList) { this.file_name = file_name; this.fieldsList = fieldsList; } RecordObject() {} public List<RecordField> getFieldsList() { return fieldsList; } public void setFieldsList(List<RecordField> fieldsList) { this.fieldsList = fieldsList; } public String getFile_name() { return file_name; } public void setFile_name(String file_name) { this.file_name = file_name; } }
解决方案
原代码存在多个核心问题,以下是针对性修复:
1. 正确初始化CLOB对象
原代码中Clob clob = null;直接调用clob.setAsciiStream(0)会触发空指针异常。必须通过数据库连接创建合法的Clob实例,且TimesTen要求流起始索引为1而非0。
2. 修复序列化流处理
使用try-with-resources自动管理输出流,确保数据完整写入CLOB后关闭资源,避免泄漏。
3. 修正PreparedStatement参数设置
原代码重复设置同一个参数索引(psmt.setString(1, key)和psmt.setClob(1, key)),导致参数覆盖。需根据SQL语句的占位符位置分别设置对应参数。
4. 确保序列化完整性
RecordField类必须实现Serializable接口,否则对象序列化会失败。
修复后的代码示例
创建CLOB对象的方法
// 将RecordObject序列化为Clob并返回 public Clob convertToRecordObject(Connection conn, EventRecord er) throws SQLException, IOException { // 通过数据库连接创建合法的Clob实例 Clob clob = conn.createClob(); RecordObject ro = new RecordObject(er.getOriginalFilename().toString(), new ArrayList<RecordField>()); copy(er, ro.getFieldsList()); // TimesTen的流起始索引为1,使用try-with-resources自动关闭流 try (ObjectOutputStream out = new ObjectOutputStream(clob.setAsciiStream(1))) { out.writeObject(ro); } logger.info("Record Object :: " + ro.getFieldsList()); return clob; }
存储CLOB到数据库的代码
// 假设SQL语句为 INSERT INTO your_table (key_column, clob_column) VALUES (?, ?) psmt.setString(1, key); // 设置第一个占位符为key字符串 psmt.setClob(2, clob); // 设置第二个占位符为序列化后的Clob对象 psmt.executeUpdate();
补充:RecordField类需实现Serializable
public class RecordField implements Serializable { // 类成员及方法 }
内容的提问来源于stack exchange,提问作者Sunny Jangid
相关产品推荐
相关产品推荐

