因爲需求變化,以前使用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字段基本相似,所以在此就不再進行闡述。