dwr+oracle進行clob、blob字段插入、修改和讀取

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

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章