背景
因为Mybatis-Plus的saveBatch()方法的批量插入其实也是循环插入,而不是真正的一个SqlSession完成的批插,效率很低。所以我们在写批量插入的时候是自己实现了一个工具类去生成批量插入的sql再去执行,但是会遇到有些文本里有单引号导致插入失败的情况,因此需要优化这个工具类
优化工具类
先贴一下优化后的工具类的代码
java
/**
* 构建批量插入语句 insert 语句
*
* @param clazz 实体类class
* @param beanList 要插入的带值的对象集合
* @param ignoreFields 需要忽略的属性名集合
*/
public static <T> String getInsertString(Class<T> clazz, Collection<T> beanList, String... ignoreFields) {
StringBuilder insertSql = new StringBuilder();
String className = clazz.getSimpleName();
insertSql.append("insert into ").append(StrUtil.toUnderlineCase(className)).append("(");
Field[] allFields = FieldUtils.getAllFields(clazz);
// 构建字段
StringBuilder columnSql = new StringBuilder();
for (Field field : allFields) {
// 构建非static的属性
String name = field.getName();
if (!isIgnore(ignoreFields, name)) {
if (!Modifier.isStatic(field.getModifiers())) {
columnSql.append(StrUtil.toUnderlineCase(name)).append(",");
}
}
}
insertSql.append(StrUtil.removeSuffix(columnSql.toString(), ",")).append(")").append(" values ");
// 循环构建参数
for (T t : beanList) {
StringBuilder paramsSql = new StringBuilder();
paramsSql.append("(");
// 根据字段构建参数
for (Field field : allFields) {
// 构建非static的属性
String name = field.getName();
if (!isIgnore(ignoreFields, name)) {
if (!Modifier.isStatic(field.getModifiers())) {
Object fieldValue = ReflectUtil.getFieldValue(t, field.getName());
/* 根据格式转换数据 */
if (fieldValue instanceof String) {
String fieldValueStr = (String) ReflectUtil.getFieldValue(t, name);
//防止值里面有'导致插入数据失败
if (StringUtils.isNotBlank(fieldValueStr)) {
fieldValueStr = fieldValueStr.replaceAll("'", "''");
paramsSql.append("'").append(fieldValueStr).append("',");
} else {
paramsSql.append("null,");
}
} else if (fieldValue instanceof Enum) {
paramsSql.append("'").append(ReflectUtil.getFieldValue(t, name)).append("',");
} else if (fieldValue instanceof Date) {
Date dateValue = (Date) ReflectUtil.getFieldValue(t, name);
paramsSql.append("'").append(DateUtil.format(dateValue, DatePattern.NORM_DATETIME_PATTERN)).append("',");
} else if (fieldValue instanceof LocalDateTime) {
LocalDateTime dateValue = (LocalDateTime) ReflectUtil.getFieldValue(t, name);
paramsSql.append("'").append(DateUtil.format(dateValue, DatePattern.NORM_DATETIME_PATTERN)).append("',");
} else {
paramsSql.append(ReflectUtil.getFieldValue(t, name)).append(",");
}
}
}
}
insertSql.append(StrUtil.removeSuffix(paramsSql.toString(), ",")).append(")").append(",");
}
return StrUtil.removeSuffix(insertSql.toString(), ",");
}
处理方案
对于'这种特殊符号,可以直接将一个单引号修改为两个单引号,在执行sql语句的时候,两个单引号会被像转移字符一样处理成一个单引号入库,这样即不会报错,也可以保留文本的原始内容