当前位置: 首页 > 科技观察

SpringBoot代码生成器,让你释放双手,从此不用手撸代码

时间:2023-03-13 18:56:10 科技观察

SpringBoot代码生成器让你解放双手,页面从此不再需要手写代码。如果开发前没有强制约束,每个程序员都有自己的编码习惯,最终会导致一个项目呈现出多种编码风格。然后是一些CRUD列表功能,基本没什么挑战性,纯属辛苦,浪费时间。所以根据公司现有的框架,还是需要开发一个风格统一的代码生成器。技术选择开发框架:SpringBoot+JPA,考虑到会产生各种前后端代码文件,这里使用freemarker模板引擎制作相应的模板。实现思路获取表结构信息首先,我们定义一个实体类。为了方便使用,我们把表和字段信息放到一个类中:/***表和相关字段信息*/@DatapublicclassAppGeneextendsPageBeanimplementsSerializable{/***表名*/privateStringtableName;/***实体类名*/privateStringentityName;/***实体类名首字母小写*/privateStringlowerEntityName;/***表注释*/privateStringtableComment;/***表前缀*/privateStringprefix;/***功能描述*/privateStringfunction;/***列名*/privateStringcolumnName;/***实体列名*/privateStringentityColumnName;/***列描述*/privateStringcolumnComment;/***类型*/privateStringdataType;/***自增*/privateObjectcolumnExtra;/***length*/privateObjectcolumnLength;privateListlist;}获取表列表:@Override@Transactional(readOnly=true)publicResultlist(AppGengen){StringcountSql="SELECTCOUNT(*)FROMinformation_schema.tables";countSql+="WHEREtable_schema='tools'";LongtotalCount=dynamicQuery.nativeQueryCount(countSql);PageBeandata=newPageBean<>();if(totalCount>0){StringnativeSql="SELECTtable_nameastableName,table_commentastableComment";nativeSql+="FROMinformation_schema.tablesWHEREtable_schema='tools'";Pageablepageable=PageRequest.of(gen.getPageNo(),gen.getPageSize());Listlist=dynamicQuery.nativeQueryPagingListModel(AppGen.class,pageable,nativeSql);data=newPageBean<>(list,totalCount);}returnResult.ok(data);}模板太多了,这里只以Controller模板为例,贴上实现代码,更多看源码模板:packagecom.tools。module.${prefix}.web;importcom.tools.common.config.AbstractController;importcom.tools.common.model.Result;importcom.tools.module.${prefix}.entity.${entityName};importcom.tools.module.${prefix}.service.${entityName}服务;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.web.bind.annotation.PostMapping;importorg.springframework.web.bind.annotation。RequestBody;importorg.springframework.web.bind.annotation.RequestMapping;importorg.springframework.web.bind.annotation.RestController;@RestController@RequestMapping("/${prefix}/${function}")publicclass${entityName}ControllerextendsAbstractController{@Autowiredprivate${entityName}Service${function}Service;/***list*/@PostMapping("/list")publicResultlist(${entityName}${function}){return${function}Service.list(${function});}/***Query*/@PostMapping("/get")publicResultget(Longid){return${function}Service.get(id);}/***保存*/@PostMapping("/save")publicResultsave(@RequestBody${entityName}${function}){return${function}Service.save(${function});}/***delete*/@PostMapping("/delete")publicResultdelete(Longid){return${function}Service.delete(id);}}说白了其实就是传递参数,写一些${name}形式的变量代码片段代码生成有点长,看一下,其实就是在渲染各种前后端模板:/***generatecode*@paramgen*@return*@throwsIOException*@throwsTemplateException*/@PostMapping("/create")publicResultcreate(@RequestBodyAppGengen)throwsIOException,TemplateException{/***获取表字段和注释*/Listlist=genService.getByTable(gen);Stringname=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);StringbaseFile=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;/***后端代码*/FileentityFile=FileUtil.touch(baseFile+"entity"+SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+".java");FilerepositoryFile=FileUtil.touch(baseFile+"repository"+SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+"Repository.java");FileserviceFile=FileUtil.touch(baseFile+"service"+SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+"Service.java");FileserviceImplFile=FileUtil.touch(baseFile+"service"+SystemConstant.SF_FILE_SEPARATOR+"impl"+SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+"ServiceImpl.java");FilecontrollerFile=FileUtil.touch(baseFile+"web"+SystemConstant.SF_FILE_SEPARATOR+gen.getEntityName()+"Controller.java");/***前端代码*/StringhtmlPath=filePath+SystemConstant.SF_FILE_SEPARATOR+"templates"+SystemConstant.SF_FILE_SEPARATOR+gen.getPrefix()+SystemConstant.SF_FILE_SEPARATOR+gen.getFunction()+SystemConstant.SF_FILE_SEPARATOR;FilelistFile=FileUtil.touch(htmlPath+"list.html");FileformFile=FileUtil.touch(htmlPath+"form.html");/***生成静态页面*/Templatetemplate=configuration.getTemplate("html/list.ftl");Stringtext=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");/***生成后端代码服务实现*/template=configuration.getTemplate("java/serviceImpl.ftl");text=FreeMarkerTemplateUtils.processTemplateIntoString(template,gen);FileUtil.writeString(text,serviceImplFile,"UTF-8");/***生成后端代码控制器实现*/template=configuration.getTemplate("java/controller.ftl");text=FreeMarkerTemplateUtils.processTemplateIntoString(template,gen);FileUtil.writeString(text,controllerFile,"UTF-8");returnResult.ok();}生成逻辑还是很笨的,而且它后面会逐步优化,比如根据字段类型生成不同的form表单,可以自定义字段是否显示等。总结总的来说还是比较好用的。比起一些简单的列表功能,分分钟就能出效果,开发喝茶一分钟。一整天。当然,对于一些复杂的效果,还是自己一个一个实现比较好,但这并不影响生成器的实用性。源代码https://gitee.com/52itstyle/SPTools