本文介绍代码生成器的使用方法
代码生成器的基本原理是,开发人员根据业务编写实体类(Entity),然后执行代码生成逻辑,系统将解析实体类字段,并由此生成Dao、Service接口、Service实现类、Controller控制器、增删改查前端代码、前端路由及接口配置、实体类建表sql和相关菜单、功能、API的sql记录。
比如开发人员现在需要做一个客户管理功能,客户信息里包含姓名、年龄、两个字段。那么我们就需要写一个符合规范的实体类,该类放于com.spz.demo.singleboot.entity包下
当实体类较多时,开发人员可能需要对众多实体类进行分类,比如系统有关的实体类均放到com.spz.demo.singleboot.entity.system包下; 测试有关的放在com.spz.demo.singleboot.entity.test包下; 也有部分实体类直接放com.spz.demo.singleboot.entity目录下,不需要按目录隔开存。代码生成器遇到非entity包下的实体类时,将会在生成目标代码文件时也进行包分隔。例如Book实体类,存放于com.spz.demo.singleboot.entity.file包下,则生成的控制器类则会放在com.spz.demo.singleboot.controller.file包下,并且该类的RequestMapping根路径为"/file"
现在以客户实体类(Customer.java)和书本实体类(Book.java)为例演示代码生成器的使用方法
代码生成器相关配置
在application.properties文件中配置,该配置文件运行于local环境。建议只配置generate.project.rootPath和generate.out.path这两项,其他的建议不要修改
# 代码生成器配置
# 【需要配置】项目根路径(绝对路径),简单地说就是项目拉下来是一个目录,这里配置的就是拉下来目录的绝对路径
generate.project.rootPath=C:/Users/spz/WORK/ME_PRO/single-java-demo
# 【需要配置】前端代码、sql语句文件输出路径(绝对路径)
generate.out.path=C:/Users/spz/WORK/ME_PRO/single-java-demo/generate/
# 作者
generate.doc.author=spzmmd
# 注释时间
generate.doc.date=2021/02/01
# 项目根包路径(建议不要修改)
generate.project.package=com.spz.demo.singleboot
# 实体类存放包路径(建议不要修改)
generate.scan.package=entity
# 实体类Bean代码生成存放包相对路径
generate.out.package.bean=bean
# 控制器代码生成存放包相对路径
generate.out.package.controller=controller
# mapper接口代码生成存放包相对路径
generate.out.package.dao=dao
# Service接口代码生成存放包相对路径
generate.out.package.service=service
# Service实现类代码生成存放包相对路径
generate.out.package.serviceimpl=serviceimpl
编写实体类Entity
- Customer.java客户实体类,存放于entity根包下(com.spz.demo.singleboot.entity)
package com.spz.demo.singleboot.entity;
import com.baomidou.mybatisplus.annotation.TableName;
import com.spz.demo.singleboot.core.annotation.EntityDoc;
import com.spz.demo.singleboot.core.entity.BasicEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 顾客实体类
* 用于代码生成器测试
* @author spzmmd
* @date 2019/05/15
*/
@EntityDoc(isClass = true, note = "顾客")
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("biz_customer")
public class Customer extends BasicEntity {
/**
* 姓名
*/
@EntityDoc(note = "姓名")
private String name;
/**
* 年龄
*/
@EntityDoc(note = "年龄")
private Integer age;
}
- Book.java 书本实体类,存放于entity包下的file包下(com.spz.demo.singleboot.entity.file)
package com.spz.demo.singleboot.entity.file;
import com.baomidou.mybatisplus.annotation.TableName;
import com.spz.demo.singleboot.core.annotation.EntityDoc;
import com.spz.demo.singleboot.core.entity.BasicEntity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* 书籍实体类
* 用于代码生成器测试
* @author spzmmd
* @date 2019/05/15
*/
@EntityDoc(isClass = true, note = "书籍")
@Data
@NoArgsConstructor
@AllArgsConstructor
@TableName("biz_book")
public class Book extends BasicEntity {
/**
* 名称
*/
@EntityDoc(note = "名称")
private String name;
/**
* 作者
*/
@EntityDoc(note = "作者")
private String author;
}
-
客户类和书籍类在包中的位置如图
-
编写实体类时必须遵守下列规范
- 实体类上必须声明如下注解
// 代码生成器需要从此注解的note字段得知该类名称注释,注意该字段在类上声明时,需要注明isClass为true
@EntityDoc(isClass = true, note = "顾客")
// Lombok注解,用于自动生成get、set方法及相关构造器
@Data
@NoArgsConstructor
@AllArgsConstructor
// Mybatis注解,用于声明实体类对应的数据库表名称
// 【!】数据库表名不要使用 sys_ 前缀,这是系统自带数据表的前缀,在生成sql时系统会自动跳过表面带有该前缀的实体类
@TableName("biz_customer")
-
实体类必须继承 com.spz.demo.singleboot.core.entity.BasicEntity 类
BasicEntity类包含了主键字段(code)、数据有效字段、记录创建时间字段、记录修改时间字段,开发人员建立新实体类时无需再声明。BasicEntity类字段如下图:(关于系统自动设置创建时间、修改时间和数据有效字段的逻辑请看此类:com.spz.demo.singleboot.core.config.MybatisPlusMetaObjectHandler) -
实体类字段上必须声明@EntityDoc(note = "xxx")注解,并设置其note为字段注释名称
代码生成器需要读取EntityDoc注解里的note字段来获得字段的注释名称,用于前端输入框显示等场景 -
实体类里基本类型的字段,必须使用包装类型,如int,请换成Integer
-
实体类存放示例
生成代码
代码生成器执行示例在com.spz.demo.singleboot.CodeGenerateTest下,可直接运行。如下图:
实体类编写完成后,即可运行代码生成器生成代码(生成过程中会输出日志供查看生成情况);代码生成后,在相关目录下可看见生成的代码:
-
Bean 类
Bean类用于控制层展示/参数传递,Service层将数据查询出来以后,需要赋值给对应Bean类返回给Controller层。此外,Bean类除了包含实体类字段,还包含了BasicEntity里的所有字段(code、valid等);
并包含了唯一标识集合字段,用于类似"根据id集合查询/删除的业务场景" -
Controller 类
每个实体类对应一个控制器类,生成的控制器接口包含如下方法: -
Dao 类
实际为Mybatis-Plus的Mapper接口类 -
Service接口及其实现类
内部封装了一套增删改查接口
下图为Service实现类里包含的方法,注意createWrapper()方法,建议整个Service实现类里,所有涉及查询的方法均调用createWrapper()方法返回的LambdaQueryWrapper对象来参与查询,而所有查询条件均在createWrapper()方法里编写(注:LambdaQueryWrapper为Mybatis-plus提供的Lambda方式查询) -
前端页面、前端配置及SQL建表语句
实体类sql建表
使用generate/sql目录下的tableSqlList.sql文件进行建表(注意前提是使用doc/sql目录下的sql文件初始化过了数据库)
配置前端
-
使用开发工具(如WebStorm)打开前端项目single-demo-admin,如果没有可去此处下载single-demo-admin,打开后目录如下:
-
事先进行代码生成操作后,后台项目根目录下的generate目录将生成html和htmlConfig目录,如下图:
-
拷贝前端代码,将"后台项目根目录/generate/html/"下的所有文件均拷贝至"前端项目根目录/src/views/"目录下,该目录存放前端页面代码
-
打开"前端项目根目录/src/config/api.js"以及"后端项目根目录/generate/htmlConfig/htmlConfig.js",将api相关的配置复制到api.js
-
打开"前端项目根目录/src/config/router.js"以及"后端项目根目录/generate/htmlConfig/htmlConfig.js",将路由相关的配置复制到router.js
运行项目并配置菜单
运行项目后,还需要对当前角色配置有权限的菜单和功能,才能使用到代码生成器生成的顾客管理和书籍管理功能
-
分别启动前端和后端项目运行(运行方法请查看之前的文章),访问页面(http://localhost:8080)并输入账号密码验证码登录(账号zhangsan,密码:123):
-
配置角色菜单映射
选择书籍管理、顾客管理,然后确定 -
配置角色功能映射
选择相应的功能,然后确定 -
配置完后,重新登录系统
这里菜单icon是默认的,需要更改则去"系统设置-菜单管理"里修改,同时该处也可以修改菜单的排序,代码生成器默认给新菜单都设置为900顺序 -
基本的增删改查均具备
-
列表页面新增查询字段
注意生成的页面里是没有具体字段的查询的,需要开发人员自行添加,比如需要给书籍管理页面添加按书籍名称查询的字段,则打开"前端项目根目录/src/views/book/List.vue",在下图红框出编写字段:
在后端项目里,也需要增加查询条件,如图: