因为需求变化,以前使用varchar2就可以存储的内容需要替换为clob字段进行存储。如果使用的是oracle12c版本的,只需修改varchar2的长度为36000就可以了。而之前的版本只能通过clob字段来进行大文本的存储。方法就是通过流的方式将文本写入到数据库。
当前项目使用的是dwr这个框架。也出现了从前端传回来的json对象会无法转换成java对象,这是由于String类型无法直接转换为clob对象。所以解决方法是从前端传json字符串或者单独传需要转为clob对象的字符串,然后在后端再生成java对象。
以下是代码示例:
实体类:
public class Book implements AbstractEntity {
private String no;
private String bookName;
private Clob bookContent;
private static final String[] PROPERTICE_NAME = new String[] {
"no",
"bookName",
"bookContent"
};
private static final Class<?>[] PROPERTICE_TYPE = new Class[] {
String.class,
String.class,
Clob.class
};
public QualityGuaranteeSys(){
}
public String getNo() {
Object obj = getProperties().get(PROPERTICE_NAME[0]);
return obj != null ? obj.toString() : null;
}
public void setNo(String no) {
getProperties().put(PROPERTICE_NAME[0], no);
}
public String getBookName() {
Object obj = getProperties().get(PROPERTICE_NAME[1]);
return obj != null ? obj.toString() : null;
}
public void setBookName(String bookName) {
getProperties().put(PROPERTICE_NAME[1], bookName);
}
public Clob getBookContent() {
Object obj = getProperties().get(PROPERTICE_NAME[2]);
return obj != null ? (Clob)obj : null;
}
public void setBookContent(Clob bookContent) {
getProperties().put(PROPERTICE_NAME[2], bookContent);
}
}
CommonDao:使用的是hibernate
// 存取带clob类型的对象
public boolean saveEntityWithClob(AbstractEntity entity, Map<String, String> longTexts){
Session session = null;
try{
session = this.getSession();
session.beginTransaction();
BeanUtil.insertEmptyForClob(entity); // 插入空值
session.save(entity); // session插入的字符过长会报错
session.flush();
session.refresh(entity, LockMode.UPGRADE); // 锁住此行
writeClobs(BeanUtil.getAllClobsInEntity(entity), longTexts); // 将clob对象的值写进去
session.getTransaction().commit();
}catch (Exception e) {
e.printStackTrace();
return false;
}finally {
if(session != null)
session.close();
}
return true;
}
private void writeClobs(Map<String, Clob> clobsMap, Map<String, String> longTexts) {
if(clobsMap.isEmpty() || longTexts.isEmpty())
return;
for(String key : clobsMap.keySet()) {
if(clobsMap.get(key) == null || longTexts.get(key) == null) // 如果没有值就进行下一次循环
continue;
writeClob(clobsMap.get(key), longTexts.get(key));
}
}
// 将获取到的clob对象使用流的方式输入
private void writeClob(Clob clobField, String longText) {
//oracle.sql.CLOB clob = (oracle.sql.CLOB)clobField;
java.sql.Clob wrapclob = (java.sql.Clob)(((org.hibernate.lob.SerializableClob) clobField).getWrappedClob());
Writer pw = null;
try {
if(wrapclob instanceof oracle.sql.CLOB) {
oracle.sql.CLOB clob = (oracle.sql.CLOB)wrapclob;
pw = clob.getCharacterOutputStream();
pw.write(longText);//写入长文本
}
} catch (SQLException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}finally {
if(pw != null)
try {
pw.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
// 更新带clob类型的对象
public boolean updateEntityWithClob(AbstractEntity entity, Map<String, String> longTexts){
Session session = null;
try{
session = this.getSession();
session.beginTransaction();
BeanUtil.insertEmptyForClob(entity); // 插入空值
session.update(entity);
session.flush();
session.refresh(entity, LockMode.UPGRADE); // 锁住此行
writeClobs(BeanUtil.getAllClobsInEntity(entity), longTexts); // 将clob对象的值写进去
session.getTransaction().commit();
}catch (Exception e) {
return false;
}finally {
if(session != null)
session.close();
}
return true;
}
BeanUtil:
public class BeanUtil {
public static void insertEmptyForClob(AbstractEntity entity) {
Class<?>[] properticeType = entity.getEntityPropertiesType();
String[] properticeName = entity.getEntityPropertiesName();
for(int i = 0; i < properticeType.length; i++) {
if(properticeType[i].isAssignableFrom(Clob.class))
entity.getProperties().put(properticeName[i], Hibernate.createClob(" ")); // 为每个clob字段插入空值,注意需要插入1个字节的空格,否则会返回一个空对象
}
}
/**
* 获取实体类中所有的Clob对象,键是属性名,值是clob字段
* */
public static Map<String, Clob> getAllClobsInEntity(AbstractEntity entity) {
Map<String, Clob> clobsMap = new HashMap<String, Clob>();
Class<?>[] properticeType = entity.getEntityPropertiesType();
String[] properticeName = entity.getEntityPropertiesName();
for(int i = 0; i < properticeType.length; i++) {
if(properticeType[i].isAssignableFrom(Clob.class)) {
Object obj = entity.getProperties().get(properticeName[i]);
clobsMap.put(properticeName[i], obj != null ? (Clob) obj : null);
}
}
return clobsMap;
}
/**
* 获取实体类中所有的Clob对象中字符串的内容,键是属性名,值是clob字段的字符串内容
* */
public static Map<String, String> getAllClobsStringInEntity(AbstractEntity entity) {
Map<String, String> clobStringsMap = new HashMap<String, String>();
Class<?>[] properticeType = entity.getEntityPropertiesType();
String[] properticeName = entity.getEntityPropertiesName();
for(int i = 0; i < properticeType.length; i++) {
if(properticeType[i].isAssignableFrom(Clob.class)) {
Object obj = entity.getProperties().get(properticeName[i]);
clobStringsMap.put(properticeName[i], obj != null ? ClobUtil.ClobToString((Clob) obj) : "");
}
}
return clobStringsMap;
}
}
ClobUtil:
public class ClobUtil {
public static String ClobToString(Clob clob) {
String clobStr = "";
Reader is = null;
try {
is = clob.getCharacterStream();
// 得到流
BufferedReader br = new BufferedReader(is);
String s = null;
s = br.readLine();
StringBuffer sb = new StringBuffer();
// 执行循环将字符串全部取出赋值给StringBuffer,由StringBuffer转成String
while (s != null) {
sb.append(s);
s = br.readLine();
}
clobStr = sb.toString();
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}
return clobStr;
}
}
读取clob字段,我暂时不知道如何通过hibernate读取,所以我这里使用的jdbc的方式读取clob字段
/**
* @Title: executeQuery
* @Description:
* 执行静态Sql 查询语句,把结果集合放在一个 List<Map<String,Object>> 里面
* @param sql
* @return
* @return List<Map<String,Object>>
*/
public List<Map<String, Object>> executeQuery(String sql) {
Connection con = null;
Statement statement = null;
ResultSet rs = null;
List<Map<String, Object>> result = new ArrayList<Map<String, Object>>();
try {
con=JdbcUtils.getConnection();
statement = con.createStatement();
rs = statement.executeQuery(sql);
ResultSetMetaData md = (ResultSetMetaData) rs.getMetaData();
int columnCount = md.getColumnCount();
while(rs.next()) {
Map<String, Object> hs = new HashMap<String, Object>();
for (int i = 1; i <= columnCount; i++) { // 将Clob对象转换为
if(!(rs.getObject(i) instanceof oracle.sql.CLOB))
hs.put(md.getColumnName(i), rs.getObject(i));
else{
hs.put(md.getColumnName(i),ClobUtil.ClobToString(rs.getClob(i)));
}
}
result.add(hs);
}
} catch (SQLException e) {
e.printStackTrace();
}finally{
JdbcUtils.close(rs, statement, con);
}
return result;
}
以上就是对clob字段的插入、修改和读取的方法。而blob字段操作跟clob字段基本相似,所以在此就不再进行阐述。