Commit 91333ecd authored by shangtx's avatar shangtx

chore: 代码生成器搬运

parent 82d7e46b
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
<module>common</module> <module>common</module>
<module>admin</module> <module>admin</module>
<module>mini-app</module> <module>mini-app</module>
<module>test</module>
</modules> </modules>
<dependencies> <dependencies>
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>parent</artifactId>
<groupId>com.onsiteservice</groupId>
<version>1.0.0</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>test</artifactId>
<dependencies>
<!--依赖公共通用模块-->
<dependency>
<groupId>com.onsiteservice</groupId>
<artifactId>common</artifactId>
<version>1.0.0</version>
</dependency>
<!--代码生成器依赖-->
<dependency>
<groupId>org.freemarker</groupId>
<artifactId>freemarker</artifactId>
</dependency>
<dependency>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-core</artifactId>
<version>1.3.7</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
</project>
\ No newline at end of file
package com.onsiteservice;
import com.google.common.base.CaseFormat;
import com.onsiteservice.constant.constant.Constants;
import org.apache.commons.lang3.StringUtils;
import java.io.File;
import java.io.IOException;
import java.io.RandomAccessFile;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringJoiner;
/**
* @author 潘维吉
* @date 2019-08-01 10:14
* 自定义api方法统一生成
* 根据模型Model名称生成对应的XML、Mapper、Service、Controller各自的API方法
*/
public class ApiGenerator {
//TODO 根据模型Model名称生成对应的XML、Mapper、Service、Controller各自的API方法 前提各个文件已生成
public static void main(String[] args) {
String modelName = "BaseTable"; // 模型名
String methodName = "test"; // 方法名称
String comments = "测试生成方法"; // 方法注释
String returnType = "List<Map<String, Object>>"; // 方法返回类型
String params = "Integer id,String str"; // 方法参数 支持无参 单参 多参 , 多参分号后暂不要加空格 注意格式
String methodType = "GET"; // 方法类型 支持 GET, POST, PUT, DELETE
System.out.println("===========================自定义API方法代码自动生成结果=================================");
System.out.println();
ApiGenerator.genApi(modelName, methodName, comments, returnType, params, methodType);
System.out.println();
System.out.println("=======================================================================================");
System.out.println();
System.out.println("根据" + modelName + "模型名称生成对应的XML、Mapper、Service、Controller各自的"
+ returnType + " " + methodName + "(" + params + ")" + "方法完成" + SUCCESS_COLOR);
}
//以下几个选项根据项目的实际情况修改
private static final String CURRENT_MODULE_NAME = CodeGenerator.CURRENT_MODULE_NAME;//当前生成模块名称 根据项目修改
private static final String CURRENT_PACKAGE = CodeGenerator.CURRENT_PACKAGE;//当前生成模块包名称 根据项目修改
public static String FILE_MODULE = ""; // 自定义文件模块目录 用于生成到相应的文件夹下 默认使用表前缀
public static final Boolean IS_GEN_FILE_MODULE = true; // 是生成文件模块目录
private static final String CONTROLLER_PACKAGE = CURRENT_PACKAGE + ".controller";//Controller所在包
private static final String SERVICE_PACKAGE = CURRENT_PACKAGE + ".service";//Service所在包
private static final String MAPPER_PACKAGE = CURRENT_PACKAGE + ".mapper";//Mapper所在包
private static final String PROJECT_PATH = System.getProperty("user.dir") + "/" + CURRENT_MODULE_NAME;//当前项目在硬盘上的基础路径
private static final String JAVA_PATH = "/src/main/java"; //java文件路径
private static final String RESOURCES_PATH = "/src/main/resources";//xml sql资源文件路径
private static final String CONTROLLER_PACKAGE_PATH = packageConvertPath(CONTROLLER_PACKAGE);//生成的Controller存放路径
private static final String SERVICE_PACKAGE_PATH = packageConvertPath(SERVICE_PACKAGE);//生成的Service接口存放路径
private static final String MAPPER_PACKAGE_PATH = packageConvertPath(MAPPER_PACKAGE);//生成的Mapper接口存放路径
public static final String SUCCESS_COLOR = Constants.ANSI_GREEN + " ✔ " + Constants.ANSI_RESET;
public static final String FAIL_COLOR = Constants.ANSI_RED + " ✘ " + Constants.ANSI_RESET;
/**
* 统一生成API方法
*/
public static void genApi(String modelName, String methodName, String comments, String returnType, String params, String methodType) {
FILE_MODULE = StringUtils.isNotBlank(FILE_MODULE) ? FILE_MODULE : modelNameConvertTableName(modelName).split("_")[0];
updateMapperAndXML(modelName, methodName, comments, returnType, params, methodType);
updateService(modelName, methodName, comments, returnType, params);
updateController(modelName, methodName, comments, returnType, params, methodType);
}
/**
* mapper接口和 xml两处方法生成
*/
public static void updateMapperAndXML(String modelName, String methodName, String comments, String returnType, String params, String methodType) {
FILE_MODULE = StringUtils.isNotBlank(FILE_MODULE) ? FILE_MODULE : modelNameConvertTableName(modelName).split("_")[0];
String sqlType = "";
String resultType = "";
switch (methodType) {
case "POST":
sqlType = "insert";
break;
case "PUT":
sqlType = "update";
break;
case "DELETE":
sqlType = "delete";
break;
default:
sqlType = "select";
resultType = "resultType=\"map\"";
}
String sqlSnippet = "";
String note = " /**\n" +
" * " + comments + "\n" +
" */\n";
updateFile(PROJECT_PATH + RESOURCES_PATH + "/mapper/" + (IS_GEN_FILE_MODULE ? (FILE_MODULE + "/") : "") + modelName + "BizMapper.xml",
" <!--" + comments + "-->\n" +
" <" + sqlType + " id=\"" + methodName + "\" " + resultType + ">\n" +
sqlSnippet +
" \n" +
" </" + sqlType + ">",
"</mapper>", 11);
System.out.println(modelName + "BizMapper.xml 资源XML SQL文件新增方法" + SUCCESS_COLOR);
updateFile(PROJECT_PATH + JAVA_PATH + MAPPER_PACKAGE_PATH + (IS_GEN_FILE_MODULE ? (FILE_MODULE + "/") : "") + modelName + "BizMapper.java",
note + " " + returnType + " "
+ methodName + "(" + getMapperParams(params) + ");",
"}", 2);
System.out.println(modelName + "BizMapper.java Mapper接口新增方法" + SUCCESS_COLOR);
}
/**
* Service层两处方法生成
*/
public static void updateService(String modelName, String methodName, String comments, String returnType, String params) {
String lowerModelName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelName);
String note = " /**\n" +
" * " + comments + "\n" +
" */\n";
updateFile(PROJECT_PATH + JAVA_PATH + SERVICE_PACKAGE_PATH + (IS_GEN_FILE_MODULE ? (FILE_MODULE + "/") : "") + modelName + "Service.java",
note +
// " @Override \n" +
" public " + returnType + " " + methodName + "(" + params + ") {\n" +
" return " + lowerModelName + "BizMapper." + methodName + "(" + getParamsName(params) + ");\n" +
" }", "}", 3);
System.out.println(modelName + "Service.java 服务类新增方法" + SUCCESS_COLOR);
}
/**
* Controller层方法生成
*/
public static void updateController(String modelName, String methodName, String comments, String returnType, String params, String methodType) {
String lowerModelName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelName);
String requestMapping = "";
switch (methodType) {
case "POST":
requestMapping = "@PostMapping";
break;
case "PUT":
requestMapping = "@PutMapping";
break;
case "DELETE":
requestMapping = "@DeleteMapping";
break;
default:
requestMapping = "@GetMapping";
}
String note = " /**\n" +
" * " + comments + "\n" +
" */\n";
updateFile(PROJECT_PATH + JAVA_PATH + CONTROLLER_PACKAGE_PATH + (IS_GEN_FILE_MODULE ? (FILE_MODULE + "/") : "") + modelName + "Controller.java",
note +
" " + requestMapping + "(\"/" + CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_HYPHEN, methodName) + "\") \n" +
" public Result " + methodName + "(" + params + ") {\n" +
" " + returnType + " result = " + lowerModelName + "Service."
+ methodName + "(" + getParamsName(params) + "); \n" +
" return success(result, \"" + comments + "成功" + "\");\n" +
" }", "}", 3);
System.out.println(modelName + "Controller.java 控制类新增方法" + SUCCESS_COLOR);
}
/**
* 更新文件
*
* @param filePathName 文件路径
* @param content 更新的内容代码
* @param suffix 根据修改的文件尾部后缀符号替换
* @param tailNum 根据修改的文件截取指定的代码插入位置
*/
public static void updateFile(String filePathName, String content, String suffix, int tailNum) {
if (!isExistsFile(filePathName)) {
return;
}
try {
// 打开一个随机访问文件流,按读写方式
RandomAccessFile randomFile = new RandomAccessFile(filePathName, "rw");
// 文件长度,字节数
long fileLength = randomFile.length() - tailNum;
// 将写文件指针移到文件尾
randomFile.seek(fileLength);
// 中文乱码处理 用write(byte b[])方法
randomFile.write(("\n" + content + "\n" + suffix).getBytes());
randomFile.close();
} catch (IOException e) {
e.printStackTrace();
}
}
/**
* 获取多参数名称
*/
private static String getParamsName(String params) {
if (StringUtils.isBlank(params)) {
return "";
}
List<String> paramsList = new ArrayList<>();
Arrays.asList(params.split(",")).forEach(item -> {
paramsList.add(item.split(" ")[1]);
});
return StringUtils.join(paramsList.toArray(), ", ");
}
/**
* 获取Mapper接口多参数
*/
private static String getMapperParams(String params) {
if (StringUtils.isBlank(params)) {
return "";
}
StringJoiner mapperParams = new StringJoiner(", ");
Arrays.asList(params.split(",")).forEach(item -> {
mapperParams.add("@Param(\"" + item.split(" ")[1] + "\") " + item);
});
return mapperParams.toString();
}
/**
* 文件是否存在
*/
private static boolean isExistsFile(String filePathName) {
File file = new File(filePathName);
if (!file.exists()) { // file.isDirectory()
// file.createNewFile();
System.out.println("文件" + filePathName + "不存在, 无法代码生成" + FAIL_COLOR);
return false;
}
return true;
}
/**
* 包名转成路径
*/
private static String packageConvertPath(String packageName) {
return String.format("/%s/",
packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName);
}
/**
* 大驼峰转下划线
*/
private static String modelNameConvertTableName(String modelName) {
return CaseFormat.LOWER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName);
}
}
package com.onsiteservice;
import com.google.common.base.CaseFormat;
import com.onsiteservice.constant.constant.Constants;
import com.onsiteservice.util.command.CommandUtils;
import org.apache.commons.lang3.StringUtils;
import freemarker.template.TemplateExceptionHandler;
import org.apache.commons.lang3.StringUtils;
import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.*;
import org.mybatis.generator.internal.DefaultShellCallback;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.*;
/**
* @author 潘维吉
* @date 2018-06-06
* 代码自动生成器,根据数据表名称生成对应的Model、Mapper、XML、Service、Controller 提高开发体验和效率
*/
public class CodeGenerator {
//以下几个选项根据项目的实际情况修改
public static final String CURRENT_MODULE_NAME = "admin"; // 业务模块名称 根据项目修改
public static final String BASE_PACKAGE = "com.onsiteservice"; // 业务基础模块包名称 根据项目修改
public static final String CURRENT_PACKAGE = BASE_PACKAGE + ".admin"; // 业务模块包名称 根据项目修改
private static final String AUTHOR = "潘维吉"; // @author
public static final Boolean IS_GEN_PAGE = false; // 是否生成分页dao层代码
public static final Boolean IS_GEN_SAVE_OR_UPDATE = true; // 是否生成保存或更新方法
public static final Boolean IS_GEN_MAPPER_SEPARATE = true; // 是否生成通用mapper和自定义mapper分离 不分离:只生成通用mapper放在指定的业务模块 分离: 通用mapper在dao模块 自定义mapper在业务模块
//TODO 根据数据库表 自动生成CRUD和分页接口
public static void main(String[] args) {
String[] tables = new String[]{"user"}; // 输入表名 支持多表 模块目录情况批量代码生成确保表前缀一致 否则建议分批生成
if (!ask(tables)) {
return;
}
genCode(tables); // 默认按照表前缀分模块目录
List.of(tables).forEach(item -> { // 以下方法是根据不同需求生成不同的代码
// genModelAndMapper(item, true); // 生成Model实体类、通用Mapper接口和XML文件 当数据库表字段变化或只需实体类等 可设置只生成实体类
// genControllerAndService(item); // 只生成Controller、Service层
// genCustomMapperAndXML(item); // 只生成自定义业务Mapper接口和XML
});
// genCodeByCustomModelName("输入表名","输入自定义Model名称");
}
public static String FILE_MODULE = ""; // 自定义文件模块目录 用于生成到相应的文件夹下 默认使用表前缀
public static final Boolean IS_GEN_FILE_MODULE = true; // 是否生成文件模块目录
public static final Boolean IS_USE_MY_JAVA_TYPE_RESOLVER = true; // 是否使用自定义Mybatis自动生成代码数据类型转换 如tinyint 转成Integer
public static final Boolean IS_ENTITY_SERIALIZABLE = true; // 是否自动生成实体类序列化 如 implements Serializable
/** JDBC配置,请修改为你项目的实际配置 */
private static final String JDBC_DIVER_CLASS_NAME = "com.mysql.cj.jdbc.Driver"; // 8.x
private static final String JDBC_URL = "jdbc:mysql://39.96.84.51:3306/onsite_service_dev" +
"?useUnicode=true&characterEncoding=utf8&useSSL=false&serverTimezone=UTC";
private static final String JDBC_USERNAME = "onsite_service";
private static final String JDBC_PASSWORD = "antaikeji2022";
private static final String DATE = new SimpleDateFormat("yyyy-MM-dd HH:mm").format(new Date());//@date
private static final String CORE_PACKAGE = Constants.PACKAGE_NAME_GROUP + ".core"; //CORE核心模块包名称
private static final String DAO_PACKAGE = BASE_PACKAGE + ".dao"; //DAO数据库模块包名称
private static final String ENTITY_PACKAGE = BASE_PACKAGE + ".entity"; //Entity实体所在包
private static final String CONTROLLER_PACKAGE = CURRENT_PACKAGE + ".controller"; //Controller所在包
private static final String SERVICE_PACKAGE = CURRENT_PACKAGE + ".service"; //Service所在包
private static final String DAO_MAPPER_PACKAGE = DAO_PACKAGE + ".mapper"; //通用Mapper所在包
private static final String MAPPER_PACKAGE = CURRENT_PACKAGE + ".mapper"; //自定义Mapper所在包
private static final String COMMON_MAPPER = Constants.PACKAGE_NAME_GROUP + ".dao.common.Mapper";//Mapper插件基础接口
private static final String PROJECT_PATH = System.getProperty("user.dir") + "/" + CURRENT_MODULE_NAME; //当前项目在硬盘上的基础路径
private static final String ENTITY_PROJECT_PATH = System.getProperty("user.dir") + "/" + "entity"; //ENTITY模块在硬盘上的基础路径
private static final String DAO_PROJECT_PATH = System.getProperty("user.dir") + "/" + "dao"; //DAO模块在硬盘上的基础路径
private static final String TEMPLATE_FILE_PATH = System.getProperty("user.dir") + "/test/src/main/resources/generator"; //自定义生成模板.ftl文件位置
private static final String JAVA_PATH = "/src/main/java"; //java文件路径
private static final String RESOURCES_PATH = "/src/main/resources";//xml sql资源文件路径
private static final String CONTROLLER_PACKAGE_PATH = packageConvertPath(CONTROLLER_PACKAGE);//生成的Controller存放路径
private static final String SERVICE_PACKAGE_PATH = packageConvertPath(SERVICE_PACKAGE);//生成的Service接口存放路径
private static final String DAO_MAPPER_PACKAGE_PATH = packageConvertPath(DAO_MAPPER_PACKAGE);//生成通用Mapper接口存放路径
private static final String MAPPER_PACKAGE_PATH = packageConvertPath(MAPPER_PACKAGE);//生成自定义Mapper接口存放路径
public static final String SUCCESS_COLOR = Constants.ANSI_GREEN + " ✔ " + Constants.ANSI_RESET;
/**
* 通过数据表名称生成代码,Model 名称通过解析数据表名称获得,下划线转大驼峰的形式。
* 如输入表名称 "t_user_detail" 将生成 TUserDetail、TUserDetailMapper、TUserDetailService ...
*
* @param tableNames 数据表名称...
*/
public static void genCode(String... tableNames) {
for (String tableName : tableNames) {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
genCodeByCustomModelName(tableName, null);
}
}
/**
* 通过数据表名称,和自定义的 Model 名称生成代码
* 如输入表名称 "t_user_detail" 和自定义的 Model 名称 "User" 将生成 User、UserMapper、UserService、UserController...
*
* @param tableName 数据表名称
* @param modelName 自定义的 Model 名称
*/
public static void genCodeByCustomModelName(String tableName, String modelName) {
FILE_MODULE = StringUtils.isNotBlank(FILE_MODULE) ? FILE_MODULE : tableName.split("_")[0];
if (IS_GEN_MAPPER_SEPARATE) {
genCustomMapperAndXML(tableName);
}
genModelAndMapper(tableName, modelName, false);
genService(tableName, modelName);
genController(tableName, modelName);
}
/**
* 已自动生成复用模块的Model实体类、XML SQL文件和Mapper Dao接口
* 只需要单独生成指定项目 Controller、 Service层
*
* @param tableName 数据表名称
*/
public static void genControllerAndService(String tableName) {
FILE_MODULE = StringUtils.isNotBlank(FILE_MODULE) ? FILE_MODULE : tableName.split("_")[0];
genService(tableName, null);
genController(tableName, null);
}
/**
* 生成Model实体类和XML SQL文件
* 不改变Mapper Dao接口文件和Service Controller层
*
* @param tableName 数据表名称
* @param onlyGenModel 只生成实体类
*/
public static void genModelAndMapper(String tableName, Boolean onlyGenModel) {
FILE_MODULE = StringUtils.isNotBlank(FILE_MODULE) ? FILE_MODULE : tableName.split("_")[0];
genModelAndMapper(tableName, null, onlyGenModel);
}
/**
* 生成自定义业务Mapper接口和XML
*
* @param tableName 数据表名称
*/
public static void genCustomMapperAndXML(String tableName) {
FILE_MODULE = StringUtils.isNotBlank(FILE_MODULE) ? FILE_MODULE : tableName.split("_")[0];
genCustomMapper(tableName, null);
}
/**
* 生成Model模型 Mapper接口 XML的sql文件
*
* @param tableName 数据表名称
* @param modelName 自定义的 Model 名称
* @param onlyGenModel 只生成实体类
*/
public static void genModelAndMapper(String tableName, String modelName, Boolean onlyGenModel) {
Context context = new Context(ModelType.FLAT);
context.setId("Potato");
context.setTargetRuntime("MyBatis3Simple");
//生成的Java文件
context.addProperty(PropertyRegistry.CONTEXT_JAVA_FILE_ENCODING, "utf-8");
context.addProperty(PropertyRegistry.CONTEXT_BEGINNING_DELIMITER, "`");
context.addProperty(PropertyRegistry.CONTEXT_ENDING_DELIMITER, "`");
//设置数据库连接信息
JDBCConnectionConfiguration jdbcConnectionConfiguration = new JDBCConnectionConfiguration();
jdbcConnectionConfiguration.setConnectionURL(JDBC_URL);
jdbcConnectionConfiguration.setUserId(JDBC_USERNAME);
jdbcConnectionConfiguration.setPassword(JDBC_PASSWORD);
jdbcConnectionConfiguration.setDriverClass(JDBC_DIVER_CLASS_NAME);
//解决mysql的驱动版本导致的generator生成实体类的无@Id问题 5.x.x驱动正常有@id,6.x和8.x都没有@id
jdbcConnectionConfiguration.addProperty("nullCatalogMeansCurrent", "true");
context.setJdbcConnectionConfiguration(jdbcConnectionConfiguration);
//添加各种插件 插件配置信息
addPlugins(context);
//生成实体类Entity对象
JavaModelGeneratorConfiguration javaModelGeneratorConfiguration = new JavaModelGeneratorConfiguration();
javaModelGeneratorConfiguration.setTargetProject(ENTITY_PROJECT_PATH + JAVA_PATH);
javaModelGeneratorConfiguration.setTargetPackage(IS_GEN_FILE_MODULE ? (ENTITY_PACKAGE + "." + FILE_MODULE) : ENTITY_PACKAGE);
context.setJavaModelGeneratorConfiguration(javaModelGeneratorConfiguration);
// 自动判断通用mapper是否已生成 已生成不再生成
String mapperPath = DAO_PROJECT_PATH + JAVA_PATH + DAO_MAPPER_PACKAGE_PATH + (IS_GEN_FILE_MODULE ? (FILE_MODULE + "/") : "")
+ (modelName == null ? tableNameConvertUpperCamel(tableName) : modelName) + "Mapper.java";
if (isExistsFile(mapperPath)) {
onlyGenModel = true;
System.out.println(mapperPath + " 通用mapper已生成, 不再生成 !!!");
}
if (!onlyGenModel) {
// 生成SQL XML资源
SqlMapGeneratorConfiguration sqlMapGeneratorConfiguration = new SqlMapGeneratorConfiguration();
if (IS_GEN_MAPPER_SEPARATE) {
sqlMapGeneratorConfiguration.setTargetProject(DAO_PROJECT_PATH + RESOURCES_PATH);
sqlMapGeneratorConfiguration.setTargetPackage(IS_GEN_FILE_MODULE ? ("mapper" + "." + FILE_MODULE) : "mapper");
} else {
sqlMapGeneratorConfiguration.setTargetProject(PROJECT_PATH + RESOURCES_PATH);
sqlMapGeneratorConfiguration.setTargetPackage(IS_GEN_FILE_MODULE ? ("mapper" + "." + FILE_MODULE) : "mapper");
}
context.setSqlMapGeneratorConfiguration(sqlMapGeneratorConfiguration);
//生成Mapper Dao接口
JavaClientGeneratorConfiguration javaClientGeneratorConfiguration = new JavaClientGeneratorConfiguration();
if (IS_GEN_MAPPER_SEPARATE) {
javaClientGeneratorConfiguration.setTargetProject(DAO_PROJECT_PATH + JAVA_PATH);
javaClientGeneratorConfiguration.setTargetPackage(IS_GEN_FILE_MODULE ? (DAO_MAPPER_PACKAGE + "." + FILE_MODULE) : DAO_MAPPER_PACKAGE);
} else {
javaClientGeneratorConfiguration.setTargetProject(PROJECT_PATH + JAVA_PATH);
javaClientGeneratorConfiguration.setTargetPackage(IS_GEN_FILE_MODULE ? (MAPPER_PACKAGE + "." + FILE_MODULE) : MAPPER_PACKAGE);
}
//建议设置type="XMLMAPPER",不建议使用注解或混合模式 代码和SQL完全分离易于维护
javaClientGeneratorConfiguration.setConfigurationType("XMLMAPPER");
context.setJavaClientGeneratorConfiguration(javaClientGeneratorConfiguration);
}
TableConfiguration tableConfiguration = new TableConfiguration(context);
tableConfiguration.setTableName(tableName);
if (StringUtils.isNotBlank(modelName)) {
tableConfiguration.setDomainObjectName(modelName);
}
tableConfiguration.setGeneratedKey(
new GeneratedKey("id", "Mysql", true, null));
context.addTableConfiguration(tableConfiguration);
List<String> warnings;
MyBatisGenerator generator;
try {
Configuration config = new Configuration();
config.addContext(context);
config.validate();
//是否覆盖Model和Mapper文件
boolean overwrite = true;
DefaultShellCallback callback = new DefaultShellCallback(overwrite);
warnings = new ArrayList<String>();
generator = new MyBatisGenerator(config, callback, warnings);
generator.generate(null);
} catch (Exception e) {
throw new RuntimeException("生成Model和Mapper失败", e);
}
if (StringUtils.isBlank(modelName)) {
modelName = tableNameConvertUpperCamel(tableName);
}
System.out.println();
System.out.println("===========================CRUD代码自动生成结果=================================");
System.out.println();
System.out.println(modelName + ".java 实体类生成成功" + SUCCESS_COLOR);
if (!onlyGenModel) {
if (generator.getGeneratedJavaFiles().isEmpty() || generator.getGeneratedXmlFiles().isEmpty()) {
throw new RuntimeException("生成Model和Mapper失败:" + warnings);
}
System.out.println(modelName + "Mapper.xml 通用资源XML SQL文件生成成功" + SUCCESS_COLOR);
System.out.println(modelName + "Mapper.java 通用Mapper接口生成成功" + SUCCESS_COLOR);
System.out.println();
System.out.println("==============================================================================");
// 回滚生成的代码
/* CommandUtils.executeCommand("git -c core.quotepath=false -c log.showSignature=false rm --cached -f -- " + mapperPath);
CommandUtils.executeCommand("git -c core.quotepath=false -c log.showSignature=false checkout HEAD -- " + mapperPath);*/
}
CommandUtils.executeCommand("git add .");
}
/**
* 生成自定义业务Mapper接口和XML
*
* @param tableName 数据表名称
* @param modelName 自定义的 Model 名称
*/
public static void genCustomMapper(String tableName, String modelName) {
try {
freemarker.template.Configuration cfg = getConfiguration();
String modelNameUpperCamel = StringUtils.isBlank(modelName) ? tableNameConvertUpperCamel(tableName) : modelName;
Map<String, Object> data = setData(modelNameUpperCamel, tableName);
File file1 = new File(
PROJECT_PATH + JAVA_PATH + MAPPER_PACKAGE_PATH + (IS_GEN_FILE_MODULE ? (FILE_MODULE + "/") : "") + modelNameUpperCamel + "BizMapper.java");
if (!file1.getParentFile().exists()) {
file1.getParentFile().mkdirs();
}
cfg.getTemplate("mapper.ftl").process(data, new FileWriter(file1));
System.out.println(modelNameUpperCamel + "BizMapper.java 自定义业务Mapper生成成功" + SUCCESS_COLOR);
File file2 = new File(
PROJECT_PATH + RESOURCES_PATH + "/" + (IS_GEN_FILE_MODULE ? ("mapper" + "/" + FILE_MODULE) : "mapper") + "/" + modelNameUpperCamel + "BizMapper.xml");
if (!file2.getParentFile().exists()) {
file2.getParentFile().mkdirs();
}
cfg.getTemplate("mapper-xml.ftl").process(data, new FileWriter(file2));
System.out.println(modelNameUpperCamel + "BizMapper.xml 自定义业务xml生成成功" + SUCCESS_COLOR);
} catch (Exception e) {
throw new RuntimeException("生成自定义业务Mapper失败", e);
}
}
/**
* 生成Service接口和实现类
*
* @param tableName 数据表名称
* @param modelName 自定义的 Model 名称
*/
public static void genService(String tableName, String modelName) {
try {
freemarker.template.Configuration cfg = getConfiguration();
String modelNameUpperCamel = StringUtils.isBlank(modelName) ? tableNameConvertUpperCamel(tableName) : modelName;
Map<String, Object> data = setData(modelNameUpperCamel, tableName);
File file1 = new File(
PROJECT_PATH + JAVA_PATH + SERVICE_PACKAGE_PATH + (IS_GEN_FILE_MODULE ? (FILE_MODULE + "/") : "") + modelNameUpperCamel + "Service.java");
if (!file1.getParentFile().exists()) {
file1.getParentFile().mkdirs();
}
cfg.getTemplate("service-impl.ftl").process(data,
new FileWriter(file1));
System.out.println(modelNameUpperCamel + "Service.java 服务类生成成功" + SUCCESS_COLOR);
} catch (Exception e) {
throw new RuntimeException("生成Service失败", e);
}
}
/**
* 生成Controller控制类
*
* @param tableName 数据表名称
* @param modelName 自定义的 Model 名称
*/
public static void genController(String tableName, String modelName) {
try {
freemarker.template.Configuration cfg = getConfiguration();
String modelNameUpperCamel = StringUtils.isBlank(modelName) ? tableNameConvertUpperCamel(tableName) : modelName;
Map<String, Object> data = setData(modelNameUpperCamel, tableName);
File file = new File(
PROJECT_PATH + JAVA_PATH + CONTROLLER_PACKAGE_PATH + (IS_GEN_FILE_MODULE ? (FILE_MODULE + "/") : "") + modelNameUpperCamel + "Controller.java");
if (!file.getParentFile().exists()) {
file.getParentFile().mkdirs();
}
// controller-restful.ftl 两种风格选择
cfg.getTemplate("controller-swagger.ftl").process(data, new FileWriter(file));
System.out.println(modelNameUpperCamel + "Controller.java 控制类生成成功" + SUCCESS_COLOR);
System.out.println();
System.out.println("==============================================================================");
CommandUtils.executeCommand("git add .");
} catch (Exception e) {
throw new RuntimeException("生成Controller失败", e);
}
}
/**
* 统一设置Controller层 Service层生成模板需要的数据信息
*
* @param modelNameUpperCamel
* @return
*/
private static Map setData(String modelNameUpperCamel, String tableName) {
Map<String, Object> data = new HashMap<>(10);
data.put("author", AUTHOR);
data.put("date", DATE);
data.put("requestMappingPath", modelNameConvertMappingPath(modelNameUpperCamel));
data.put("modelNameUpperCamel", modelNameUpperCamel);
data.put("modelNameLowerCamel", CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_CAMEL, modelNameUpperCamel));
data.put("corePackage", CORE_PACKAGE);
data.put("commonDaoPackage", Constants.PACKAGE_NAME_GROUP + ".dao");
data.put("daoPackage", DAO_PACKAGE);
data.put("entityPackage", ENTITY_PACKAGE);
data.put("fileModule", FILE_MODULE);
data.put("currentPackage", CURRENT_PACKAGE);
data.put("isGenFileModule", IS_GEN_FILE_MODULE);
data.put("isGenMapperSeparate", IS_GEN_MAPPER_SEPARATE);
data.put("isGenPage", IS_GEN_PAGE);
data.put("isGenSaveOrUpdate", IS_GEN_SAVE_OR_UPDATE);
return data;
}
/**
* 添加各种插件
*/
private static void addPlugins(Context context) {
PluginConfiguration pluginConfiguration = new PluginConfiguration();
pluginConfiguration.setConfigurationType("tk.mybatis.mapper.generator.MapperPlugin");
//通用的Mapper文件地址 Mapper接口继承它
pluginConfiguration.addProperty("mappers", COMMON_MAPPER);
//增加 Model 代码生成时,可以直接生成 lombok 注解 如不使用lombok请去掉配置 Mapper 4.1.0以上支持
pluginConfiguration.addProperty("lombok", "Getter,Setter,ToString");
pluginConfiguration.addProperty("swagger", "true");
context.addPluginConfiguration(pluginConfiguration);
if (IS_USE_MY_JAVA_TYPE_RESOLVER) { // 自定义Mybatis自动生成代码数据类型转换
JavaTypeResolverConfiguration javaTypeResolverConfiguration = new JavaTypeResolverConfiguration();
//是否使用bigDecimal, false可自动转化以下类型(Long, Integer, Short, etc.)
javaTypeResolverConfiguration.addProperty("forceBigDecimals", "false");
javaTypeResolverConfiguration.setConfigurationType("MyJavaTypeResolverImpl");
context.setJavaTypeResolverConfiguration(javaTypeResolverConfiguration);
}
if (IS_ENTITY_SERIALIZABLE) { //实现实体类序列化插件
pluginConfiguration = new PluginConfiguration();
pluginConfiguration.setConfigurationType("org.mybatis.generator.plugins.SerializablePlugin");
context.addPluginConfiguration(pluginConfiguration);
}
}
private static freemarker.template.Configuration getConfiguration() throws IOException {
freemarker.template.Configuration cfg =
new freemarker.template.Configuration(freemarker.template.Configuration.VERSION_2_3_28);
cfg.setDirectoryForTemplateLoading(new File(TEMPLATE_FILE_PATH));
cfg.setDefaultEncoding("UTF-8");
cfg.setTemplateExceptionHandler(TemplateExceptionHandler.IGNORE_HANDLER);
return cfg;
}
private static String tableNameConvertLowerCamel(String tableName) {
//带下划线的表名转化成小驼峰命名
return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.LOWER_CAMEL, tableName.toLowerCase());
}
private static String tableNameConvertUpperCamel(String tableName) {
//带下划线的表名转化成大驼峰命名
return CaseFormat.LOWER_UNDERSCORE.to(CaseFormat.UPPER_CAMEL, tableName.toLowerCase());
}
private static String tableNameConvertMappingPath(String tableName) {
tableName = tableName.toLowerCase();//兼容使用大写的表名
return "/" + (tableName.contains("_") ? tableName.replaceAll("_", "/") : tableName);
}
private static String modelNameConvertMappingPath(String modelName) {
String tableName = CaseFormat.UPPER_CAMEL.to(CaseFormat.LOWER_UNDERSCORE, modelName);
return tableNameConvertMappingPath(tableName);
}
private static String packageConvertPath(String packageName) {
// 包名转成路径
return String.format("/%s/",
packageName.contains(".") ? packageName.replaceAll("\\.", "/") : packageName);
}
/**
* 文件是否存在
*/
private static boolean isExistsFile(String filePathName) {
File file = new File(filePathName);
if (!file.exists()) { // file.isDirectory()
// file.createNewFile();
return false;
}
return true;
}
/**
* 询问
*/
private static boolean ask(String... tables) {
Scanner kbd = new Scanner(System.in);
System.out.println("请确认以下参数是否正确 \uD83D\uDC47");
System.out.println("执行的模块名称: " + CURRENT_MODULE_NAME);
System.out.println("执行的模块包名: " + CURRENT_PACKAGE);
System.out.println("执行的表名: " + StringUtils.join(tables, ","));
System.out.println("请输入是否执行CRUD代码生成: yes/no");
String decision = kbd.nextLine();
switch (decision) {
case "yes":
return true;
case "no":
return false;
default:
System.out.println("输入错误请重新执行");
return false;
}
}
}
package com.onsiteservice;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;
import java.sql.Types;
/**
* @author 潘维吉
* @date 2020-02-05 9:10
* 自定义Mybatis自动生成代码数据类型转换
*/
public class MyJavaTypeResolverImpl extends JavaTypeResolverDefaultImpl {
public MyJavaTypeResolverImpl() {
super();
//把数据库的 TINYINT 映射成 Integer 类型 而不是Byte类型 简化程序开发
super.typeMap.put(Types.TINYINT, new JdbcTypeInformation("TINYINT", new FullyQualifiedJavaType(Integer.class.getName())));
super.typeMap.put(Types.SMALLINT, new JdbcTypeInformation("SMALLINT", new FullyQualifiedJavaType(Integer.class.getName())));
}
}
<#if isGenFileModule >
package ${currentPackage}.controller.${fileModule};
import ${entityPackage}.${fileModule}.${modelNameUpperCamel};
import ${currentPackage}.service.${fileModule}.${modelNameUpperCamel}Service;
<#else>
package ${currentPackage}.controller;
import ${entityPackage}.${modelNameUpperCamel};
import ${currentPackage}.service.${modelNameUpperCamel}Service;
</#if>
import ${corePackage}.result.Result;
import ${commonDaoPackage}.common.page.PageParams;
import lombok.NonNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import javax.validation.constraints.Positive;
import static ${corePackage}.result.ResultGenerator.success;
import static ${corePackage}.result.ResultGenerator.fail;
/**
* @author ${author}
* @date ${date}
* @description ${modelNameUpperCamel}Controller控制类
*/
@RestController
@RequestMapping("${requestMappingPath}")
@Validated
public class ${modelNameUpperCamel}Controller {
@Resource
private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service;
/**
* 分页查询列表
*
* @param param 分页参数
* @return 分页数据
*/
@PostMapping("/page")
public Result getPage(@RequestBody @NonNull @Validated PageParams param) {
return success(${modelNameLowerCamel}Service.getPage(param), "获取分页列表");
}
/**
* 根据id查询
*
* @param id 主键
* @return 详情数据
*/
@GetMapping("/{id}")
public Result getDetails(@PathVariable @Positive Long id) {
return success(${modelNameLowerCamel}Service.selectByPrimaryKey(id), "根据id获取详情");
}
<#if isGenSaveOrUpdate >
/**
* 新增或修改
*/
@PostMapping("/save-or-update")
public Result saveOrUpdate(@RequestBody @NonNull @Validated ${modelNameUpperCamel} ${modelNameLowerCamel}) {
return success(${modelNameLowerCamel}Service.saveOrUpdate(${modelNameLowerCamel}), ${modelNameLowerCamel}.getId() == null ? "新增成功" : "修改成功");
}
<#else>
/**
* 新增
*
* @param ${modelNameLowerCamel} 新增对象
*/
@PostMapping
public Result save(@RequestBody @NonNull @Validated ${modelNameUpperCamel} ${modelNameLowerCamel}) {
return success(${modelNameLowerCamel}Service.insertSelective(${modelNameLowerCamel}), "新增成功");
}
/**
* 修改
*
* @param ${modelNameLowerCamel} 修改对象
*/
@PutMapping
public Result update(@RequestBody @NonNull @Validated ${modelNameUpperCamel} ${modelNameLowerCamel}) {
return success(${modelNameLowerCamel}Service.updateByPrimaryKeySelective(${modelNameLowerCamel}), "修改成功");
}
</#if>
/**
* 根据id删除
*
* @param id 主键
*/
@DeleteMapping("/{id}")
public Result deleteById(@PathVariable @Positive Long id) {
return success(${modelNameLowerCamel}Service.deleteByPrimaryKey(id), "删除成功");
}
}
<#if isGenFileModule >
package ${currentPackage}.controller.${fileModule};
import ${entityPackage}.${fileModule}.${modelNameUpperCamel};
import ${currentPackage}.service.${fileModule}.${modelNameUpperCamel}Service;
<#else>
package ${currentPackage}.controller;
import ${daoPackage}.model.${modelNameUpperCamel};
import ${currentPackage}.service.${modelNameUpperCamel}Service;
</#if>
import ${corePackage}.result.Result;
import ${commonDaoPackage}.common.page.PageInfoVO;
import ${commonDaoPackage}.common.page.PageParams;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.NonNull;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import springfox.documentation.annotations.ApiIgnore;
import javax.annotation.Resource;
import javax.validation.constraints.Positive;
import static ${corePackage}.result.ResultGenerator.success;
import static ${corePackage}.result.ResultGenerator.fail;
/**
* @author ${author}
* @date ${date}
* @description ${modelNameUpperCamel}Controller控制类
*/
@ApiIgnore
@Api(tags = "${modelNameUpperCamel}Controller")
@RestController
@RequestMapping("${requestMappingPath}")
@Validated
public class ${modelNameUpperCamel}Controller {
@Resource
private ${modelNameUpperCamel}Service ${modelNameLowerCamel}Service;
@ApiOperation(value = "分页查询列表", notes = "作者: ${author}")
@PostMapping("/page")
public Result<PageInfoVO> getPage(@RequestBody @NonNull @Validated PageParams param) {
return success(${modelNameLowerCamel}Service.getPage(param), "获取分页列表");
}
@ApiOperation(value = "根据id查询", notes = "作者: ${author}")
@GetMapping("/{id}")
public Result<${modelNameUpperCamel}> getDetails(@PathVariable @Positive Long id) {
return success(${modelNameLowerCamel}Service.selectByPrimaryKey(id), "根据id获取详情");
}
<#if isGenSaveOrUpdate >
@ApiOperation(value = "新增或修改", notes = "作者: ${author}")
@PostMapping("/save-or-update")
public Result saveOrUpdate(@RequestBody @NonNull @Validated ${modelNameUpperCamel} ${modelNameLowerCamel}) {
return success(${modelNameLowerCamel}Service.saveOrUpdate(${modelNameLowerCamel}), ${modelNameLowerCamel}.getId() == null ? "新增成功" : "修改成功");
}
<#else>
@ApiOperation(value = "新增", notes = "作者: ${author}")
@PostMapping
public Result save(@RequestBody @NonNull @Validated ${modelNameUpperCamel} ${modelNameLowerCamel}) {
return success(${modelNameLowerCamel}Service.insertSelective(${modelNameLowerCamel}), "新增成功");
}
@ApiOperation(value = "修改", notes = "作者: ${author}")
@PutMapping
public Result update(@RequestBody @NonNull @Validated ${modelNameUpperCamel} ${modelNameLowerCamel}) {
return success(${modelNameLowerCamel}Service.updateByPrimaryKeySelective(${modelNameLowerCamel}), "修改成功");
}
</#if>
@ApiOperation(value = "根据id删除", notes = "作者: ${author}")
@DeleteMapping("/{id}")
public Result deleteById(@PathVariable @Positive Long id) {
return success(${modelNameLowerCamel}Service.deleteByPrimaryKey(id), "删除成功");
}
}
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<#if isGenFileModule >
<mapper namespace="${currentPackage}.mapper.${fileModule}.${modelNameUpperCamel}BizMapper">
<#else>
<mapper namespace="${currentPackage}.mapper.${modelNameUpperCamel}BizMapper">
</#if>
<#if isGenPage >
<!--分页查询列表-->
<select id="getPage" resultType="map">
select t1.*
from t1
<where>
and t1.is_deleted = 0
<if test="param.name != null and param.name != ''">
and t1.name like <#noparse>"%"#{param.name}"%"</#noparse>
</if>
</where>
order by
<if test="param.sort != null and param.sort != ''">
<#noparse>${param.sort} ${param.order}</#noparse>,
</if>
t1.id desc
</select>
</#if>
</mapper>
<#if isGenFileModule >
package ${currentPackage}.mapper.${fileModule};
<#else>
package ${currentPackage}.mapper;
</#if>
<#if isGenPage >
import ${commonDaoPackage}.common.page.PageParams;
import org.apache.ibatis.annotations.Param;
import java.util.List;
</#if>
/**
* @author ${author}
* @date ${date}
* @description ${modelNameUpperCamel}BizMapper业务接口
*/
public interface ${modelNameUpperCamel}BizMapper {
<#if isGenPage >
/**
* 分页查询列表
*/
List getPage(@Param("param") PageParams param);
</#if>
}
<#if isGenFileModule >
package ${currentPackage}.service.${fileModule};
import ${entityPackage}.${fileModule}.${modelNameUpperCamel};
<#if isGenMapperSeparate >
import ${daoPackage}.mapper.${fileModule}.${modelNameUpperCamel}Mapper;
import ${currentPackage}.mapper.${fileModule}.${modelNameUpperCamel}BizMapper;
<#else>
import ${currentPackage}.mapper.${fileModule}.${modelNameUpperCamel}Mapper;
</#if>
<#else>
package ${currentPackage}.service;
import ${entityPackage}.${modelNameUpperCamel};
<#if isGenMapperSeparate >
import ${daoPackage}.mapper.${modelNameUpperCamel}Mapper;
import ${currentPackage}.mapper.${modelNameUpperCamel}BizMapper;
<#else>
import ${currentPackage}.mapper.${modelNameUpperCamel}Mapper;
</#if>
</#if>
import ${commonDaoPackage}.common.AbstractMapper;
import ${commonDaoPackage}.common.page.PageParams;
import ${commonDaoPackage}.common.page.PageInfoVO;
import com.github.pagehelper.PageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import javax.annotation.Resource;
/**
* @author ${author}
* @date ${date}
* @description ${modelNameUpperCamel}Service服务类
*/
@Service
@Transactional(rollbackFor = Exception.class)
public class ${modelNameUpperCamel}Service extends AbstractMapper<${modelNameUpperCamel}> {
@Resource
private ${modelNameUpperCamel}Mapper ${modelNameLowerCamel}Mapper;
<#if isGenMapperSeparate >
@Resource
private ${modelNameUpperCamel}BizMapper ${modelNameLowerCamel}BizMapper;
</#if>
/**
* 分页查询列表
*/
public PageInfoVO getPage(PageParams param) {
PageHelper.startPage(param.getPage(), param.getSize());
<#if !isGenPage >
return new PageInfoVO(this.selectAll());
<#else>
return new PageInfoVO(${modelNameLowerCamel}BizMapper.getPage(param));
</#if>
}
<#if isGenSaveOrUpdate >
/**
* 保存或更新方法
*/
public int saveOrUpdate(${modelNameUpperCamel} ${modelNameLowerCamel}) {
if (${modelNameLowerCamel}.getId() == null) {
return this.insertSelective(${modelNameLowerCamel});
} else {
return this.updateByPrimaryKeySelective(${modelNameLowerCamel});
}
}
</#if>
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment