String字符串存入數據庫中超出最大長度(oracle varchar2 4000)?應合理分條存儲(java實現-工具/方法)

問題描述

須要向數據庫中保存數據,但某個字段內容長度過長(有中文、符號、英文),應該根據字符串內容與數據庫存儲上限合理設置儲存方式。數據庫

解決思路

分條存儲,即多條數據前n個字段一致,最後內容字段不一樣,下方代碼可高效利用數據庫空間!app

代碼以下

public class StringSavingUtils {
    /**
     * 根據參數length,將String類型對象,進行截取
     * 用於將長字符串,存入數據庫中
     * 避免過長 數據庫保存失敗
     * 避免直接寫死長度 產生沒必要要數據
     * 前提:一個漢字 佔3個字節
     *      一個英文 佔1個字節
     * @param content 須要截取的字符串
     * @param lengthMax 數據庫中存儲的最大長度
     * @param lengthCN 漢字佔的字節數
     * @return List<String>
     */
    public static List<String> getList(String content,int lengthMax,int lengthCN) {
        List<String> resultList = new ArrayList<>();
        if (StringUtils.isEmpty(content) || lengthMax <= 0 || lengthCN <= 0 || (lengthMax <=lengthCN)) {
            throw new RuntimeException("參數非法");
        }
        try {
            while(true) {
                //最好狀況:content即便都是中文,也 <= lengthMax
                if (content.length() <= lengthMax / lengthCN) {
                    resultList.add(content);
                    break;
                }
                //有超長的可能
                else {
                    int lenStart = 0;
                    //截取到lengthMax / lengthCN,計算總長度
                    for (int i = 0; i < lengthMax / lengthCN; i++) {
                        //獲取每一個c的長度+++
                        String c = content.substring(i,i+1);
                        lenStart += c.getBytes("UTF-8").length;
                    }
                    StringBuilder builder = new StringBuilder(content.substring(0, (lengthMax / lengthCN)));
                    //循環:當達到最大能儲存的最大值 或者 剩下的content取完
                    int i = lengthMax / lengthCN;
                    while (lenStart <= lengthMax && i < content.length()) {
                        String c = content.substring(i,i+1);
                        lenStart += c.getBytes("UTF-8").length;
                        builder.append(c);
                        i++;
                    }
                    //應清楚:當由於達到上限跳出循環時,while循環中的全部操做都是多餘的
                    // 包括:i++ -> bug01
                    // 包括:builder最後一次append -> bug02
                    //爲什麼退出循環?
                    // 1:加到content結束,沒有達到lengthMax->直接add到resultList
                    // 2:達到了上限->content被賦值成後半段
                    if (lenStart <= lengthMax) {
                        resultList.add(content);
                        break;
                    }else {
                        //bug01
                        content = content.substring(i-1);
                        String line = builder.toString();
                        //bug02
                        resultList.add(line.substring(0,line.length()-1));
                    }
                }
            }
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
        }
        return resultList;
    }

}

最後

根據方法返回的list,list.forEach(),循環構造實體+調用save方法!ui

相關文章
相關標籤/搜索