前言

谈到软件开发,总是避不开管理系统的,只有是一个零碎总会附带 >=1 数据的后盾管理系统。而管理系统的风貌就是性能反复、量大、管饱。可看似性能类型,却总不是反复的
所以总是要将这些相似的性能一个一个一遍一遍的手动开发,就会耗费大量的工夫与人力。可是总是写这些反复没养分的页面,为人者总会心有不甘的。
所以就踊跃出一大批帝境强人,制作出各种一键生成增删改查性能的工具插件想来逆天改命。java 者的尤甚,而前端生成工具的略少,兴许是框架层出不穷缘故,我所知有若依之列。
而后试了一下的确能够,不过要一个一个生成而后解压复制到本地对应目录,当数据表数量达到半步百张之境还是让人头疼不已。不过却实节约了大量工夫与人力。
随之而来的是,事实上每个页面并不是纯增删改查之能,如:没有删除性能、没有查问行、某字段不能够编辑、A 数据依赖 B、操作列按状态展现、有审批性能等等。

思考

即便做为一条炼气境的小杂鱼,也还是想进一步思考如何去更好的解决此列问题。所以我在想,如果给我一个数据库(或创立库的 sql 构造)如何能最快实现我的需要的计划。

想法

没错,还是应用前后拆散生成计划,因为支流。
服务端思路
陈词滥调,没什么特地新鲜的办法。读取表构造生成对应 PO、VO、service、controller 等等。办法就是先创立几个模板(动态文本原样输入、能够传入变量输出不定文本),
而后按需将表构造解析传入模板,生成文件到对应目录,到也不难。这里咱们为了不便,不必去生成 sql 就用 mybatis-plus, 如咱们的 controller 模板:

package ${package};import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;import com.baomidou.mybatisplus.extension.plugins.pagination.Page;import org.springframework.beans.BeanUtils;import org.springframework.beans.factory.annotation.Autowired;import org.springframework.boot.autoconfigure.EnableAutoConfiguration;import org.springframework.transaction.annotation.Propagation;import org.springframework.transaction.annotation.Transactional;import org.springframework.web.bind.annotation.*;import java.util.List;import ${impPo};import ${impVo};import ${impService};@EnableAutoConfiguration@RestController@RequestMapping(value="/${strutil.toLowerCase(entityName)}")public class ${entityName}Controller {    @Autowired    private ${entityName}Service ${varName}Service;    /**     *${tableComment}增加     **/    @RequestMapping(value="/save", method=RequestMethod.POST)    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)    public Object save${entityName}(            @RequestBody ${entityName}${poSuffix} ${varName}) {        return ${varName}Service.save(${varName});    }    /**     *${tableComment}批改     **/    @RequestMapping(value="/update", method=RequestMethod.POST)    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)    public Object update${entityName}(            @RequestBody ${entityName}${poSuffix} ${varName}) {        return ${varName}Service.updateById(${varName});    }    /**     *${tableComment}增加或批改      **/    @RequestMapping(value="/saveOrUpdate", method=RequestMethod.POST)    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)    public Object saveOrUpdate${entityName}(            @RequestBody ${entityName}${poSuffix} ${varName}) {        return ${varName}Service.saveOrUpdate(${varName});    }    /**     *${tableComment}查找     **/    @RequestMapping(value="/search", method = RequestMethod.POST)    public Object search${entityName}(@RequestBody ${entityName}${voSuffix} params) {        ${entityName}${poSuffix} ${varName}${poSuffix} = new ${entityName}${poSuffix}();        BeanUtils.copyProperties(params, ${varName}${poSuffix});        Page<${entityName}${poSuffix}> page = new Page<>(params.getPageNo(), params.getPageSize());        QueryWrapper<${entityName}${poSuffix}> queryWrapper = new QueryWrapper<>(${varName}${poSuffix});        return ${varName}Service.page(page, queryWrapper);    }        /**     *${tableComment}通过id删除     **/    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)    @RequestMapping(value="/removeById/{id}", method=RequestMethod.POST)    public Object remove${entityName}ById(@PathVariable Integer id) {        return ${varName}Service.removeById(id);    }    /**     *${tableComment}删除     **/    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)    @RequestMapping(value="/remove", method=RequestMethod.POST)    public Object remove${entityName}(@RequestBody ${entityName}${poSuffix} ${varName}) {        return ${varName}Service.remove(new QueryWrapper<>(${varName}));    }    /**     *${tableComment}删除多条     **/    @Transactional(propagation = Propagation.REQUIRED, rollbackFor = Throwable.class)    @RequestMapping(value="/removeByIds", method=RequestMethod.POST)    public Object remove${entityName}ByIds(@RequestBody List<Integer> ids) {        return ${varName}Service.removeByIds(ids);    }}

能够看到办法名,门路等都能够在模板里批改。启动我的项目裸露办法调用就可能生成根本了性能了,那么后端简略的增删改查性能接口就好了

