文章插图
前言通常在开始开发项目的时候,首先会建立好数据库相关表,然后根据表结构生成 Controller、Service、DAO、Model以及一些前端页面 。
如果开发前没有强制的约束,而每个程序员都有自己的编码习惯,最终会导致一个项目呈现出多种编码风格 。再有就是一些CRUD的列表功能,基本是没啥挑战性的,纯粹苦力活,浪费时间 。
所以,根据公司现有框架,开发一款统一风格的代码生成器还是很有必要的 。
技术选型
开发框架:SpringBoot+JPA,考虑到会生成各种前后端代码文件,这里我们选用freemarker模板引擎来制作相应的模板 。
实现思路
获取表结构信息
首先我们定义一个实体类,为了使用方便,把表和字段信息放到了一个类中:
/** * 表以及相关字段信息 */@Datapublic class AppGen extends PageBean implements Serializable {/*** 表名*/private String tableName;/*** 实体类名*/private String entityName;/*** 实体类名 首字母小写*/private String lowerEntityName;/*** 表备注*/private String tableComment;/*** 表前缀*/private String prefix;/*** 功能描述*/private String function;/*** 列名*/private String columnName;/*** 实体列名*/private String entityColumnName;/*** 列描述*/private String columnComment;/*** 类型*/private String dataType;/*** 自增*/private Object columnExtra;/*** 长度*/private Object columnLength;private List<AppGen> list;}
获取表列表:@Override@Transactional(readOnly = true)public Result list(AppGen gen){String countSql = "SELECT COUNT(*) FROM information_schema.tables ";countSql +="WHERE table_schema='tools'";Long totalCount = dynamicQuery.nativeQueryCount(countSql);PageBean<AppGen> data = https://www.isolves.com/it/cxkf/jiagou/2020-07-16/new PageBean<>();if(totalCount>0){String nativeSql = "SELECT table_name as tableName,table_comment as tableComment ";nativeSql+="FROM information_schema.tables WHERE table_schema='tools'";Pageable pageable = PageRequest.of(gen.getPageNo(),gen.getPageSize());List list = dynamicQuery.nativeQueryPagingListModel(AppGen.class,pageable, nativeSql);data = new PageBean<>(list, totalCount);}return Result.ok(data);}
文章插图
制作模板模板太多了,这里只以Controller模板为例,贴一下实现代码,更多模板见源码:
package com.tools.module.${prefix}.web;import com.tools.common.config.AbstractController;import com.tools.common.model.Result;import com.tools.module.${prefix}.entity.${entityName};import com.tools.module.${prefix}.service.${entityName}Service;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.web.bind.annotation.PostMapping;import org.springframework.web.bind.annotation.RequestBody;import org.springframework.web.bind.annotation.RequestMapping;import org.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/${prefix}/${function}")public class ${entityName}Controller extends AbstractController {@Autowiredprivate ${entityName}Service ${function}Service;/*** 列表*/@PostMapping("/list")public Result list(${entityName} ${function}){return ${function}Service.list(${function});}/*** 查询*/@PostMapping("/get")public Result get(Long id){return ${function}Service.get(id);}/*** 保存*/@PostMapping("/save")public Result save(@RequestBody ${entityName} ${function}){return ${function}Service.save(${function});}/*** 删除*/@PostMapping("/delete")public Result delete(Long id){return ${function}Service.delete(id);}}
说白了其实就是传递参数,把一些可变的代码片段使用${name}形式编写 。代码生成
有点长,慢慢看,其实就是渲染各种前后端模板:
【SpringBoot代码生成器,让你释放双手,从此不用手撸代码】
/** * 生成代码 * @param gen * @return * @throws IOException * @throws TemplateException */@PostMapping("/create")public Result create(@RequestBody AppGen gen) throws IOException, TemplateException {/*** 获取表字段以及注释*/List<AppGen> list = genService.getByTable(gen);String name = gen.getTableName();String[] table =StringUtils.split(name,"_");gen.setPrefix(table[0]);gen.setFunction(table[1]);gen.setEntityName(GenUtils.allInitialCapital(gen.getTableName()));list.stream().forEach(column-> {column.setEntityColumnName(GenUtils.secInitialCapital(column.getColumnName()));});gen.setList(list);String baseFile = filePath+ SystemConstant.SF_FILE_SEPARATOR+"com"+SystemConstant.SF_FILE_SEPARATOR+ "tools"+SystemConstant.SF_FILE_SEPARATOR+ "module"+SystemConstant.SF_FILE_SEPARATOR+ gen.getPrefix()+SystemConstant.SF_FILE_SEPARATOR;/*** 后端代码*/File entityFile = FileUtil.touch(baseFile+"entity"+SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+".JAVA");File repositoryFile = FileUtil.touch(baseFile+"repository"+SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+"Repository.java");File serviceFile = FileUtil.touch(baseFile+"service"+SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+"Service.java");File serviceImplFile = FileUtil.touch(baseFile+"service"+SystemConstant.SF_FILE_SEPARATOR+"impl"+SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+"ServiceImpl.java");File controllerFile = FileUtil.touch(baseFile+"web"+SystemConstant.SF_FILE_SEPARATOR + gen.getEntityName() + "Controller.java");/*** 前端代码*/String htmlPath =filePath+SystemConstant.SF_FILE_SEPARATOR + "templates"+SystemConstant.SF_FILE_SEPARATOR + gen.getPrefix()+SystemConstant.SF_FILE_SEPARATOR + gen.getFunction()+SystemConstant.SF_FILE_SEPARATOR;File listFile = FileUtil.touch(htmlPath + "list.html");File formFile = FileUtil.touch(htmlPath + "form.html");/*** 生成静态页面*/Template template = configuration.getTemplate("html/list.ftl");String text = FreeMarkerTemplateUtils.processTemplateIntoString(template, gen);FileUtil.writeString(text,listFile,"UTF-8");template = configuration.getTemplate("html/form.ftl");text = FreeMarkerTemplateUtils.processTemplateIntoString(template, gen);FileUtil.writeString(text,formFile,"UTF-8");/*** 生成后端代码 repository*/template = configuration.getTemplate("java/repository.ftl");text = FreeMarkerTemplateUtils.processTemplateIntoString(template, gen);FileUtil.writeString(text,repositoryFile,"UTF-8");/*** 生成后端代码 entity*/template = configuration.getTemplate("java/entity.ftl");text = FreeMarkerTemplateUtils.processTemplateIntoString(template, gen);FileUtil.writeString(text,entityFile,"UTF-8");/*** 生成后端代码 service*/template = configuration.getTemplate("java/service.ftl");text = FreeMarkerTemplateUtils.processTemplateIntoString(template, gen);FileUtil.writeString(text,serviceFile,"UTF-8");/*** 生成后端代码 service 实现*/template = configuration.getTemplate("java/serviceImpl.ftl");text = FreeMarkerTemplateUtils.processTemplateIntoString(template, gen);FileUtil.writeString(text,serviceImplFile,"UTF-8");/*** 生成后端代码 controller 实现*/template = configuration.getTemplate("java/controller.ftl");text = FreeMarkerTemplateUtils.processTemplateIntoString(template, gen);FileUtil.writeString(text,controllerFile,"UTF-8");return Result.ok();}
推荐阅读
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 生意参谋标准版可以查词吗
- |20岁之后,你就要开始面对真正的人生了!
- 懂过vs磨烈,懂过古茶山
- 一见钟情时的生理反应
- 冬季养生喝什么茶好?
- 英国|一生共被人钓起63次的鲤鱼,死后登上报纸,被誉为“人民的鱼”
- 试用期转正失败,会影响应届生身份吗?
- 女人冬季怎样养生?中医师这样说
- 春季养生喝茶6大好处,春季排毒养颜
- 网上做生意怎么做 在网上怎么做生意