手写Java代码生成工具(六)生成controller文件

192 阅读6分钟

前言​

写博客是为了记录和分享自己的学习,所分享内容是网上的资源,由于非原创项目,主要分享学习思路,只展示贴图部分代码(本人不分享本项目源码,支持项目付费

一、写入控制器类所需的包导入声明和注解

//创建Controller包
        File folder = new File(Constants.PATH_CONTROLLER);
        if(!folder.exists()){
            folder.mkdirs();
        }
        String serviceName=tableInfo.getBeanName()+Constants.SUFFIX_BEAN_SERVICE;
        String serviceBeanName=StringUtils.lowerCaseFirstLetter(serviceName);

        String className=tableInfo.getBeanName()+Constants.SUFFIX_BEAN_CONTROLLER;
        //创建ServiceImpl文件
        File file = new File(folder,className+".java");
        OutputStream out=null;
        OutputStreamWriter writer=null;
        BufferedWriter bw=null;
        
        out=new FileOutputStream(file);
        writer=new OutputStreamWriter(out,"UTF-8");
        bw=new BufferedWriter(writer);


        //生成包名
        bw.write("package "+Constants.PACKAGE_CONTROLLER+";");
        bw.newLine();
        bw.newLine();

        bw.write("import javax.annotation.Resource;");
        bw.newLine();

        bw.write("import "+Constants.PACKAGE_PO+"."+tableInfo.getBeanName()+Constants.SUFFIX_BEAN_PO+";");
        bw.newLine();
        bw.write("import "+Constants.PACKAGE_QUREY+"."+tableInfo.getBeanName()+Constants.SUFFIX_BEAN_QUREY+";");
        bw.newLine();
        bw.write("import "+Constants.PACKAGE_SERVICE+"."+serviceName+";");
        bw.newLine();
        bw.write("import java.util.List;");
        bw.newLine();
        bw.write("import org.springframework.web.bind.annotation.RequestMapping;");
        bw.newLine();
        bw.write("import org.springframework.web.bind.annotation.RestController;");
        bw.newLine();
        bw.write("import org.springframework.web.bind.annotation.RequestBody;");
        bw.newLine();

        bw.write("import "+Constants.PACKAGE_VO+".ResultVO;");
        bw.newLine();

创建一个 Java 控制器(Controller)类的文件。它首先检查指定的目录是否存在,如果不存在则创建该目录。然后,通过拼接表信息和特定后缀生成类名,并创建文件。接着,向文件中写入控制器类所需的包导入声明和注解等内容,为后续生成完整的控制器类做准备。

  1. 创建目录
  • File folder = new File(Constants.PATH_CONTROLLER);:使用常量Constants.PATH_CONTROLLER指定的路径创建一个File对象,表示要创建的控制器包所在的目录。
  • if(!folder.exists()){ folder.mkdirs(); }:如果该目录不存在,则创建目录。
  1. 生成类名和文件
  • String serviceName=tableInfo.getBeanName()+Constants.SUFFIX_BEAN_SERVICE;:根据表信息的beanName和常量后缀生成服务类的名称。
  • String serviceBeanName=StringUtils.lowerCaseFirstLetter(serviceName);:将服务类名称的首字母小写,可能是为了遵循某种命名规范。
  • String className=tableInfo.getBeanName()+Constants.SUFFIX_BEAN_CONTROLLER;:生成控制器类的名称。
  • File file = new File(folder,className+".java");:在指定目录下创建一个以控制器类名命名的 Java 文件。
  1. 文件写入准备
  • OutputStream out=null;、OutputStreamWriter writer=null;、BufferedWriter bw=null;:声明输出流、输出流写入器和缓冲写入器变量,用于向文件写入内容。
  • out=new FileOutputStream(file);:创建文件输出流,关联到要创建的 Java 文件。 writer=new OutputStreamWriter(out,"UTF-8");:使用 UTF-8 编码创建输出流写入器。
  • bw=new BufferedWriter(writer);:创建缓冲写入器,提高写入效率。
  1. 写入内容
  • bw.write("package "+Constants.PACKAGE_CONTROLLER+";");:写入控制器类所在的包名。 后续的bw.write方法依次写入各种导入声明,包括 Java 标准库中的类和项目中自定义的包中的类,如服务类、实体类、查询类、结果返回类等。
  • bw.newLine();:写入换行符,使代码在文件中更加清晰易读。

二、生成控制器类的具体方法

   //生成类名
            bw.newLine();
            BuildComment.createClassComment(bw, tableInfo.getComment());
            bw.write("@RestController");
            bw.newLine();
            bw.write("@RequestMapping(\"/"+StringUtils.lowerCaseFirstLetter(tableInfo.getBeanName())+"\")");
            bw.newLine();
            bw.write("public class "+className+" extends BaseController{");
            bw.newLine();
            bw.newLine();


            bw.write("\t@Resource");
            bw.newLine();
            bw.write("\tprivate "+serviceName+" "+serviceBeanName+";");
            bw.newLine();
            bw.newLine();


            bw.write("\t@RequestMapping(\"loadDataList\")");
            bw.newLine();
            bw.write("\tpublic ResultVO loadDataList("+tableInfo.getBeanParamName()+" query) {");
            bw.newLine();
            bw.write("\t\treturn getSuccessResponse("+serviceBeanName+".findListByParam(query));");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();



            BuildComment.createFieldComment(bw,"新增");
            bw.write("\t@RequestMapping(\"add\")");
            bw.newLine();
            bw.write("\tpublic ResultVO add("+tableInfo.getBeanName()+Constants.SUFFIX_BEAN_PO+" bean) {");
            bw.newLine();
            bw.write("\t\t"+serviceBeanName+".add(bean);");
            bw.newLine();
            bw.write("\t\treturn getSuccessResponse("+"null);");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();


            BuildComment.createFieldComment(bw,"批量新增");
            bw.write("\t@RequestMapping(\"addBatch\")");
            bw.newLine();
            bw.write("\tpublic ResultVO addBatch(@RequestBody List<"+tableInfo.getBeanName()+Constants.SUFFIX_BEAN_PO+"> listBean) {");
            bw.newLine();
            bw.write("\t\t"+serviceBeanName+".addBatch(listBean);");
            bw.newLine();
            bw.write("\t\treturn getSuccessResponse("+"null);");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();

            BuildComment.createFieldComment(bw,"批量新增或修改");
            bw.write("\t@RequestMapping(\"addUpdateBatch\")");
            bw.newLine();
            bw.write("\tpublic ResultVO addOrUpdateBatch(@RequestBody List<"+tableInfo.getBeanName()+Constants.SUFFIX_BEAN_PO+"> listBean) {");
            bw.newLine();
            bw.write("\t\t"+serviceBeanName+".addOrUpdateBatch(listBean);");
            bw.newLine();
            bw.write("\t\treturn getSuccessResponse("+"null);");
            bw.newLine();
            bw.write("\t}");
            bw.newLine();
            bw.newLine();

在已创建的 Java 文件中继续写入内容,主要是生成控制器类的具体方法实现。包括生成类名、添加注解、定义成员变量、实现不同功能的 HTTP 请求处理方法,如加载数据列表、新增数据、批量新增数据、批量新增或修改数据等。

  1. 生成类名和注解
  • BuildComment.createClassComment(bw, tableInfo.getComment());:调用方法为类生成注释,注释内容可能来自表信息中的描述。
  • bw.write("@RestController");:为类添加@RestController注解,表示这是一个 RESTful Web 服务的控制器类。
  • bw.write("@RequestMapping("/"+StringUtils.lowerCaseFirstLetter(tableInfo.getBeanName())+"")");:添加@RequestMapping注解,指定控制器的基本请求路径,路径根据表信息的beanName生成,首字母小写。
  • bw.write("public class "+className+" extends BaseController{");:定义控制器类,继承自BaseController。
  1. 定义成员变量
  • bw.write("\t@Resource");:添加@Resource注解,用于依赖注入。
  • bw.write("\tprivate "+serviceName+" "+serviceBeanName+";");:定义一个服务类的成员变量,用于调用服务层的方法。
  1. 实现请求处理方法
  • loadDataList方法:
  • bw.write("\t@RequestMapping("loadDataList")");:为方法添加@RequestMapping注解,指定请求路径为loadDataList。
  • bw.write("\tpublic ResultVO loadDataList("+tableInfo.getBeanParamName()+" query) {");:定义方法,接收一个查询参数对象,返回类型为ResultVO。
  • bw.write("\t\treturn getSuccessResponse("+serviceBeanName+".findListByParam(query));");:调用服务层的方法获取数据列表,并将结果封装在成功响应对象中返回。
  • add方法:用于新增单个数据。
  • addBatch方法:用于批量新增数据。
  • addOrUpdateBatch方法:用于批量新增或修改数据。

三、根据字段生成特定的查询、更新和删除

   for(Map.Entry<String, List<FieldInfo>> entry:tableInfo.getKeyIndexMap().entrySet()){
                List<FieldInfo> fieldInfoList = entry.getValue();

                Integer index=0;
                StringBuilder methodName = new StringBuilder();
                StringBuilder methodParamName = new StringBuilder();
                StringBuilder paramsBuilder = new StringBuilder();
                for(FieldInfo fieldInfo:fieldInfoList){
                    index++;
                    methodName.append(StringUtils.uperCaseFirstLetter(fieldInfo.getPropertyName()));
                    if(index<fieldInfoList.size()){
                        methodName.append("And");
                    }

                    methodParamName.append(fieldInfo.getJavaType()+" "+fieldInfo.getPropertyName());

                    paramsBuilder.append(fieldInfo.getPropertyName());
                    if(index<fieldInfoList.size()){
                        methodParamName.append(",");
                        paramsBuilder.append(",");
                    }
                }
                //TODO 类目一致
                BuildComment.createFieldComment(bw,"根据"+methodName+"查询");
                bw.write("\t@RequestMapping(\"selectBy"+methodName+"\")");
                bw.newLine();
                bw.write("\tpublic ResultVO"+" selectBy"+ methodName+"("+methodParamName+") {");
                bw.newLine();
                bw.write("\t\treturn getSuccessResponse("+serviceBeanName+".selectBy"+methodName+"("+paramsBuilder+"));");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();

                BuildComment.createFieldComment(bw,"根据"+methodName+"更新");
                bw.write("\t@RequestMapping(\"updateBy"+methodName+"\")");
                bw.newLine();
                bw.write("\tpublic  ResultVO updateBy"+ methodName+"("+tableInfo.getBeanName()+Constants.SUFFIX_BEAN_PO+" bean,"+methodParamName+") {");
                bw.newLine();
                bw.write("\t\tthis."+serviceBeanName+".updateBy"+methodName+"(bean,"+paramsBuilder+");");
                bw.newLine();
                bw.write("\t\treturn getSuccessResponse("+"null);");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();

                BuildComment.createFieldComment(bw,"根据"+methodName+"删除");
                bw.write("\t@RequestMapping(\"deleteBy"+methodName+"\")");
                bw.newLine();
                bw.write("\tpublic  ResultVO deleteBy"+ methodName+"("+methodParamName+") {");
                bw.newLine();
                bw.write("\t\tthis."+serviceBeanName+".deleteBy"+methodName+"("+paramsBuilder+");");
                bw.newLine();
                bw.write("\t\treturn getSuccessResponse("+"null);");
                bw.newLine();
                bw.write("\t}");
                bw.newLine();
                bw.newLine();
            }

遍历表的键索引映射(tableInfo.getKeyIndexMap()),为每个键组合生成特定的查询、更新和删除方法。这些方法用于根据特定的字段组合进行数据操作,并在控制器类中实现了相应的 HTTP 请求处

  1. 遍历键索引映射
  • for(Map.Entry<String, List> entry:tableInfo.getKeyIndexMap().entrySet()){...}:遍历表的键索引映射,其中每个条目包含一个键(可能是字段组合的描述)和对应的FieldInfo列表。
  1. 生成方法相关信息
  • 对于每个字段组合,通过遍历FieldInfo列表生成方法名、方法参数名和参数列表字符串。
  • methodName:通过将每个字段的属性名首字母大写并使用And连接生成方法名。
  • methodParamName:生成方法参数列表,包括参数类型和参数名。
  • paramsBuilder:生成实际传递给服务层方法的参数列表字符串。
  1. 生成查询方法
  • BuildComment.createFieldComment(bw,"根据"+methodName+"查询");:为方法生成注释。
  • bw.write("\t@RequestMapping("selectBy"+methodName+"")");:添加@RequestMapping注解,指定查询方法的请求路径。
  • bw.write("\tpublic ResultVO"+" selectBy"+ methodName+"("+methodParamName+") {...}:定义查询方法,接收特定的参数,返回类型为ResultVO。
  • bw.write("\t\treturn getSuccessResponse("+serviceBeanName+".selectBy"+methodName+"("+paramsBuilder+"));");:调用服务层的方法进行查询,并将结果封装在成功响应对象中返回。
  1. 生成更新方法
  • 类似地,为更新方法生成注释、请求路径、方法定义和实现逻辑。
  • bw.write("\tpublic ResultVO updateBy"+ methodName+"("+tableInfo.getBeanName()+Constants.SUFFIX_BEAN_PO+" bean,"+methodParamName+") {...}:更新方法接收实体对象和特定的参数,调用服务层方法进行更新操作。
  1. 生成删除方法
  • 同样的方式生成删除方法的注释、请求路径、方法定义和实现逻辑。
  • bw.write("\tpublic ResultVO deleteBy"+ methodName+"("+methodParamName+") {...}:删除方法接收特定的参数,调用服务层方法进行删除操作。

如果我的内容对你有帮助,请点赞,评论,收藏。创作不易,大家的支持就是我坚持下去的动力! 在这里插入图片描述