最近在用jpa,批量插入效率皮较低,所以就写了个生成sql的方法,执行本地sql,这样效率有明显提升,可惜一次只能插入1000条 /** * @author > * @Description: 生成sql语句 * @date 2022-03-31 16:24 */ public final class GenerateSqlUtils { private static final Pattern HUMP_PATTERN = Pattern.compile("[A-Z]"); public static final Integer BATCH_INSERT_NUMBER = 1000; /** * 生成 插入 语句:insert into person(name, age, info) values ('张三', '30', '*****'); * * @param objectList List * @return String */ public static String batchInsertSql(List<?> objectList, UserInfo currentUser) { try { // 插入数据的列名 StringBuilder columns = new StringBuilder("("); // 如果为空则不执行 if (CollectionUtil.isEmpty(objectList)) { return ""; } //通过 List 中的第一个 Object,确定插入对象的字段 Object object = objectList.get(0); Class<?> clazz = object.getClass(); List<Field> fieldsList = new ArrayList<>(); assert object.getClass() != null; String tableName = humpToLine(object.getClass().getSimpleName()).replaceFirst("_", ""); // 遍历所有父类字节码对象 while (clazz != null) { Field[] declaredFields = clazz.getDeclaredFields(); //将`Filed[]`数组转换为`List<>`然后再将其拼接至`ArrayList`上 fieldsList.addAll(Arrays.asList(declaredFields)); // 获得父类的字节码对象 clazz = clazz.getSuperclass(); } // 打印当前类以及其父类的多有属性对象 for (Field field : fieldsList) { //不处理 sort,pageIndex,pageSize字段 if (field.getAnnotation(Transient.class) != null) { continue; } columns.append(humpToLine(field.getName())).append(", "); } columns.replace(columns.lastIndexOf(", "), columns.length(), ")"); StringBuilder values = new StringBuilder(); //获取所有的值,构造values的值 for (Object obj : objectList) { values.append("("); for (Field field : fieldsList) { field.setAccessible(true); //不处理 sort,pageIndex,pageSize字段 if (field.getAnnotation(Transient.class) != null) { continue; } if (field.getAnnotation(Id.class) != null && null == field.get(obj)) { values.append(generatePkId(tableName)); values.append(", "); } else { values.append(colTypeConvert(field.get(obj))); values.append(", "); } } values.replace(values.lastIndexOf(","), values.length(), ""); values.append("),"); } values.replace(values.lastIndexOf(","), values.length(), ""); return "INSERT INTO " + tableName + " " + columns + "VALUES " + values; } catch (IllegalAccessException e) { e.printStackTrace(); } // 生成最终 SQL return ""; } /** * 生成 update 语句: update EXAM_ITEM_DIC set EXAM_ITEM_NAME=case when EXAM_ITEM_DIC_ID = 220067666731872256 then 1 when EXAM_ITEM_DIC_ID = 220067666731872258 then 2 end where EXAM_ITEM_DIC_ID in (220067666731872256, 220067666731872258) * * @param objectList List * @return String * @throws IllegalAccessException 抛出异常 */ public static String batchUpdateSql(List<?> objectList, UserInfo currentUser) { try { StringBuilder updateContent = new StringBuilder(); // 如果为空则不执行 if (CollectionUtil.isEmpty(objectList)) { return ""; } //通过 List 中的第一个 Object,确定插入对象的字段 Object object = objectList.get(0); Class<?> clazz = object.getClass(); String tableName = humpToLine(object.getClass().getSimpleName()).replaceFirst("_", ""); List<String> pkNames = new ArrayList<>(); List<Object> pkValues = new ArrayList<>(); List<Field> pkFields = new ArrayList<>(); //不包括父类的字段 Field[] fields = clazz.getDeclaredFields(); for (Field field : fields) { if (field.getAnnotation(Id.class) != null) { //查找主键字段名 pkNames.add(field.getName()); pkFields.add(field); } } updateContent.append(" set "); for (Field field : fields) { field.setAccessible(true); if (!pkNames.contains(field.getName())) { updateContent.append(humpToLine(field.getName())).append("= case "); for (Object obj : objectList) { updateContent.append(" when "); if (CollectionUtils.isNotEmpty(pkNames)) { Field pkField = pkFields.get(0); pkField.setAccessible(true); updateContent.append(humpToLine(pkField.getName())).append("=").append(colTypeConvert(pkField.get(obj))); } updateContent.append(" then ").append(colTypeConvert(field.get(obj))); } updateContent.append(" else ").append(humpToLine(field.getName())); updateContent.append(" end, "); } } updateContent.updateContent(updateContent.lastIndexOf(","), updateContent.length(), ""); for (Object obj : objectList) { if (CollectionUtils.isNotEmpty(pkNames)) { Field pkField = pkFields.get(0); pkField.setAccessible(true); pkValues.add(pkField.get(obj)); } } return "UPDATE " + tableName + " " + updateContent + " where " + humpToLine(pkFields.get(0).getName()) + " in (" + StringUtils.join(pkValues, ",") + ")"; } catch (IllegalAccessException e) { e.printStackTrace(); } return ""; } /** * 驼峰转下划线 * * @param str String * @return String */ public static String humpToLine(String str) { Matcher matcher = HUMP_PATTERN.matcher(str); StringBuffer sb = new StringBuffer(); while (matcher.find()) { matcher.appendReplacement(sb, "_" + matcher.group(0).toLowerCase()); } matcher.appendTail(sb); return sb.toString(); } /** * 生成主键 * * @return Long */ private static Long generatePkId(String tableName) { /***88888****/ } /** * instanceSerial String * * @return Long */ private static Long getId(String instanceSerial) { /***88888****/ } /** * 字段类型转换 * * @param obj Object * @return Object */ public static Object colTypeConvert(Object obj) { /***88888****/ } }
java 反射生成批量插入或者新增更新sql
于 2022-04-02 15:29:49 首次发布