String字符串存入数据库中超出最大长度(oracle varchar2 4000)?应合理分条存储(java实现-工具/方法)
问题描述
需要向数据库中保存数据,但某个字段内容长度过长(有中文、符号、英文),应该根据字符串内容与数据库存储上限合理设置储存方式。
解决思路
分条存储,即多条数据前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方法!
作者:kangkaii
如果您觉得本文有帮助的话,可以点个推荐呐!!
若有不对或者不合理的地方也欢迎指出,感谢~
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利.