这个代码生成器不是用模板,所以如果需要配合公司的工具类等等,则需要修改代码。
该生成器会生成controller、service、service-impl、dao、mapper、xml文件、vo、实体
package com.example.jpacodegenerator;
/**
* @author JunHao Huang
* @since 2023/6/7 13:41
*/
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class JpaCodeGenerator {
private static final String BASE_PACKAGE = "cn.com.infox.attendance";
private static final String ENTITY_PACKAGE = BASE_PACKAGE + ".entity";
private static final String REPOSITORY_PACKAGE = BASE_PACKAGE + ".repository";
private static final String SERVICE_PACKAGE = BASE_PACKAGE + ".service";
private static final String SERVICE_IMPL_PACKAGE = SERVICE_PACKAGE + ".impl";
private static final String CONTROLLER_PACKAGE = BASE_PACKAGE + ".controller";
private static final String VO_PACKAGE = BASE_PACKAGE + ".vo";
private static final String MAPPER_PACKAGE = BASE_PACKAGE + ".mapper";
private static final List RESERVED_KEYWORDS = Arrays.asList("abstract", "assert", "boolean", "break", "byte", "case", "catch", "char", "class", "const", "continue", "default", "do", "double", "else", "enum", "extends", "false", "final", "finally", "float", "for", "goto", "if", "implements", "import", "instanceof", "int", "interface", "long", "native", "new", "null", "package", "private", "protected", "public", "return", "short", "static", "strictfp", "super", "switch", "synchronized", "this", "throw", "throws", "transient", "true", "try", "void", "volatile", "while");
public static void main(String[] args) throws IOException {
String tableName = "我的测试表";
String author = "huangjunhao";
// 实体类名和字段名可以根据需求自行修改
generateEntity("myTest", tableName + "实体类", author, "id", "name");
generateVO("myTest", tableName + "实体类VO", author, "id", "name");
generateMapper("myTest", tableName + "数据库访问层", author);
Map cls = new HashMap<>();
cls.put("id", "id");
cls.put("name", "name");
cls.put("is_deleted", "isDeleted");
cls.put("create_user", "createUser");
cls.put("create_time", "createTime");
cls.put("update_user", "updateUser");
cls.put("update_time", "updateTime");
cls.put("status", "status");
generateXML("myTest", cls, "my_test");
generateService("myTest", tableName + "服务接口", author);
generateServiceImpl("myTest", tableName + "服务实现类", author);
generateController("myTest", tableName + "控制器", author, tableName, tableName + "接口");
}
private static void generateXML(String entityName, Map cls, String tableName) throws IOException {
StringBuilder sb = new StringBuilder();
sb.append("\n");
sb.append("\n");
sb.append("\n");
sb.append("\t\n");
sb.append("\t\n");
cls.forEach((key, value) -> {
sb.append("\t\t\n");
});
sb.append("\t \n\n");
sb.append("\t\n\n");
sb.append(" ");
writeFile("src/main/resources/mapper/", capitalize(entityName)+"Mapper", sb.toString(), ".xml", capitalize(entityName));
}
/**
* 生成实体类
*/
private static void generateEntity(String entityName, String todo, String author, String... fieldNames) throws IOException {
String className = capitalize(entityName);
StringBuilder sb = new StringBuilder();
sb.append("package ").append(ENTITY_PACKAGE).append(";\n\n");
sb.append("import cn.com.infox.core.mp.base.BaseEntity;\n");
sb.append("import com.baomidou.mybatisplus.annotation.TableName;\n");
sb.append("import lombok.Data;\n");
sb.append("import lombok.EqualsAndHashCode;\n");
sb.append("import com.baomidou.mybatisplus.annotation.TableName;\n");
sb.append("import io.swagger.annotations.ApiModelProperty;\n\n");
sb.append("/**\n");
classAddAuthor(todo, author, sb);
sb.append("@Data\n");
sb.append("@EqualsAndHashCode(callSuper = true)\n");
sb.append("@TableName(\"").append(toSnakeCase(entityName)).append("\")\n");
sb.append("public class ").append(className).append(" extends BaseEntity {\n\n");
// 生成字段
for (String fieldName : fieldNames) {
if (RESERVED_KEYWORDS.contains(fieldName)) {
fieldName = "_" + fieldName;
}
sb.append("\t@ApiModelProperty()\n");
sb.append("\tprivate String ").append(fieldName).append(";\n\n");
}
sb.append("}");
writeFile("src/main/java/" + ENTITY_PACKAGE.replaceAll("\\.", "/"), capitalize(entityName), sb.toString(), ".java", capitalize(entityName));
writeFile("src/main/java/" + VO_PACKAGE.replaceAll("\\.", "/"), capitalize(entityName) + "VO", sb.toString(), ".java", capitalize(entityName));
}
/**
* 生成实体类VO
*/
private static void generateVO(String entityName, String todo, String author, String... fieldNames) throws IOException {
String className = capitalize(entityName);
StringBuilder sb = new StringBuilder();
sb.append("package ").append(ENTITY_PACKAGE).append("vo;\n\n");
sb.append("import ").append(ENTITY_PACKAGE).append(".").append(className).append(";\n");
sb.append("import com.baomidou.mybatisplus.annotation.TableField;\n");
sb.append("import lombok.Data;\n");
sb.append("import lombok.EqualsAndHashCode;\n\n");
sb.append("/**\n");
classAddAuthor(todo, author, sb);
sb.append("@Data\n");
sb.append("@EqualsAndHashCode(callSuper = true)\n");
sb.append("public class ").append(className).append("VO extends ").append(className).append("{\n\n");
// 生成字段
sb.append("\tprivate static final long serialVersionUID = 323961866895098324L;").append(";\n\n");
sb.append("}");
writeFile("src/main/java/" + VO_PACKAGE.replaceAll("\\.", "/"), capitalize(entityName) + "VO", sb.toString(), ".java", capitalize(entityName));
}
private static void classAddAuthor(String todo, String author, StringBuilder sb) {
sb.append("* " + todo + "\n");
sb.append("* \n");
sb.append("* @author " + author + "\n");
sb.append("*/\n");
}
/**
* 生成 Repository
*/
private static void generateRepository(String entityName) throws IOException {
String className = capitalize(entityName) + "Repository";
StringBuilder sb = new StringBuilder();
sb.append("package ").append(REPOSITORY_PACKAGE).append(";\n\n");
sb.append("import org.springframework.data.jpa.repository.JpaRepository;\n");
sb.append("import ").append(ENTITY_PACKAGE).append(".").append(capitalize(entityName)).append(";\n\n");
sb.append("public interface ").append(className).append(" extends JpaRepository<")
.append(capitalize(entityName)).append(", Long> {\n\n").append("}");
writeFile("src/main/java/", REPOSITORY_PACKAGE, sb.toString(), ".java", capitalize(entityName));
}
private static void generateMapper(String entityName, String todo, String author) throws IOException {
String className = capitalize(entityName) + "Mapper";
StringBuilder sb = new StringBuilder();
sb.append("package ").append(MAPPER_PACKAGE).append(";\n\n");
sb.append("import java.util.List;\n\n");
sb.append("import ").append(VO_PACKAGE).append(".").append(capitalize(entityName)).append("VO;\n");
sb.append("import com.baomidou.mybatisplus.core.mapper.BaseMapper;\n");
sb.append("import com.baomidou.mybatisplus.core.metadata.IPage;\n");
sb.append("import ").append(ENTITY_PACKAGE).append(".").append(capitalize(entityName) + ";\n\n");
sbAddAuthor(todo, author, sb);
sb.append("public interface ").append(className).append(" extends BaseMapper<")
.append(capitalize(entityName)).append("> {\n\n");
sb.append("\t/**\n");
sb.append("\t* 自定义分页\n");
sb.append("\t* \n");
sb.append("\t* @param page 分页数据\n");
sb.append("\t* @param ").append(toCamelCase(entityName)).append(" 查询条件\n");
sb.append("\t* @return List<").append(capitalize(entityName)).append("VO>\n");
sb.append("\t*/\n");
sb.append("\tList<").append(capitalize(entityName)).append("VO> select").append(capitalize(entityName)).append("Page")
.append("(IPage page, ").append(capitalize(capitalize(entityName))).append("VO ").append(toCamelCase(entityName))
.append(");\n");
sb.append("}");
writeFile("src/main/java/" + MAPPER_PACKAGE.replaceAll("\\.", "/"), capitalize(entityName) + "Mapper", sb.toString(), ".java", capitalize(entityName));
}
/**
* 生成 Service 接口
*/
private static void generateService(String entityName, String todo, String author) throws IOException {
String className = capitalize(entityName) + "Service";
StringBuilder sb = new StringBuilder();
sb.append("package ").append(SERVICE_PACKAGE).append(";\n\n");
sb.append("import ").append(VO_PACKAGE).append(".").append(capitalize(entityName)).append("VO;\n");
sb.append("import cn.com.infox.core.mp.base.BaseService;\n");
sb.append("import ").append(ENTITY_PACKAGE).append(".").append(capitalize(entityName)).append(";\n");
sb.append("import com.baomidou.mybatisplus.core.metadata.IPage;\n\n");
sbAddAuthor(todo, author, sb);
sb.append("public interface ").append(className).append(" extends BaseService<")
.append(capitalize(entityName)).append("> {\n\n");
sb.append("\t/**\n");
sb.append("\t* 自定义分页\n");
sb.append("\t* \n");
sb.append("\t* @param page 分页参数\n");
sb.append("\t* @param ").append(toCamelCase(entityName)).append(" 查询条件\n");
sb.append("\t* @return ").append("分页数据IPage<").append(capitalize(entityName)).append(">\n");
sb.append("\t*/\n");
sb.append("\tIPage<").append(capitalize(entityName)).append("VO> select" + capitalize(entityName) + "Page")
.append("(IPage<").append(capitalize(entityName)).append("VO> page, ").append(capitalize(entityName))
.append("VO ").append(toCamelCase(entityName)).append(");\n");
sb.append("}");
writeFile("src/main/java/" + SERVICE_PACKAGE.replaceAll("\\.", "/"), capitalize(entityName) + "Service", sb.toString(), ".java", capitalize(entityName));
}
private static void sbAddAuthor(String todo, String author, StringBuilder sb) {
sb.append("/**\n");
sb.append("* " + todo + "\n");
sb.append("*\n");
sb.append("* @author " + author + "\n");
sb.append("*/\n");
}
/**
* 生成 Service 实现类
*/
private static void generateServiceImpl(String entityName, String todo, String author) throws IOException {
String className = capitalize(entityName) + "ServiceImpl";
StringBuilder sb = new StringBuilder();
sb.append("package ").append(SERVICE_PACKAGE).append(".impl;\n\n");
sb.append("import ").append(ENTITY_PACKAGE).append(".").append(capitalize(entityName)).append(";\n");
sb.append("import ").append(MAPPER_PACKAGE).append(".").append(capitalize(entityName)).append("Mapper;\n");
sb.append("import ").append(SERVICE_PACKAGE).append(".").append(capitalize(entityName)).append("Service;\n");
sb.append("import ").append(VO_PACKAGE).append(".").append(capitalize(entityName)).append("VO;\n");
sb.append("import cn.com.infox.core.mp.base.BaseServiceImpl;\n");
sb.append("import com.baomidou.mybatisplus.core.metadata.IPage;\n");
sb.append("import org.springframework.stereotype.Service;\n\n");
sbAddAuthor(todo, author, sb);
sb.append("@Service\n");
sb.append("public class ").append(className).append(" extends BaseServiceImpl<")
.append(capitalize(entityName)).append("Mapper, ").append(capitalize(entityName))
.append(">").append(" implements ").append(capitalize(entityName))
.append("Service {\n\n");
sb.append("\t@Override\n");
sb.append("\tpublic IPage<").append(capitalize(entityName)).append("VO> select")
.append(capitalize(entityName)).append("Page(IPage<").append(capitalize(entityName))
.append("VO> page, ").append(capitalize(entityName)).append("VO ").append(toCamelCase(entityName))
.append(") {\n");
sb.append("\t\treturn page.setRecords(baseMapper.select").append(capitalize(entityName)).append("Page(page, ")
.append(toCamelCase(entityName)).append("));\n");
sb.append("\t}\n");
sb.append("}");
writeFile("src/main/java/" + SERVICE_IMPL_PACKAGE.replaceAll("\\.", "/"), capitalize(entityName) + "ServiceImpl", sb.toString(), ".java", capitalize(entityName));
}
/**
* 生成 Controller
*/
private static void generateController(String entityName, String todo, String author, String apiValue, String apiTags) throws IOException {
String className = capitalize(entityName) + "Controller";
StringBuilder sb = new StringBuilder();
sb.append("package ").append(CONTROLLER_PACKAGE).append(";\n\n");
sb.append("import ").append(ENTITY_PACKAGE).append(".").append(capitalize(entityName)).append(";\n");
sb.append("import ").append(SERVICE_PACKAGE).append(".").append(capitalize(entityName)).append("Service;\n");
sb.append("import ").append(VO_PACKAGE).append(".").append(capitalize(entityName)).append("VO;\n");
sb.append("import cn.com.infox.core.boot.ctrl.BasicController;\n");
sb.append("import cn.com.infox.core.mp.support.Condition;\n");
sb.append("import cn.com.infox.core.mp.support.Query;\n");
sb.append("import cn.com.infox.core.tool.api.R;\n");
sb.append("import cn.com.infox.core.tool.utils.BeanUtil;\n");
sb.append("import cn.com.infox.core.tool.utils.Func;\n");
sb.append("import com.baomidou.mybatisplus.core.metadata.IPage;\n");
sb.append("import com.baomidou.mybatisplus.extension.plugins.pagination.Page;\n");
sb.append("import com.github.xiaoymin.knife4j.annotations.ApiOperationSupport;\n");
sb.append("import io.swagger.annotations.Api;\n");
sb.append("import io.swagger.annotations.ApiOperation;\n");
sb.append("import io.swagger.annotations.ApiParam;\n");
sb.append("import lombok.AllArgsConstructor;\n");
sb.append("import org.springframework.web.bind.annotation.*;\n\n");
sb.append("import javax.validation.Valid;\n");
sb.append("import java.util.stream.Collectors;\n\n");
sbAddAuthor(todo, author, sb);
sb.append("@RestController\n");
sb.append("@AllArgsConstructor\n");
sb.append("@RequestMapping(\"/").append(toCamelCase(entityName)).append("\")\n");
sb.append("@Api(value = \"/").append(apiValue).append("\", tags = \"").append(apiTags).append("\")\n");
sb.append("public class ").append(className).append(" extends BasicController {\n\n");
sb.append("\tprivate ").append(capitalize(entityName)).append("Service ")
.append(toCamelCase(entityName)).append("Service;\n\n");
//详情
controllerDetail(entityName, sb);
//分页
controllerList(entityName, apiValue, sb);
//自定义分页
controllerPage(entityName, apiValue, sb);
//新增
controllerSave(entityName, sb);
//修改
controllerUpdate(entityName, sb);
//新增或修改
controllerSubmit(entityName, sb);
controllerDelete(entityName, sb);
sb.append("}");
writeFile("src/main/java/" + CONTROLLER_PACKAGE.replaceAll("\\.", "/"), capitalize(entityName) + "Controller", sb.toString(), ".java", capitalize(entityName));
}
private static void controllerDelete(String entityName, StringBuilder sb) {
sb.append("\t/**\n");
sb.append("\t* 逻辑删除\n");
sb.append("\t*/\n");
sb.append("\t@PostMapping(\"/remove\")\n");
sb.append("\t@ApiOperationSupport(order = 7)\n");
sb.append("\t@ApiOperation(value = \"逻辑删除\", notes = \"传入ids\")\n");
sb.append("\tpublic R remove(@ApiParam(value = \"主键集合\", required = true) @RequestBody String ids) {\n");
sb.append("\t\treturn R.status(").append(toCamelCase(entityName)).append("Service.deleteLogic(Func.toStrList(ids)));\n");
sb.append("\t}\n\n");
}
private static void controllerSubmit(String entityName, StringBuilder sb) {
sb.append("\t/**\n");
sb.append("\t* 新增或修改\n");
sb.append("\t*/\n");
sb.append("\t@PostMapping(\"/submit\")\n");
sb.append("\t@ApiOperationSupport(order = 6)\n");
sb.append("\t@ApiOperation(value = \"新增或修改\", notes = \"传入" + entityName + "\")\n");
sb.append("\tpublic R submit(@Valid @RequestBody ")
.append(capitalize(entityName)).append(" ").append(toCamelCase(entityName)).append(") {\n");
sb.append("\t\treturn R.status(").append(toCamelCase(entityName)).append("Service.saveOrUpdate(")
.append(toCamelCase(entityName)).append("));\n");
sb.append("\t}\n\n");
}
private static void controllerUpdate(String entityName, StringBuilder sb) {
sb.append("\t/**\n");
sb.append("\t* 修改\n");
sb.append("\t*/\n");
sb.append("\t@PostMapping(\"/update\")\n");
sb.append("\t@ApiOperationSupport(order = 5)\n");
sb.append("\t@ApiOperation(value = \"修改\", notes = \"传入" + entityName + "\")\n");
sb.append("\tpublic R update(@Valid @RequestBody ")
.append(capitalize(entityName)).append(" ").append(toCamelCase(entityName)).append(") {\n");
sb.append("\t\treturn R.status(").append(toCamelCase(entityName)).append("Service.updateById(")
.append(toCamelCase(entityName)).append("));\n");
sb.append("\t}\n\n");
}
private static void controllerSave(String entityName, StringBuilder sb) {
sb.append("\t/**\n");
sb.append("\t* 新增\n");
sb.append("\t*/\n");
sb.append("\t@PostMapping(\"/save\")\n");
sb.append("\t@ApiOperationSupport(order = 4)\n");
sb.append("\t@ApiOperation(value = \"新增\", notes = \"传入" + entityName + "\")\n");
sb.append("\tpublic R save(@Valid @RequestBody ")
.append(capitalize(entityName)).append(" ").append(toCamelCase(entityName)).append(") {\n");
sb.append("\t\treturn R.status(").append(toCamelCase(entityName)).append("Service.save(")
.append(toCamelCase(entityName)).append("));\n");
sb.append("\t}\n\n");
}
private static void controllerPage(String entityName, String apiValue, StringBuilder sb) {
sb.append("\t/**\n");
sb.append("\t* 自定义分页 " + apiValue + "\n");
sb.append("\t*/\n");
sb.append("\t@GetMapping(\"/page\")\n");
sb.append("\t@ApiOperationSupport(order = 3)\n");
sb.append("\t@ApiOperation(value = \"分页\", notes = \"传入" + entityName + "\")\n");
sb.append("\tpublic R> page(")
.append(capitalize(entityName)).append("VO ").append(toCamelCase(entityName)).append(", Query query").append("){\n");
sb.append("\t\tIPage<").append(capitalize(entityName)).append("VO> ").append("pages = ").
append(toCamelCase(entityName)).append("Service.select").append(capitalize(entityName))
.append("Page(Condition.getPage(query), ").append(toCamelCase(entityName)).append(");\n");
sb.append("\t\treturn R.data(pages);\n");
sb.append("\t}\n\n");
}
private static void controllerList(String entityName, String apiValue, StringBuilder sb) {
sb.append("\t/**\n");
sb.append("\t* 分页 " + apiValue + "\n");
sb.append("\t*/\n");
sb.append("\t@GetMapping(\"/list\")\n");
sb.append("\t@ApiOperationSupport(order = 2)\n");
sb.append("\t@ApiOperation(value = \"分页\", notes = \"传入" + entityName + "\")\n");
sb.append("\tpublic R> list(")
.append(capitalize(entityName)).append(" ").append(toCamelCase(entityName)).append(", Query query").append("){\n");
sb.append("\t\tIPage<").append(capitalize(entityName)).append("> ").append("pages = ")
.append(toCamelCase(entityName)).append("Service.page(Condition.getPage(query), Condition.getQueryWrapper(")
.append(toCamelCase(entityName)).append("));\n");
sb.append("\t\tIPage<").append(capitalize(entityName)).append("VO> page = new Page<>();\n");
sb.append("\t\tBeanUtil.copy(pages, page);\n");
sb.append("\t\tpage.setRecords(pages.getRecords().stream().map(p -> BeanUtil.copy(p, ")
.append(capitalize(entityName)).append("VO.class)).collect(Collectors.toList()));\n");
sb.append("\t\treturn R.data(page);\n");
sb.append("\t}\n\n");
}
private static void controllerDetail(String entityName, StringBuilder sb) {
sb.append("\t/**\n");
sb.append("\t* 详情\n");
sb.append("\t*/\n");
sb.append("\t@GetMapping(\"/detail\")\n");
sb.append("\t@ApiOperationSupport(order = 1)\n");
sb.append("\t@ApiOperation(value = \"详情\", notes = \"传入" + entityName + "\")\n");
sb.append("\tpublic R<").append(capitalize(entityName)).append("VO> detail(")
.append(capitalize(entityName)).append(" ").append(toCamelCase(entityName)).append("){\n");
sb.append("\t\t").append(capitalize(entityName)).append(" detail").append(" = ")
.append(toCamelCase(entityName)).append("Service.getOne(Condition.getQueryWrapper(").append(toCamelCase(entityName))
.append("));\n");
sb.append("\t\treturn R.data(detail == null ? null : BeanUtil.copy(detail, ").append(capitalize(entityName)).append("VO.class));\n");
sb.append("\t}\n\n");
}
private static String capitalize(String str) {
return str.substring(0, 1).toUpperCase() + str.substring(1);
}
private static String toSnakeCase(String str) {
return str.replaceAll("([a-z])([A-Z]+)", "$1_$2").toLowerCase();
}
private static String toCamelCase(String str) {
return str.substring(0, 1).toLowerCase() + str.substring(1);
}
private static void writeFile(String fileUrl, String className, String content, String fileType, String fileName) throws IOException {
File dir = new File(fileUrl);
if (!dir.exists()) {
dir.mkdirs();
}
FileWriter writer = new FileWriter(new File(dir, capitalize(className.substring(className.lastIndexOf(".") + 1)) + fileType));
writer.write(content);
writer.flush();
writer.close();
}
}