前端思路

此处咱们应用 react 加 antd 格调的吧,当然应用vue + 饿了摸滴呀也一样喽。读取表构造中的字段名做为名,数据类型来对应组件,是否为空为校验条件等。
按下面思路,诶定义模版,动静解决变动局部一哈子如同也就能生成进去了,但问题来了,我想要的是还能在生成的性能上以可视化去解决不要的字段,不对的组件、等其它的性能。
那么这样的话后续我就不好搞不定了。所以只能另寻它路,起初我将数据库的构造先解析成一个形容对象(JSON)在页面中对这个对象进行解析为设计构造并能够按理论运行预览,那么
我再批改设计构造不就能够批改形容对象了么,而后再将形容对象生成理论的代码是不是就能够实现我的需要了呢(代码生成 + 可视化编辑,或者也叫 LOWCODE 吧)

//如 JSON[    {         type: 'search',        children: [            { type: 'input', name: 'userName', label: '用户名' }            { type: 'button', value: '查问' }        ]    },    {        type: 'region',        children: [            { type: 'button', value: '增加' }            { type: 'button', value: '批量删除' }        ]    },    {        type: 'table',        children: {            { type: 'text', name: 'userName', label: '用户名' },            [                { type: 'button', value: '编辑' },                { type: 'button', value: '删除' }                { type: 'space' }            ]        }    }    ...]

如上,先将数据库构造生成如上构造页面再以拖拽形式操作构造达到目标后点击再生成 React 代码:

    return (<div>        <Form inline>            <Form.Item name="userName" label="用户名">                <Input />            <Form.Item>            <Form.Item>                <Button>查问</Button>            <Form.Item>        </Form>        ...    </div>)

问题

然而服务端还是没想到好的计划能够主动生成定制化的性能,如果只是对数据的批改是很简略,可如果须要计算则没有好的实现办法(比方传到服务端数据要 + B表的某个字段值再入库等)。

路漫漫其修远兮,还须要持续摸索

应用

抛砖引玉,看看设计的试验成绩

筹备好一个数据库,如先从一个简略的两页面开始,如下:

```sql/*Navicat Premium Data TransferSource Server         : localhost_3306Source Server Type    : MySQLSource Server Version : 50743Source Host           : localhost:3306Source Schema         : student_gradeTarget Server Type    : MySQLTarget Server Version : 50743File Encoding         : 65001Date: 25/08/2023 16:12:20*/SET NAMES utf8mb4;SET FOREIGN_KEY_CHECKS = 0;-- ------------------------------ Table structure for grade-- ----------------------------DROP TABLE IF EXISTS `grade`;CREATE TABLE `grade`  (`grade_id` int(11) NOT NULL AUTO_INCREMENT,`student_id` int(11) NULL DEFAULT NULL,`grade_name` varchar(64) CHARACTER SET utf8 COLLATE utf8_bin NULL DEFAULT NULL COMMENT '考试名称',`grade_chinese` float NULL DEFAULT NULL COMMENT '语文问题',`grade_math` float NULL DEFAULT NULL COMMENT '数学问题',`grade_english` float NULL DEFAULT NULL COMMENT '英文问题',`created_at` datetime NULL DEFAULT CURRENT_TIMESTAMP,`deleted` tinyint(2) NULL DEFAULT 0,PRIMARY KEY (`grade_id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '问题治理' ROW_FORMAT = Dynamic;-- ------------------------------ Table structure for student-- ----------------------------DROP TABLE IF EXISTS `student`;CREATE TABLE `student`  (`student_id` int(11) NOT NULL AUTO_INCREMENT COMMENT '主键',`student_name` varchar(11) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '学生姓名',`student_no` varchar(11) CHARACTER SET utf8 COLLATE utf8_bin NOT NULL COMMENT '学号',`student_in_time` datetime NOT NULL COMMENT '退学日期',`created_at` datetime NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '创立日期',`deleted` tinyint(1) NULL DEFAULT 0 COMMENT '逻辑删除',PRIMARY KEY (`student_id`) USING BTREE) ENGINE = InnoDB AUTO_INCREMENT = 1 CHARACTER SET = utf8 COLLATE = utf8_bin COMMENT = '学生治理' ROW_FORMAT = Dynamic;SET FOREIGN_KEY_CHECKS = 1;```

配置连贯到数据库并启动服务端我的项目后,关上代码生成页面,点击生成:

看一下我的项目中曾经生成了基本功能的代码

后端生成实现,咱们再来操作下前端,连贯或导入数据库构造 sql 再配置下接口门路等信息

生成后页面预览,基本功能都没有问题了,发现所以页面的基本功能只有测试一次

增加自定义的性能

应用视频

地址

服务端代码生成 github 地址
前端代码生成 gitee 地址
前端代码生成线上间接应用地址