如何编写自己的代码生成器(理论篇一)

article/2025/9/29 3:21:01

作者简介

一个很懒很懒的程序员


如何编写自己的代码生成器

我平常开发都会用到代码生成器,本文将介绍如何制作属于自己业务的代码生成工具

代码生成器的作用

一个新的需求开发涉及到的数据库表有可能有很多张,每个都需要去写增删改查后台管理页面有很多重复的工作并且浪费时间。
具体的作用大家在工作中也都使用过类似的代码生成工具就不在去详细的介绍了,主要有以下几个优点

  1. 代码风格统一,易维护
  2. 提高开发效率
  3. 降低bug率从而降低测试成本
  4. 无需浪费过多的精力在重复的工作上

代码生成器的原理

代码生成器原理其实非常简单,就是使用我们平常写的代码抽取出来一套模板,使用模板绑定数据生成我们需要的代码。


接下来一步步去实现一个我们经常用到前端增删改查的生成器

大家想下,没有页面代码生成工具我们是怎么做的?

  1. 首先是复制一个以前开发过的列表、新增页面将它复制过来
  2. 修改列表页面的标题、展示列、查询域
  3. 修改新增页面的表单信息,添加自己的字段
  4. 修改列表以及表单用到的增删改查接口
  5. 测试是否可用

有了工具一般我们是怎么做的?

  1. 运行工具
  2. 简单修改

如何制作生成工具

  1. 我们可以写个标准的页面来做我们的模板
  2. 将我们平常复制修改的地方修改为占位符
  3. 我们可以通过代码将数据(可以通过数据库、自定义等方式去获取)绑定到模板上生成一个新的页面

程序设计

涉及到几大块

  1. 制作模板
  2. 获取模板绑定的数据源
  3. 进行绑定
  4. 生成文件

代码实现

制作模板

原页面展示效果如下

源码

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css" /><script src="https://www.layuicdn.com/layui/layui.js"></script></head><body>         
<blockquote class="layui-elem-quote layui-text">
代码生成展示 
</blockquote><fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;"><legend>测试</legend>
</fieldset>
<form class="layui-form layui-form-pane" action=""><div class="layui-form-item"><label class="layui-form-label">输入框</label><div class="layui-input-inline"><input type="text" name="username" lay-verify="required" placeholder="请输入" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item"><div class="layui-inline"><label class="layui-form-label">日期</label><div class="layui-input-inline"><input type="text" name="date" id="date1" autocomplete="off" class="layui-input"></div></div></div><div class="layui-form-item"><label class="layui-form-label">单行选择框</label><div class="layui-input-inline"><select name="interest" lay-filter="aihao"><option value=""></option><option value="0">写作</option><option value="1" selected="">阅读</option><option value="2">游戏</option><option value="3">音乐</option><option value="4">旅行</option></select></div></div><div class="layui-form-item" pane=""><label class="layui-form-label">单选框</label><div class="layui-input-block"><input type="radio" name="sex" value="" title="" checked=""><input type="radio" name="sex" value="" title=""><input type="radio" name="sex" value="" title="禁用" disabled=""></div></div><div class="layui-form-item layui-form-text"><label class="layui-form-label">文本域</label><div class="layui-input-block"><textarea placeholder="请输入内容" class="layui-textarea"></textarea></div></div><div class="layui-form-item"><button class="layui-btn" lay-submit="" lay-filter="submit">提交</button></div>
</form>    
<script>
layui.use(['form', 'layedit', 'laydate', 'layer'], function(){var form = layui.form,layer = layui.layer,layedit = layui.layedit,laydate = layui.laydate;laydate.render({elem: '#date1'});//监听提交form.on('submit(submit)', function(data){layer.alert(JSON.stringify(data.field), {title: '最终的提交信息'})return false;});});
</script></body>
</html>

将可以数据绑定的地方使用占位符代替制作成模板

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css" /><script src="https://www.layuicdn.com/layui/layui.js"></script>
</head>
<body>
<blockquote class="layui-elem-quote layui-text">代码生成展示
</blockquote><fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;"><legend>${title}</legend>
</fieldset>
<form class="layui-form layui-form-pane" action="" style="margin: 20px;">${ui}<div class="layui-form-item"><button class="layui-btn" lay-submit="" lay-filter="submit">提交</button></div>
</form>
<script>layui.use(['form', 'layedit', 'laydate', 'layer'], function(){var form = layui.form,layer = layui.layer,layedit = layui.layedit,laydate = layui.laydate;${script}//监听提交form.on('submit(submit)', function(data){layer.alert(JSON.stringify(data.field), {title: '最终的提交信息'})return false;});});
</script>
</body>
</html>

可以看到已经把能通过代码动态填充的部分用占位符替代

数据源

生成代码用到的数据表对象

public class TableBO {//标题private String title;//名称private String name;//是否可以删除private Integer canDelete;//是否能新增private Integer canAdd;//是否可编辑private Integer canEdit;//是否可查询private Integer canQuery;//列private List<ColumnBO> columns;
}

表具体的字段

public class ColumnBO {//标题private String title;//名称private String name;//字段长度private Integer length;//ui组件private FormUiEnum ui;//组件值private String uiValue;//是否必填private boolean isRequired;//是否是主键private boolean isId;//java类型private String javaType;//是否能在页面新增private Boolean canAdd;
}
数据绑定

下面为表单的数据绑定

public class FormTemplateDataBind implements ITemplateDataBind {@Overridepublic String bindDataToString(TableBO tableBO) {//封装模板使用的数据HashMap<String, Object> bindData = new HashMap<>();bindData.put("title",tableBO.getTitle());//表单字段组件内容获取bindData.put("ui",new UiTemplateContentHandler().get(tableBO));//表单需要的js脚本获取bindData.put("script",new ScriptTemplateContentHandler().get(tableBO));//绑定模板(这里可以使用三方插件,如 freemarker,beetl等模板工具)String formTemplate = BeetlTemplateGenUtils.bindToString(bindData, "formTemplate.html");//输出return formTemplate;}
}

根据字段组件类型获取不同的组件内容。

public class UiTemplateContentHandler implements ITemplateContentHandler {@Overridepublic String get(TableBO tableBO) {StringBuilder stringBuilder = new StringBuilder();List<ColumnBO> columns = tableBO.getColumns();for (ColumnBO column : columns) {if(column.getCanAdd()==true){switch (column.getUi()){case INPUT:stringBuilder.append(new InputUiHtmlHandler().get(column));break;case DIC:break;case DATE:break;case FILE:break;case RADIO:break;case IMAGE:break;case SELECT:stringBuilder.append(new SelectUiHtmlHandler().get(column));break;case TEXTAREA:stringBuilder.append(new TextAreaUiHtmlHandler().get(column));break;case HTML:break;default:stringBuilder.append(new InputUiHtmlHandler().get(column));break;}}}return stringBuilder.toString();}
}

演示文本框组件内容获取

public class InputUiHtmlHandler implements IUiHtmlHandelr {@Overridepublic String get(ColumnBO columnBO) {String required = "";if(columnBO.isRequired()){required = "required";}return "  <div class=\"layui-form-item\">\n" +"    <label class=\"layui-form-label\">"+columnBO.getTitle()+"</label>\n" +"    <div class=\"layui-input-inline\">\n" +"      <input type=\"text\" name=\""+columnBO.getName()+"\" lay-verify=\""+required+"\" placeholder=\"请输入\" autocomplete=\"off\" class=\"layui-input\">\n" +"    </div>\n" +"  </div>\n";}
}
编写测试用例

代码生成数据来源测试是使用自己定义的数据而没有读取数据库,可以读取数据库,将数据库的信息映射到我们的对象中

public static void main(String[] args) {//相当于添加一个数据库表 如:短信模板配置表TableBO tableBO = new TableBO();tableBO.setTitle("短信模板配置");tableBO.setName("smsTemplate");tableBO.setCanDelete(0);tableBO.setCanAdd(1);tableBO.setCanEdit(0);tableBO.setCanQuery(1);//数据库表有哪些字段List<ColumnBO> columns = Lists.newArrayList();//模板名称字段ColumnBO columnBO = new ColumnBO();columnBO.setCanAdd(true);columnBO.setTitle("模板名称");columnBO.setName("templateName");columnBO.setLength(20);columnBO.setUi(FormUiEnum.INPUT);columnBO.setUiValue("");columnBO.setRequired(true);columnBO.setId(true);columnBO.setJavaType("String");//模板内容字段ColumnBO columnBO2 = new ColumnBO();columnBO2.setCanAdd(true);columnBO2.setTitle("模板内容");columnBO2.setName("templateContent");columnBO2.setLength(300);columnBO2.setUi(FormUiEnum.TEXTAREA);columnBO2.setUiValue("");columnBO2.setRequired(true);columnBO2.setId(true);columnBO2.setJavaType("String");//模板类型字段ColumnBO columnBO3 = new ColumnBO();columnBO3.setCanAdd(true);columnBO3.setTitle("模板类型");columnBO3.setName("templateType");columnBO3.setLength(20);columnBO3.setUi(FormUiEnum.SELECT);columnBO3.setUiValue("{\"1\":\"短信通知\",\"2\":\"验证码\"}");columnBO3.setRequired(true);columnBO3.setId(true);columnBO3.setJavaType("String");columns.add(columnBO);columns.add(columnBO2);columns.add(columnBO3);tableBO.setColumns(columns);//将数据与模板绑定输出新的内容ITemplateDataBind templateDataBind = new FormTemplateDataBind();String template = templateDataBind.bindDataToString(tableBO);System.out.printf(template);}

运行程序输出内容为:

<!DOCTYPE html>
<html><head><meta charset="utf-8" /><link rel="stylesheet" type="text/css" href="https://www.layuicdn.com/layui/css/layui.css" /><script src="https://www.layuicdn.com/layui/layui.js"></script>
</head>
<body>
<blockquote class="layui-elem-quote layui-text">代码生成展示
</blockquote><fieldset class="layui-elem-field layui-field-title" style="margin-top: 50px;"><legend>短信模板配置</legend>
</fieldset>
<form class="layui-form layui-form-pane" action="" style="margin: 20px;"><div class="layui-form-item"><label class="layui-form-label">模板名称</label><div class="layui-input-inline"><input type="text" name="templateName" lay-verify="required" placeholder="请输入" autocomplete="off" class="layui-input"></div></div><div class="layui-form-item layui-form-text"><label class="layui-form-label">模板内容</label><div class="layui-input-block"><textarea name="templateContent" placeholder="请输入内容" class="layui-textarea"></textarea></div></div><div class="layui-form-item"><label class="layui-form-label">单行选择框</label><div class="layui-input-inline"><select name="templateType" lay-filter="templateType"><option value=""></option><option value="1">短信通知</option><option value="2">验证码</option></select></div></div><div class="layui-form-item"><button class="layui-btn" lay-submit="" lay-filter="submit">提交</button></div>
</form>
<script>layui.use(['form', 'layedit', 'laydate', 'layer'], function(){var form = layui.form,layer = layui.layer,layedit = layui.layedit,laydate = layui.laydate;//监听提交form.on('submit(submit)', function(data){layer.alert(JSON.stringify(data.field), {title: '最终的提交信息'})return false;});});
</script>
</body>
</html> 

将输出内容打开之后可以看到如下图,页面生成成功


结语

这里只是演示了一个简单的思路,工欲善其事必先利其器,我们平常也会选择好的ide及ide插件来开发,但是遇到一些特殊需求我们可以思考下有没有更好的方式去实现。

源码已提交至github(https://github.com/lanrensoft-zhangqin/shiqiao-code-generate/tree/master)


http://chatgpt.dhexx.cn/article/pVXAUY7k.shtml

相关文章

简单代码生成工具

代码生成 我们做项目的时候&#xff0c;经常会碰到写一些基础的增删改查代码&#xff0c;所以就写了个代码生成的工具&#xff0c;可根据自己的需求编写相应的代码模板。 大致思路 查询表信息&#xff0c;通过字段类型映射出 java 类型&#xff0c;然后通过模板生成 java 文件…

自制代码生成器(上)

自制代码生成器原因&#xff1a; •Mybatis自带的自动生成代码&#xff0c;不能自定义&#xff0c;各种命名没法改&#xff0c;不能生成controller、service、jsp等页面 如何写代码生成器—模板引擎velocity Velocity-1.7.jar &#xff1a; 模板引擎 commons的2个jar包 &#…

Mybatis 代码生成器

MBG与Example GitHub - mybatis/generator: A code generator for MyBatis. 我们在项目中使用Mybatis的时候&#xff0c;针对需要操作的一张表&#xff0c;需要创建实体类、Mapper映射器、Mapper接口&#xff0c;里面又有很多的字段和方法的配置&#xff0c;这部分的工作是非常…

Java-代码生成器的实现

文章目录 前言一、概述二、手写代码1. 简要说明2. 代码编写3. 完整代码4. 测试效果 三、项目源码 前言 最近看了一个开源的项目&#xff0c;jfinal-layui&#xff0c;然后这个项目里面有一个 代码生成器 的功能 之前虽然有用过代码生成器&#xff0c;但是从来没有看过相关的源…

MyBatis-Plus代码生成器(新)使用

目录 一&#xff0c;MyBatis-Plus基本简介。 二&#xff0c;特性 三&#xff0c;实现代码自动生成工具 3.1&#xff0c;准备一个初始项目&#xff0c;数据表&#xff0c;连接好数据库 3.2&#xff0c;导入Mybatis-Plus相关依赖 3.3&#xff0c;配置数据库配置文件applicat…

快速上手若依代码生成器(2022)

文章目录 前言一、启动若依框架二、使用代码生成器1 导入示例表2 使用自带的代码生成 生成zip文件2.1 Illegal mix of collations报错解决 三 把zip文件的内容粘贴到对应的模块中3.1 粘贴后台代码3.2 粘贴前台代码3.3 运行菜单sql语句 四 重新启动前端后端总结 前言 快速上手使…

若依代码生成器的使用

一、代码生成器的使用 1.新建maven模块 原则上&#xff0c;我们的业务代码和若依系统本身的系统代码是要做隔离的&#xff0c;一方面是易于之后随着若依系统升级而升级&#xff0c;另一方面则是纯粹的合理性考虑。 这里新建一个ruoyi-business模块作为业务代码模块&#xff0c;…

Java代码生成器

项目说明 本项目基于是基于 renren-generator 定制的代码生成器 文章目录 **项目说明**不同点&#xff1a;效果原理分析如何定制开发&#xff1f;更多可能存在的坑代码地址 不同点&#xff1a; 因为本人的公司使用的是 tkmyabtis swagger 构建 rest api,而 renren-generator…

手把手带你实现一个代码生成器

前言 不知各位看官在工作之中有没有陷入过疯狂CV代码、看着密密麻麻的类不想动手&#xff0c;或者把大把的时间花费在底层的情况。以笔者为例&#xff0c;会经常遇到以下两个问题&#xff1a; 隔一段时间就需要构建一个新应用&#xff0c;需要各种复制粘贴&#xff08;缺乏定…

代码生成器 ----一个独立的代码生成器

这里我就没有过多发废话了&#xff0c;直接给正文。下面是代码生成器的一些简单介绍。操作简单没啥难度。 下面是生成器的地址&#xff0c;谢谢您的使用↓ 代码生成器点这儿。 一、基于简单的数据库属性连接 二、浏览器缓存连接历史 1、可以选择历史连接 2、可以清空所有浏…

如何自定义代码生成器(上)

1 概述 1.1 介绍 ​ 在项目开发过程中&#xff0c;有很多业务模块的代码是具有一定规律性的&#xff0c;例如controller控制器、service接口、service实现类、mapper接口、model实体类等等&#xff0c;这部分代码可以使用代码生成器生成&#xff0c;我们就可以将更多的时间放…

Java快速开发之代码生成器

1、代码生成器原理分析 观察我们之前写的代码&#xff0c;会发现其中也会有很多重复内容&#xff0c;比如: 那我们就想&#xff0c;如果我想做一个Book模块的开发&#xff0c;是不是只需要将红色部分的内容全部更换成Book即可&#xff0c;如&#xff1a; 所以我们会发现&#…

代码生成器

目录 引言 1 第一种 1.0 pom依赖 1.1 第一步&#xff1a;配置文件 1.2 第二步&#xff1a;代码生成器 1.3 执行生成 引言 代码生成器&#xff0c;遇到过也使用过很多了&#xff0c;用的时候觉得很简单&#xff0c;但是这个玩意不是开个新项目几乎很少碰到&#xff0c;所…

推荐几个代码自动生成器,神器!!!

20个代码生成框架 老的代码生成器的地址&#xff1a;https://www.cnblogs.com/skyme/archive/2011/12/22/2297592.html 以下是大家推荐的最近很火爆的代码生成器神器。如果有更好的希望大家多多留言&#xff0c;我会及时补充上去。 -------------------------更新补充------…

代码生成器AutoGenerator

简介&#xff1a;AutoGenerator 是 MyBatis-Plus 的代码生成器&#xff0c;通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码&#xff0c;极大的提升了开发效率。 简介 | MyBatis-Plus 一、如何使用&#xff1a; 1&#x…

代码生成器-mybatis-plus-generator

我们平时在开发的过程中&#xff0c;对于新建的一张表难免会有对其进行增删改查的操作&#xff0c;而且还要写Controller、service、Mapper、Mapper.xml、PO、VO等等。如果每次都要去写这些跟业务毫不相干但是却又耗时耗力的重复代码这不仅是让开发人员不能专注于业务逻辑甚至可…

HM2022ssm-mp5【MP代码生成器】

1. 代码生成器原理分析 1.1 造句: 我们可以往空白内容进行填词造句&#xff0c;比如: 在比如: 再有&#xff1a; 1.2 观察我们之前写的代码&#xff0c;会发现其中也会有很多重复内容&#xff0c;比如: 那我们就想&#xff0c;如果我想做一个Book模块的开发&#xff0c;是不是只…

MyBatis-Plus——代码生成器的使用

MyBatis-Plus——代码生成器的使用 AutoGenerator 是 MyBatis-Plus 的代码生成器&#xff0c;通过 AutoGenerator 可以快速生成 Entity、Mapper、Mapper XML、Service、Controller 等各个模块的代码&#xff0c;极大的提升了开发效率。 导入依赖 <dependency><groupI…

推荐几个代码自动生成器,神器

20个代码生成框架 老的代码生成器的地址&#xff1a;https://www.cnblogs.com/skyme/archive/2011/12/22/2297592.html 以下是大家推荐的最近很火爆的代码生成器神器。如果有更好的希望大家多多留言&#xff0c;我会及时补充上去。 2.0 WebFirst .NET Core代码生成器 全新的.…

Mybatis-Plus自动生成代码,自定义Controller

MP网址&#xff1a;https://baomidou.com/pages/779a6e/#%E4%BD%BF%E7%94%A8 直接copy官网代码修改成自己的&#xff1a; private void generate() {FastAutoGenerator.create("jdbc:mysql://localhost:3306/test?serverTimezoneGMT%2b8", "root", "…