package cn.huge.module.buildcode.service; import cn.huge.module.buildcode.domain.bo.UserTabColsBO; import cn.huge.module.buildcode.dao.mapper.BuildCodeMapper; import com.google.common.collect.Maps; import freemarker.core.ParseException; import freemarker.template.*; import lombok.extern.slf4j.Slf4j; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.CollectionUtils; import javax.annotation.PostConstruct; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.OutputStreamWriter; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.text.SimpleDateFormat; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * @title: 代码生成器服务层基类 * @description: 使用单元测试直接对buildAll执行测试完成代码生成 * @company: hugeinfo * @author: liyj * @time: 2021-11-05 16:51:48 * @version: 1.0.0 */ @Slf4j @Service public class BuildCodeService { public static void main(String[] args) throws MalformedURLException, URISyntaxException { } @Autowired private BuildCodeMapper buildCodeMapper; private Configuration cfg; private static StringBuffer ROOT_MAIN_PATH = new StringBuffer(System.getProperty("user.dir")).append(("/src/main/java/")); private static StringBuffer ROOT_TEST_PATH = new StringBuffer(System.getProperty("user.dir")).append(("/src/test/java/")); @PostConstruct private void init() throws IOException { try { Configuration configuration = new Configuration(Configuration.getVersion()); configuration.setClassForTemplateLoading(BuildCodeService.class, "/template"); configuration.setDefaultEncoding("UTF-8"); this.cfg = configuration; } catch (Exception e) { e.printStackTrace(); } } /** * 获取表数据属性 * @param packagePath 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 * @return Map */ private Map getTplData(String packagePath, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = Maps.newHashMap(); SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); tplData.put("packageName", packageName); tplData.put("className", className); tplData.put("author", author); tplData.put("version", version); tplData.put("createTime", format.format(new Date())); tplData.put("basePackage", packagePath); tplData.put("basePackagePath", packagePath.replace(".", "/") + "/"); List list = buildCodeMapper.getTabInfo(tableSchema, tableName); if (!CollectionUtils.isEmpty(list)) { UserTabColsBO vo = list.get(0); tplData.put("tableName", vo.getTableName()); tplData.put("tableComments", vo.getTableComments()); tplData.put("cols", list); tplData.put("hasDate", 0); tplData.put("hasClob", 0); tplData.put("hasBlob", 0); for (UserTabColsBO bo : list) { if (bo.getHasDate() > 0) { tplData.put("hasDate", 1); } } } return tplData; } /** * 生成所有层的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildAll(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { // 必须 this.buildPo(tplData); this.buildBo(tplData); this.buildDaoMapper(tplData); this.buildDaoMapperXml(tplData); this.buildService(tplData); this.buildWebController(tplData); // 可选 // this.buildWechatController(tplData); // this.buildJson(tplData); // this.buildJsForm(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成PO层的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildPo(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildPo(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成BO层的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildBo(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildBo(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成Mapper的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildDaoMapper(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildDaoMapper(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成MapperXml的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildDaoMapperXml(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildDaoMapperXml(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成service层的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildService(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildService(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成webController层的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildWebController(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildWebController(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成wechatController层的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildWechatController(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildWechatController(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成Controller层测试的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildControllerTest(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildControllerTest(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成service层测试的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildServiceTest(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildServiceTest(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成实体json的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildJson(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildJson(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } /** * 生成实体js的代码 * @param basePackage 包路径 * @param packageName 包名 * @param className 类名 * @param tableName 表名 * @param author 作者 * @param version 版本 */ public void buildJsForm(String basePackage, String packageName, String className, String tableSchema, String tableName, String author, String version) { Map tplData = this.getTplData(basePackage, packageName, className, tableSchema, tableName, author, version); try { this.buildJsForm(tplData); } catch (TemplateNotFoundException e) { log.error("TemplateNotFoundException"); } catch (TemplateException e) { log.error("TemplateException"); } catch (MalformedTemplateNameException e) { log.error("MalformedTemplateNameException"); } catch (ParseException e) { log.error("ParseException"); } catch (IOException e) { log.error("IOException"); } } private void buildFile(Template template, Map tplData, String path) throws IOException, TemplateException { File file = new File(path); File dir = new File(file.getParent()); if (!dir.exists()) { dir.mkdirs(); } if (!file.exists()) { file.createNewFile(); } else { //文件存在就做备份 int i = 1; File bakFile = new File(path + i + ".bak"); while (bakFile.exists()) { i++; bakFile = new File(path + i + ".bak"); } file.renameTo(bakFile); } FileOutputStream fos = new FileOutputStream(new File(path)); template.process(tplData, new OutputStreamWriter(fos, "utf-8")); fos.flush(); fos.close(); } /** * 创建持久化对象 * * @param tplData */ private void buildPo(Map tplData) throws TemplateException, IOException { Template template = cfg.getTemplate("po.ftl"); StringBuffer path = new StringBuffer(ROOT_MAIN_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/domain/po/") .append(tplData.get("className")) .append(".java"); this.buildFile(template, tplData, path.toString()); } /** * 创建业务对象 * * @param tplData */ private void buildBo(Map tplData) throws TemplateException, IOException { Template template = cfg.getTemplate("bo.ftl"); StringBuffer path = new StringBuffer(ROOT_MAIN_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/domain/bo/") .append(tplData.get("className")).append("BO") .append(".java"); this.buildFile(template, tplData, path.toString()); } /** * 创建Mybatis持久层接口 * * @param tplData */ private void buildDaoMapper(Map tplData) throws TemplateException, IOException { Template template = cfg.getTemplate("dao.mapper.ftl"); StringBuffer path = new StringBuffer(ROOT_MAIN_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/dao/mapper/") .append(tplData.get("className")).append("Mapper") .append(".java"); this.buildFile(template, tplData, path.toString()); } /** * 创建Mybatis Mapper.xml文件 * * @param tplData */ private void buildDaoMapperXml(Map tplData) throws TemplateException, IOException { Template template = cfg.getTemplate("dao.mapperXml.ftl"); StringBuffer path = new StringBuffer(ROOT_MAIN_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/dao/mapper/xml/") .append(tplData.get("className")).append("Mapper") .append(".xml"); this.buildFile(template, tplData, path.toString()); } /** * 创建服务层 * * @param tplData */ private void buildService(Map tplData) throws TemplateException, IOException { String className = (String) tplData.get("className"); if (Character.isLowerCase(className.charAt(0))){ tplData.put("lowerName", className); }else{ String lowerName = (new StringBuilder()).append(Character.toLowerCase(className.charAt(0))).append(className.substring(1)).toString(); tplData.put("lowerName", lowerName); } Template template = cfg.getTemplate("service.ftl"); StringBuffer path = new StringBuffer(ROOT_MAIN_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/service/") .append(tplData.get("className")).append("Service") .append(".java"); this.buildFile(template, tplData, path.toString()); } /** * 创建web控制层 * * @param tplData */ private void buildWebController(Map tplData) throws TemplateException, IOException { tplData.put("packagePath", ((String) tplData.get("packageName")).toLowerCase()); String className = (String) tplData.get("className"); if (Character.isLowerCase(className.charAt(0))){ tplData.put("classPath", className); tplData.put("lowerName", className); }else{ String lowerName = (new StringBuilder()).append(Character.toLowerCase(className.charAt(0))).append(className.substring(1)).toString(); tplData.put("classPath", lowerName); tplData.put("lowerName", lowerName); } Template template = cfg.getTemplate("webController.ftl"); StringBuffer path = new StringBuffer(ROOT_MAIN_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/controller/web/") .append(tplData.get("className")).append("WebController") .append(".java"); this.buildFile(template, tplData, path.toString()); } /** * 创建wechat控制层 * * @param tplData */ private void buildWechatController(Map tplData) throws TemplateException, IOException { tplData.put("packagePath", ((String) tplData.get("packageName")).toLowerCase()); String className = (String) tplData.get("className"); if (Character.isLowerCase(className.charAt(0))){ tplData.put("classPath", className); tplData.put("lowerName", className); }else{ String lowerName = (new StringBuilder()).append(Character.toLowerCase(className.charAt(0))).append(className.substring(1)).toString(); tplData.put("classPath", lowerName); tplData.put("lowerName", lowerName); } Template template = cfg.getTemplate("wechatController.ftl"); StringBuffer path = new StringBuffer(ROOT_MAIN_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/controller/wechat/") .append(tplData.get("className")).append("WechatController") .append(".java"); this.buildFile(template, tplData, path.toString()); } /** * 创建服务层单元测试 * * @param tplData */ private void buildServiceTest(Map tplData) throws TemplateException, IOException { String className = (String) tplData.get("className"); if (Character.isLowerCase(className.charAt(0))){ tplData.put("lowerName", className); }else{ String lowerName = (new StringBuilder()).append(Character.toLowerCase(className.charAt(0))).append(className.substring(1)).toString(); tplData.put("lowerName", lowerName); } Template template = cfg.getTemplate("serviceTest.ftl"); StringBuffer path = new StringBuffer(ROOT_TEST_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/") .append(tplData.get("className")).append("ServiceTest") .append(".java"); this.buildFile(template, tplData, path.toString()); } /** * 创建控制层单元测试 * * @param tplData */ private void buildControllerTest(Map tplData) throws TemplateException, IOException { tplData.put("packagePath", ((String) tplData.get("packageName")).toLowerCase()); String className = (String) tplData.get("className"); if (Character.isLowerCase(className.charAt(0))){ tplData.put("classPath", className); tplData.put("lowerName", className); }else{ String lowerName = (new StringBuilder()).append(Character.toLowerCase(className.charAt(0))).append(className.substring(1)).toString(); tplData.put("classPath", lowerName); tplData.put("lowerName", lowerName); } Template template = cfg.getTemplate("controllerTest.ftl"); StringBuffer path = new StringBuffer(ROOT_TEST_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/") .append(tplData.get("className")).append("ControllerTest") .append(".java"); this.buildFile(template, tplData, path.toString()); } /** * 创建Json代码 * * @param tplData */ private void buildJson(Map tplData) throws TemplateException, IOException { Template template = cfg.getTemplate("json.ftl"); StringBuffer path = new StringBuffer(ROOT_MAIN_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/domain/json/") .append(tplData.get("className")) .append(".json"); this.buildFile(template, tplData, path.toString()); } /** * 创建界面React JS代码 * * @param tplData */ private void buildJsForm(Map tplData) throws TemplateException, IOException { Template template = cfg.getTemplate("jsform.ftl"); StringBuffer path = new StringBuffer(ROOT_MAIN_PATH) .append(tplData.get("basePackagePath")) .append(tplData.get("packageName")).append("/domain/js/") .append(tplData.get("className")) .append(".js"); this.buildFile(template, tplData, path.toString()); } } /** * -------------------_ooOoo_------------------- * ------------------o8888888o------------------ * ------------------88" . "88------------------ * ------------------(| -_- |)------------------ * ------------------O\ = /O------------------ * ---------------____/`---'\____--------------- * -------------.' \\| |// `.------------- * ------------/ \\||| : |||// \------------ * -----------/ _||||| -:- |||||- \----------- * -----------| | \\\ - /// | |----------- * -----------| \_| ''\---/'' | |----------- * -----------\ .-\__ `-` ___/-. /----------- * ---------___`. .' /--.--\ `. . __---------- * ------."" '< `.___\_<|>_/___.' >'"".------- * -----| | : `- \`.;`\ _ /`;.`/ - ` : | |----- * -----\ \ `-. \_ __\ /__ _/ .-` / /----- * ======`-.____`-.___\_____/___.-`____.-'====== * -------------------`=---=' * ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ * ---------佛祖保佑---hugeinfo---永无BUG---------- */