From 5c80d4ecd45febb891dde39bb9556ce873ad18c8 Mon Sep 17 00:00:00 2001 From: Odboy Date: Fri, 6 Mar 2026 19:56:29 +0800 Subject: [PATCH] =?UTF-8?q?feat(MybatisMapperBatchOpRender):=20=E5=AE=9E?= =?UTF-8?q?=E7=8E=B0Mybatis=E6=89=B9=E9=87=8F=E6=93=8D=E4=BD=9CXML?= =?UTF-8?q?=E7=94=9F=E6=88=90=E5=99=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - 添加StrUtil和BadRequestException依赖导入 - 增加TableName注解支持验证实体类有效性 - 实现批量插入、更新、删除XML模板生成功能 - 添加字段过滤逻辑排除serialVersionUID - 实现主键字段验证和参数校验功能 - 生成标准的Mybatis批量操作SQL映射XML - 支持下划线命名转换和动态字段映射 - 提供完整的批量操作接口方法声明生成 --- .../cn/odboy/MybatisMapperBatchOpRender.java | 118 ++++++++++++++++ .../cn/odboy/MybatisMapperBatchOpRender.java | 118 ++++++++++++++++ .../cn/odboy/MybatisMapperBatchOpRender.java | 129 +++++++++++++----- 3 files changed, 334 insertions(+), 31 deletions(-) create mode 100644 cutejava-springboot3/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java create mode 100644 cutejava-springboot4/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java diff --git a/cutejava-springboot3/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java b/cutejava-springboot3/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java new file mode 100644 index 00000000..e205dd63 --- /dev/null +++ b/cutejava-springboot3/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java @@ -0,0 +1,118 @@ +package cn.odboy; + +import cn.hutool.core.util.StrUtil; +import cn.odboy.framework.exception.BadRequestException; +import cn.odboy.system.dal.dataobject.SystemDeptTb; +import cn.odboy.util.KitClassUtil; +import com.baomidou.mybatisplus.annotation.TableName; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Mybatis批量操作生成器 + * + * @author odboy + */ +public class MybatisMapperBatchOpRender { + + /** + * 渲染MapperXml + * + * @param entityClass 持久类 + * @param primaryKeyName 主键名称 + */ + public void render(Class entityClass, String primaryKeyName) { + if (entityClass == null) { + throw new BadRequestException("参数 entityClass 必填"); + } + TableName tableNameAnnotation = entityClass.getAnnotation(TableName.class); + if (tableNameAnnotation == null) { + throw new BadRequestException("参数 entityClass 不是一个有效的Mybatis表对象"); + } + + List fields = new ArrayList<>(); + KitClassUtil.getAllFields(entityClass, fields); + fields = fields.stream().filter(f -> !"serialVersionUID".equals(f.getName())).collect(Collectors.toList()); + + Field primaryKeyField = fields.stream().filter(f -> f.getName().equals(primaryKeyName)).findFirst().orElse(null); + if (primaryKeyField == null) { + throw new BadRequestException("参数 primaryKeyName 设置有误"); + } + + fields = fields.stream().filter(f -> !f.getName().equals(primaryKeyName)).collect(Collectors.toList()); + + // 持久类主键类型名 + String entityPkTypeName = primaryKeyField.getType().getSimpleName(); + // 持久类名 + String entityClassName = entityClass.getSimpleName(); + // 数据表名 + String tableName = tableNameAnnotation.value(); + + System.err.println("============== 渲染Mapper =================="); + String mapperBatchInsert = "void batchInsert(@Param(\"list\") List<$EntityClassName> list);"; + System.err.println(mapperBatchInsert.replace("$EntityClassName", entityClassName)); + String mapperBatchUpdate = "void batchUpdateById(@Param(\"list\") List<$EntityClassName> list);"; + System.err.println(mapperBatchUpdate.replace("$EntityClassName", entityClassName)); + String mapperBatchDelete = "void batchDeleteByIds(@Param(\"list\") List<$EntityPkTypeName> list);"; + System.err.println(mapperBatchDelete.replace("$EntityPkTypeName", entityPkTypeName)); + System.err.println("\n============== 渲染MapperXml =================="); + List fieldNameList = new ArrayList<>(); + List fieldNameUnderlineList = new ArrayList<>(); + List fieldNameItemList = new ArrayList<>(); + + for (Field field : fields) { + fieldNameList.add(field.getName()); + } + for (String fieldName : fieldNameList) { + fieldNameUnderlineList.add(StrUtil.toUnderlineCase(fieldName)); + fieldNameItemList.add("#{item." + fieldName + "}"); + } + + String batchInsertXml = "\n" + + "INSERT INTO " + tableName + " (" + + String.join(",", fieldNameUnderlineList) + + ") VALUES\n" + + "\n" + + "(\n" + + String.join(",\n", fieldNameItemList) + + ")\n" + + "\n" + + "\n"; + System.err.println(batchInsertXml); + + StringBuilder ifStringBuilder = new StringBuilder(); + for (int i = 0; i < fieldNameList.size(); i++) { + ifStringBuilder.append("") + .append(fieldNameUnderlineList.get(i)) + .append(" = #{item.") + .append(fieldNameList.get(i)) + .append("},\n"); + } + String batchUpdateXml = "\n" + + "\n" + + "UPDATE " + tableName + "\n" + + "\n" + + ifStringBuilder + + "\n" + + "WHERE " + StrUtil.toUnderlineCase(primaryKeyName) + " = #{item." + primaryKeyName + "}\n" + + "\n" + + "\n"; + System.err.println(batchUpdateXml); + + String batchDeleteXml = "\n" + + "delete from " + tableName + " where " + StrUtil.toUnderlineCase(primaryKeyName) + " in\n" + + "\n" + + "#{id}\n" + + "\n" + + ""; + System.err.println(batchDeleteXml); + } + + public static void main(String[] args) { + new MybatisMapperBatchOpRender().render(SystemDeptTb.class, "id"); + } +} diff --git a/cutejava-springboot4/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java b/cutejava-springboot4/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java new file mode 100644 index 00000000..e205dd63 --- /dev/null +++ b/cutejava-springboot4/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java @@ -0,0 +1,118 @@ +package cn.odboy; + +import cn.hutool.core.util.StrUtil; +import cn.odboy.framework.exception.BadRequestException; +import cn.odboy.system.dal.dataobject.SystemDeptTb; +import cn.odboy.util.KitClassUtil; +import com.baomidou.mybatisplus.annotation.TableName; +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +/** + * Mybatis批量操作生成器 + * + * @author odboy + */ +public class MybatisMapperBatchOpRender { + + /** + * 渲染MapperXml + * + * @param entityClass 持久类 + * @param primaryKeyName 主键名称 + */ + public void render(Class entityClass, String primaryKeyName) { + if (entityClass == null) { + throw new BadRequestException("参数 entityClass 必填"); + } + TableName tableNameAnnotation = entityClass.getAnnotation(TableName.class); + if (tableNameAnnotation == null) { + throw new BadRequestException("参数 entityClass 不是一个有效的Mybatis表对象"); + } + + List fields = new ArrayList<>(); + KitClassUtil.getAllFields(entityClass, fields); + fields = fields.stream().filter(f -> !"serialVersionUID".equals(f.getName())).collect(Collectors.toList()); + + Field primaryKeyField = fields.stream().filter(f -> f.getName().equals(primaryKeyName)).findFirst().orElse(null); + if (primaryKeyField == null) { + throw new BadRequestException("参数 primaryKeyName 设置有误"); + } + + fields = fields.stream().filter(f -> !f.getName().equals(primaryKeyName)).collect(Collectors.toList()); + + // 持久类主键类型名 + String entityPkTypeName = primaryKeyField.getType().getSimpleName(); + // 持久类名 + String entityClassName = entityClass.getSimpleName(); + // 数据表名 + String tableName = tableNameAnnotation.value(); + + System.err.println("============== 渲染Mapper =================="); + String mapperBatchInsert = "void batchInsert(@Param(\"list\") List<$EntityClassName> list);"; + System.err.println(mapperBatchInsert.replace("$EntityClassName", entityClassName)); + String mapperBatchUpdate = "void batchUpdateById(@Param(\"list\") List<$EntityClassName> list);"; + System.err.println(mapperBatchUpdate.replace("$EntityClassName", entityClassName)); + String mapperBatchDelete = "void batchDeleteByIds(@Param(\"list\") List<$EntityPkTypeName> list);"; + System.err.println(mapperBatchDelete.replace("$EntityPkTypeName", entityPkTypeName)); + System.err.println("\n============== 渲染MapperXml =================="); + List fieldNameList = new ArrayList<>(); + List fieldNameUnderlineList = new ArrayList<>(); + List fieldNameItemList = new ArrayList<>(); + + for (Field field : fields) { + fieldNameList.add(field.getName()); + } + for (String fieldName : fieldNameList) { + fieldNameUnderlineList.add(StrUtil.toUnderlineCase(fieldName)); + fieldNameItemList.add("#{item." + fieldName + "}"); + } + + String batchInsertXml = "\n" + + "INSERT INTO " + tableName + " (" + + String.join(",", fieldNameUnderlineList) + + ") VALUES\n" + + "\n" + + "(\n" + + String.join(",\n", fieldNameItemList) + + ")\n" + + "\n" + + "\n"; + System.err.println(batchInsertXml); + + StringBuilder ifStringBuilder = new StringBuilder(); + for (int i = 0; i < fieldNameList.size(); i++) { + ifStringBuilder.append("") + .append(fieldNameUnderlineList.get(i)) + .append(" = #{item.") + .append(fieldNameList.get(i)) + .append("},\n"); + } + String batchUpdateXml = "\n" + + "\n" + + "UPDATE " + tableName + "\n" + + "\n" + + ifStringBuilder + + "\n" + + "WHERE " + StrUtil.toUnderlineCase(primaryKeyName) + " = #{item." + primaryKeyName + "}\n" + + "\n" + + "\n"; + System.err.println(batchUpdateXml); + + String batchDeleteXml = "\n" + + "delete from " + tableName + " where " + StrUtil.toUnderlineCase(primaryKeyName) + " in\n" + + "\n" + + "#{id}\n" + + "\n" + + ""; + System.err.println(batchDeleteXml); + } + + public static void main(String[] args) { + new MybatisMapperBatchOpRender().render(SystemDeptTb.class, "id"); + } +} diff --git a/cutejava/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java b/cutejava/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java index aee233fd..e205dd63 100644 --- a/cutejava/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java +++ b/cutejava/cutejava-starter/src/main/java/cn/odboy/MybatisMapperBatchOpRender.java @@ -1,11 +1,13 @@ package cn.odboy; +import cn.hutool.core.util.StrUtil; +import cn.odboy.framework.exception.BadRequestException; import cn.odboy.system.dal.dataobject.SystemDeptTb; import cn.odboy.util.KitClassUtil; +import com.baomidou.mybatisplus.annotation.TableName; import java.lang.reflect.Field; import java.util.ArrayList; import java.util.List; -import java.util.function.Function; import java.util.stream.Collectors; /** @@ -14,38 +16,103 @@ import java.util.stream.Collectors; * @author odboy */ public class MybatisMapperBatchOpRender { - /** - * 持久类名 - */ - private String entityClassName; - /** - * 持久类主键类型名 - */ - private String entityPkTypeName; - /** - * 渲染MapperXml - * - * @param entityClass 持久类 - * @param keyMapper 哪个是主键 - */ - public void render(Class entityClass, Function keyMapper) { - String mapperBatchInsert = "void batchInsert(@Param(\"list\") List<$EntityClassName> list);"; - System.err.println(mapperBatchInsert.replace("$EntityClassName", this.entityClassName)); - String mapperBatchUpdate = "void batchUpdateById(@Param(\"list\") List<$EntityClassName> list);"; - System.err.println(mapperBatchUpdate.replace("$EntityClassName", this.entityClassName)); - String mapperBatchDelete = "void batchDeleteByIds(@Param(\"list\") List<$EntityPkTypeName> list);"; - System.err.println(mapperBatchDelete.replace("$EntityPkTypeName", this.entityPkTypeName)); - - List fields = new ArrayList<>(); - KitClassUtil.getAllFields(entityClass, fields); - - fields = fields.stream().filter(f -> !"serialVersionUID".equals(f.getName())).collect(Collectors.toList()); - - System.err.println(fields); + /** + * 渲染MapperXml + * + * @param entityClass 持久类 + * @param primaryKeyName 主键名称 + */ + public void render(Class entityClass, String primaryKeyName) { + if (entityClass == null) { + throw new BadRequestException("参数 entityClass 必填"); + } + TableName tableNameAnnotation = entityClass.getAnnotation(TableName.class); + if (tableNameAnnotation == null) { + throw new BadRequestException("参数 entityClass 不是一个有效的Mybatis表对象"); } - public static void main(String[] args) { - new MybatisMapperBatchOpRender().render(SystemDeptTb.class, SystemDeptTb::getId); + List fields = new ArrayList<>(); + KitClassUtil.getAllFields(entityClass, fields); + fields = fields.stream().filter(f -> !"serialVersionUID".equals(f.getName())).collect(Collectors.toList()); + + Field primaryKeyField = fields.stream().filter(f -> f.getName().equals(primaryKeyName)).findFirst().orElse(null); + if (primaryKeyField == null) { + throw new BadRequestException("参数 primaryKeyName 设置有误"); } + + fields = fields.stream().filter(f -> !f.getName().equals(primaryKeyName)).collect(Collectors.toList()); + + // 持久类主键类型名 + String entityPkTypeName = primaryKeyField.getType().getSimpleName(); + // 持久类名 + String entityClassName = entityClass.getSimpleName(); + // 数据表名 + String tableName = tableNameAnnotation.value(); + + System.err.println("============== 渲染Mapper =================="); + String mapperBatchInsert = "void batchInsert(@Param(\"list\") List<$EntityClassName> list);"; + System.err.println(mapperBatchInsert.replace("$EntityClassName", entityClassName)); + String mapperBatchUpdate = "void batchUpdateById(@Param(\"list\") List<$EntityClassName> list);"; + System.err.println(mapperBatchUpdate.replace("$EntityClassName", entityClassName)); + String mapperBatchDelete = "void batchDeleteByIds(@Param(\"list\") List<$EntityPkTypeName> list);"; + System.err.println(mapperBatchDelete.replace("$EntityPkTypeName", entityPkTypeName)); + System.err.println("\n============== 渲染MapperXml =================="); + List fieldNameList = new ArrayList<>(); + List fieldNameUnderlineList = new ArrayList<>(); + List fieldNameItemList = new ArrayList<>(); + + for (Field field : fields) { + fieldNameList.add(field.getName()); + } + for (String fieldName : fieldNameList) { + fieldNameUnderlineList.add(StrUtil.toUnderlineCase(fieldName)); + fieldNameItemList.add("#{item." + fieldName + "}"); + } + + String batchInsertXml = "\n" + + "INSERT INTO " + tableName + " (" + + String.join(",", fieldNameUnderlineList) + + ") VALUES\n" + + "\n" + + "(\n" + + String.join(",\n", fieldNameItemList) + + ")\n" + + "\n" + + "\n"; + System.err.println(batchInsertXml); + + StringBuilder ifStringBuilder = new StringBuilder(); + for (int i = 0; i < fieldNameList.size(); i++) { + ifStringBuilder.append("") + .append(fieldNameUnderlineList.get(i)) + .append(" = #{item.") + .append(fieldNameList.get(i)) + .append("},\n"); + } + String batchUpdateXml = "\n" + + "\n" + + "UPDATE " + tableName + "\n" + + "\n" + + ifStringBuilder + + "\n" + + "WHERE " + StrUtil.toUnderlineCase(primaryKeyName) + " = #{item." + primaryKeyName + "}\n" + + "\n" + + "\n"; + System.err.println(batchUpdateXml); + + String batchDeleteXml = "\n" + + "delete from " + tableName + " where " + StrUtil.toUnderlineCase(primaryKeyName) + " in\n" + + "\n" + + "#{id}\n" + + "\n" + + ""; + System.err.println(batchDeleteXml); + } + + public static void main(String[] args) { + new MybatisMapperBatchOpRender().render(SystemDeptTb.class, "id"); + } }