問題描述
需要向數據庫中保存數據,但某個字段內容長度過長(有中文、符號、英文),應該根據字符串內容與數據庫存儲上限合理設置儲存方式。
解決思路
分條存儲,即多條數據前n個字段一致,最后內容字段不同,下方代碼可高效利用數據庫空間!
代碼如下
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方法!