EasyCode:IDEA代码生成插件,带你告别手写CRUD
2026/9/17 19:25:20 网站建设 项目流程

写代码这几年,最烦的一件事就是写重复的 CRUD 代码。每次新建一张表,都要手写一个 entity、一个 dao、一个 service、一个 controller,还要配一个 XML mapper。字段一多,光是 getter/setter 就够磨半天的。后来我在 IDEA 里接触到了 EasyCode 这个插件,才算从这种机械劳动里解脱出来——选中一张表,右键一下,entity、controller、service、dao、mapper 全套代码自动生成,还能顺便把 MyBatis 的 XML 映射文件也补上,基本就是秒出。这篇博文我就把 EasyCode 的完整用法、模板定制思路、以及我自己踩过的坑整理出来,希望对你也有用。

EasyCode 本质上就是一个基于 IDEA 的代码生成插件,它依托数据库的表结构来生成代码,不挑框架偏好,默认生成的是 Spring Boot 风格的 MVC 分层代码。适合谁用?其实只要你平时用 IDEA + MySQL(或者其他关系型数据库)+ MyBatis/MyBatis Plus 这一套,写后台管理端接口,都值得装一个。用了它之后,再也不用对着空文件敲 deleteById 这种千篇一律的方法了。

1. EasyCode 插件能解决什么问题

1.1 手写 CRUD 代码的重复劳动困境

后端开发里,CRUD 接口是最高频、也最没有技术含量的部分。你新建一张业务表,就要配套写实体类、Mapper 接口、Mapper XML、Service 接口、ServiceImpl 实现类、Controller,每个接口基本就是增删改查加一个分页。拿最典型的用户表来说,光一个分页查询,你就要在主配置文件、SQL 映射、Service 实现三个地方来回切换,还要小心参数对不上、字段拼错,调试起来特别浪费时间。

我见过不少项目组,这种基础代码都是靠老员工复制粘贴改改表名,遇到字段多的表,复制粘贴也容易漏改。EasyCode 的思路就是:你自己把这些代码的"模板"定义好,以后数据库里加几张表,它就按模板批量生成,一次性把所有层级的代码都补齐。这套思路解决的不只是效率问题,还有规范性问题——模板统一了,大家生成的代码风格一致,再也不会出现张三写的 Controller 返回 String、李四写的返回自定义对象这种情况。

1.2 EasyCode 的工作机制

EasyCode 的原理其实不复杂,它相当于内置了一个模板引擎,用户在 IDEA 里配置好数据库连接,选择某张表之后,插件读取表名、字段名、字段类型、注释等信息,然后套用每一项对应的模板,渲染输出成完整的 Java 文件和其他资源文件。

它用的模板引擎是 Velocity,语法比较老但胜在简单——在模板文件里写$tableInfo.name$columnInfo.comment这类占位符,生成时插件会填充具体值。对于没接触过模板引擎的人来说,也不用有压力,因为它默认提供的模板已经能直接用了。你需要定制的时候,只要照着官方模板改一改变量和循环结构就行,改动成本很低。

EasyCode 还有一个很实用的搭档,叫 Free MyBatis Plugin,它俩通常搭配使用。EasyCode 负责生成 Mapper 接口和 XML,Free MyBatis Plugin 负责在接口方法和 XML 节点之间快速跳转。两个插件配合,开发体验非常顺滑。

1.3 和其他代码生成方案的对比

我早期也用过 MyBatis Generator(MBG),但说实话,MBG 的配置太折腾了。要先写一个generatorConfig.xml,配数据库驱动、配目标包名、配表名,运行完后再把生成的文件复制进项目里,路径设置不好还会覆盖旧文件。后来用 EasyCode,直接在 IDEA 数据库面板右键点一下,省了太多配置成本。

MyBatis Code Helper 也是常见的辅助插件,但它的定位偏向于编写辅助——比如在 XML 里提示 SQL 字段、生成简单的 insert/update 语句,并不会像 EasyCode 这样成套生成完整分层代码。如果你需要的不只是提示,而是整个项目的初始代码,EasyCode 会更合适。

自研代码生成器我也试过,用 Java 代码连接数据库、取元数据、拼字符串输出文件,灵活度高但每次新项目换框架都要改一遍,维护成本远高于在 IDEA 里改模板。EasyCode 的模板改动是即时生效的,不需要重新编译、重启服务,这点对日常开发来说太友好了。

2. EasyCode 安装与数据库连接配置

2.1 安装插件:二选一即可

安装路径有两个。第一个是在 IDEA 里打开File -> Settings -> Plugins,在 Marketplace 搜索框中输入 "EasyCode",找到由makejava开发的插件,直接 Install 后重启 IDEA。第二个是去 JetBrains 插件官网下载安装包,然后在 IDEA 里选择Install Plugin from Disk手动安装,这种方式适合公司内网无法访问插件市场的情况。

提示:EasyCode 在较新的 IDEA 版本里也兼容得很好,不过如果你的 IDEA 版本过于老旧,比如 2020 年以前的版本,建议先在它的插件描述页核实一下兼容性。出现安装失败的情况,多半是 IDEA 版本太旧、插件要求的依赖不满足导致的。

安装完毕后,在 IDAE 右侧或者工具栏区域会出现 EasyCode 的专属窗口,里面会展示当前数据库连接中的表列表。如果没出来,重启一下 IDEA 一般就能看到。

2.2 配置数据库连接

要生成代码,前提是 IDEA 能连上你的数据库。打开 IDEA 右侧的 Database 面板,点击左上角的+号,选择 Data Source 下对应的数据库类型,我这里以 MySQL 为例。

填写数据库连接信息时,Host、Port、User、Password 这些不多说,Database 那里可以填你的业务库名,填了之后下方的 Schema 会自动带出来。连接测试通过后,点 OK 保存。

这时候有个细节容易踩坑:如果你的项目里用的是 MySQL 8.0+ 版本,注意驱动选择上要用mysql-connector-j对应的驱动版本,IDEA 自带的驱动表里通常能直接选到,但如果没有,就需要手动添加驱动 jar 包。连接失败时先看报错信息,常见的Public Key Retrieval is not allowed错误,通常需要在连接 URL 上加上allowPublicKeyRetrieval=true参数;The server time zone value错误则要加serverTimezone=Asia/Shanghai

数据库连接配好之后,展开库名,就能看到所有表了。需要注意的是,这里显示的表是你在 Database 面板里实际连的那台数据库服务器上的,不是项目配置文件里配的那个虚拟数据源。每次生成前,先确认当前选中的表属于哪个库,别选错库,不然生成出来的包名和数据源都对不上。

3. 核心实操:用 EasyCode 一键生成全套代码

3.1 准备一张测试表

为了让整个流程清晰可见,我们先建一张结构稍微复杂一点的表,包含常见的主键、业务字段、时间字段和逻辑删除字段。

CREATE TABLE `sys_user` ( `id` bigint(20) NOT NULL AUTO_INCREMENT COMMENT '主键ID', `username` varchar(50) NOT NULL COMMENT '用户名', `password` varchar(128) NOT NULL COMMENT '密码', `nickname` varchar(50) DEFAULT NULL COMMENT '昵称', `email` varchar(100) DEFAULT NULL COMMENT '邮箱', `phone` varchar(20) DEFAULT NULL COMMENT '手机号', `status` tinyint(4) DEFAULT '1' COMMENT '状态:1启用,0禁用', `create_time` datetime DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', `update_time` datetime DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', `deleted` tinyint(4) DEFAULT '0' COMMENT '逻辑删除:1已删除,0未删除', PRIMARY KEY (`id`) ) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=utf8mb4 COMMENT='系统用户表';

建好表之后,在 Database 面板里刷新一下,让 IDEA 识别到新表。

3.2 右键生成,选择生成内容

在表名上右键,选择EasyCode -> Generate Code。这时候会弹出生成配置窗口,界面分布大概是:左边是已选定的表,中间是这表包含的字段列表,右边是我们要勾选生成的模板项,默认会勾选EasyEntityEasyDaoEasyServiceEasyServiceImplEasyControllerEasyMapper.xml这些。

包名路径那里,IDEA 一般会自动识别当前打开的项目里的源码目录,你可以手动修改生成的根包名,比如com.example.demo。这块一定要看仔细,如果包名填错,生成出来后整个目录结构都是错的,再想调整工程浩大。我的习惯是先生成到一个临时目录里,检查无误后再拷入正式工程源码目录,这样最稳妥。

点击 OK 后,看 IDEA 右下角的进度条,几秒内所有文件就生成完了。

3.3 生成后的代码结构拆解

生成完之后,我们逐个看下 EasyCode 默认给我们造出了什么。

实体类SysUser.java:它默认生成的实体里包含了每个字段的私有属性、对应 getter/setter 方法,类上会有@Data之类的注解吗?其实不会,默认模板是纯 JavaBean 风格,没有多余的注解。如果你项目中用了 Lombok,后面我们可以通过改模板把@Data加进去。

DAO 层SysUserDao.java:这是一个 MyBatis 的 Mapper 接口,里面定义了selectByPrimaryKeyinsertinsertSelectiveupdateByPrimaryKeySelectivedeleteByPrimaryKey等基础方法,这些方法名要与 XML 里的 id 一一对应。

Service 层SysUserService.javaSysUserServiceImpl.java:Service 接口定义了insertupdatedeleteByIdqueryByIdqueryAllByLimit这些方法。实现类里面直接把 DAO 的方法包装了一下,加了个@Service注解,事务注解是加在方法上的。

Controller 层SysUserController.java:这个类里有@RestController@RequestMapping("sysUser"),方法上也有对应的@GetMapping/@PostMapping,返回的是 JSON 数据。

Mapper XMLSysUserMapper.xml:这是 MyBatis 的映射文件,里面包含了ResultMapBase_Column_List、各种 SQL 语句。生成的 SQL 是比较通用的标准 SQL,字段、表名、参数都是根据表结构自动填充的,直接用完全没问题。

注意:默认生成的代码虽然能直接跑,但有几个常见问题,比如 Controller 的类名前缀、路径大小写风格可能不符合公司规范;Service 方法缺少自定义业务逻辑;XML 里没有覆盖复杂查询。这些不属于插件的缺陷,而是模板需要适配项目——下一篇内容我会专门讲怎么改模板。

3.4 把生成的代码集成到 Spring Boot 项目

光生成文件还不够,要让整个链路跑起来,还需要满足几个项目级前置条件。

第一,保证 Spring Boot 启动类上有@MapperScan注解,扫描到生成的 DAO 接口所在的包,比如com.example.demo.dao。如果不写这个注解,Spring 容器就不知道这些 Mapper 接口的存在,启动会报Field dao required a bean of type之类的错误。

第二,application.yml里需要配置 MyBatis 的 mapper-locations,指向 XML 文件所在路径,比如classpath:mapper/*.xml,否则运行时会找不到 SQL 映射。

第三,记得在pom.xml里引入mybatis-spring-boot-starter、MySQL 驱动依赖。如果用的数据库是 MySQL 8.0,驱动坐标也不一样,小心版本坑。

把这些前置条件解决掉,启动项目后,一个基础的增删改查接口就算可用了。你可以直接通过 POST 请求调用POST /sysUser新增数据,也可以通过GET /sysUser分页查询数据。

3.5 参数选择背后的逻辑

默认模板里有一个非常有用的方法queryAllByLimit,实现的是分页查询,但它是通过limit #{offset}, #{limit}这种手写方式实现的分页。这种写法对小数据量没问题,大数据量时性能需要考虑。实际项目里,通常引入 PageHelper 插件,那么我们就得改模板,把分页 SQL 改成 PageHelper 的写法——这个在模板定制章节我再展开。

还有insertSelectiveupdateByPrimaryKeySelective这两个方法,名字里的 "Selective" 是什么意思?指的是只对传入的非空字段生成 SQL 片段。比如insertSelective方法,实体的phone字段是 null,生成的 insert 语句里就会自动跳过phone列。这样一来,我们更新一条记录时,只改想改的字段,其他字段不会被覆盖,这个设计在业务开发中非常实用。

4. 模板定制:让生成代码变成你想要的风格

4.1 模板在哪个位置,怎么改

打开File -> Settings -> Other Settings -> EasyCode,这里就是插件的核心配置界面。它分为模板管理和类型映射两大块。模板管理里列出了所有内置模板文件,你可以直接点击右侧的编辑按钮修改它们;类型映射则是数据库类型和 Java 类型的对应关系,比如 MySQL 的datetime映射成LocalDateTimevarchar映射成Stringbigint映射成Long

我强烈建议先从这个类型映射入手,根据你们团队的基础类库调整。有些项目里不想用LocalDateTime,想退回java.util.Date,直接在这个映射页把datetime改成Date就行。

修改模板时有一个细节——EasyCode 的模板文件扩展名通常是.java.xml,但实际上内容是 Velocity 模板。你可以先看看系统默认的模板写法,通常在EasyEntity.java里会有#foreach($column in $tableInfo.fullColumn)这样的循环。看懂之后再动手改,不会无从下手。

4.2 实体类模板加 Lombok 注解

默认实体类生成的是完整 JavaBean,属性下面全是 getter/setter,代码很占篇幅。如果你的项目里已经统一用了 Lombok,那么完全可以改造模板,生成简洁版实体类。

改动思路是,在类声明处加上@Data@Builder注解(按需),然后删除掉所有 getter/setter 的循环输出部分。@Data会自动生成 getter/setter,@Builder方便链式赋值,这在单元测试里很常用。改完之后,生成的实体类大概长这样:

package com.example.demo.entity; import lombok.Data; import lombok.Builder; import lombok.NoArgsConstructor; import lombok.AllArgsConstructor; @Data @Builder @NoArgsConstructor @AllArgsConstructor public class SysUser { private Long id; private String username; private String password; // 其他字段 }

需要注意,如果用了 Lombok 的@Builder,默认不会生成无参构造器,所以一般配合@NoArgsConstructor@AllArgsConstructor一起使用,否则后续框架通过无参构造反射创建对象时会报错。

4.3 Controller 模板改造:统一返回结构和分页参数

默认生成的 Controller 方法返回的是R吗?不是,默认直接返回的是数据对象本身。真实项目里一般会定义一个统一的返回体,比如R<T>或者Result<T>,里面包含 code、message、data 三个字段。这一步改模板的思路是,让每个方法都返回R,并自动调用R.success(...)

这里我直接给一个改造后的 Controller 模板片段,你参考理解:

@RestController @RequestMapping("$!{tableInfo.name.substring(0,1).toLowerCase()}${tableInfo.name.substring(1)}") public class ${tableInfo.name}Controller { @Resource private ${tableInfo.name}Service ${tableInfo.name.substring(0,1).toLowerCase()}${tableInfo.name.substring(1)}Service; @PostMapping public R<${tableInfo.name}> insert(@RequestBody ${tableInfo.name} ${tableInfo.name.substring(0,1).toLowerCase()}${tableInfo.name.substring(1)}) { return R.success(${tableInfo.name.substring(0,1).toLowerCase()}${tableInfo.name.substring(1)}Service.insert(${tableInfo.name.substring(0,1).toLowerCase()}${tableInfo.name.substring(1)})); } }

注意模板中这些写法,${tableInfo.name}代表实体类名,比如SysUser,那$!{tableInfo.name.substring(0,1).toLowerCase()}${tableInfo.name.substring(1)}就是首字母小写后的sysUser。用$!{}写法的好处是,如果值为空就不输出,避免生成出奇怪的空字符串。

还有一个常见的需求——把queryAllByLimit改造成配合 PageHelper 或 MyBatis Plus 的分页写法。以 PageHelper 为例,模板里可以这样处理:

public R<PageInfo<${tableInfo.name}>> queryByPage(${tableInfo.name} ${tableInfo.name.substring(0,1).toLowerCase()}${tableInfo.name.substring(1)}, Integer pageNum, Integer pageSize) { PageHelper.startPage(pageNum, pageSize); List<${tableInfo.name}> list = service.queryAll(${tableInfo.name.substring(0,1).toLowerCase()}${tableInfo.name.substring(1)}); return R.success(new PageInfo<>(list)); }

这样生成出来的分页接口就是标准 PageHelper 风格,前端传pageNumpageSize就能直接分页。

4.4 Mapper XML 模板改造:追加批量操作和逻辑删除

默认的 XML 模板生成的都是单条增删改查。但在真实业务场景中,批量插入、批量更新、逻辑删除基本是标配。拿批量插入来说,默认模板里在foreach循环外部要有insert into table (col1, col2, ...) values,循环内部每个<foreach>的 item 用(#{item.xxx}, #{item.yyy})这种形式拼接。

要加逻辑删除的话,最简单的做法不是改模板,而是直接改 SQL。把deleteByPrimaryKey对应的删除 SQL 改成update table set deleted = 1 where id = #{id}。同时,所有查询 SQL 都要默认带上deleted = 0条件,不然逻辑删除的数据还会查出来。如果你希望生成的代码天然支持逻辑删除,那就要在模板的查询 SQL 片段里拼接这些条件。

我个人经验是,逻辑删除这种特殊处理不一定适合做在生成模板里,因为并不是每张表都带deleted字段。更合理的做法是:EasyCode 生成基础代码,逻辑删除的 SQL 由开发者在现有 XML 里做小范围修改,这样改动少、也清晰。

5. 常见问题与排查技巧实录

5.1 高频问题速查表

现象可能原因解决方法
生成代码时找不到数据库表Database 面板未配置连接或未刷新先在 Database 面板配置连接并刷新表列表
IDEA 提示找不到 EasyCode 窗口插件未安装成功或 IDEA 版本不兼容检查插件安装状态,重启 IDEA,必要时升级版本
生成的文件是乱码模板文件编码和项目编码不一致在 EasyCode 设置里统一使用 UTF-8 编码
生成的 controller 路径是sysUser这种驼峰模板中对名称做了首字母小写处理在模板里改成直接使用表名,或统一改为中划线风格
运行时报Invalid bound statement (not found)mapper XML 没有扫描到,或 XML 中 namespace 不匹配检查 application.yml 的 mapper-locations,以及 XML namespace 是否指向 DAO 接口全限定名
实体类的LocalDateTime类型无法被前端解析缺少 JSON 序列化配置在项目中配置jackson-datatype-jsr310等序列化组件
每次生成代码都会把原有修改覆盖生成时选择的输出路径和已有文件路径相同生成到临时目录,或者手动对比后再覆盖,别盲点覆盖

5.2 一个实际的报错排查过程

有一次我在一个新项目里用 EasyCode,生成完代码后启动 Spring Boot,控制台直接报Field userDao in com.example.demo.service.impl.SysUserServiceImpl required a bean of type 'com.example.demo.dao.SysUserDao' that could not be found

我第一反应是 DAO 接口没被扫描到,检查启动类发现忘了加@MapperScan("com.example.demo.dao")。加上之后,启动又报Invalid bound statement (not found): com.example.demo.dao.SysUserDao.queryAllByLimit,这次说明接口是注册上了,但 XML 文件没被加载。查了target/classes目录,发现 XML 文件根本没有被编译进去。再看pom.xml,默认情况下 Maven 只把src/main/java目录下的.java文件编译进 classpath,XML 放在src/main/java下时会被丢弃。

解决方法是,如果 XML 放在src/main/resources/mapper目录下,就不会有这个问题;如果团队习惯把 XML 和 DAO 接口放同一个包,那么需要在pom.xml中显式指定资源目录:

<build> <resources> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> </resources> </build>

这个问题也算是我用 EasyCode 时遇过最多的高频坑,所以写出来提醒大家。

5.3 表设计对生成结果的影响

EasyCode 生成的代码质量,直接受表结构设计影响。字段没有注释,生成的实体类属性上就不会有说明;用了规范命名的表名,生成的类名才好看。

一个很典型的例子:如果表名是t_user,表名前缀t_会原样带上,生成的类名是TUser。一般项目里会期望生成User,那需要在 EasyCode 配置里加一个表前缀过滤,或者在生成之前手动重命名表名。建议在配置里把t_sys_这类前缀统一去掉。

字段注释方面,建表时用中文注释,生成的 Java 代码才会自动带上对应的注释,这在接口文档自动生成时非常有用。如果字段没有注释,实体类里的属性全是光秃秃的,后期补注释很麻烦。

类型映射也是一个要提前确认的点。比如 MySQL 的tinyint(1),默认可能映射为Integer,如果你希望它映射为Boolean,需要在类型映射里把tinyintBoolean关联起来。否则生成之后,每次都要手动改字段类型很痛苦。

6. 关于 EasyCode 的更多理解

6.1 模板就是项目的"代码宪法"

使用 EasyCode 的过程中,我逐渐想明白了一个事:模板不只是省时间的工具,它其实是项目代码规范最有效的载体。你可以在模板里定义 Controller 统一返回类型,定义实体类必须使用 Lombok,定义 Service 必须写好方法注释,定义所有 Mapper 必须加@Param注解。项目组所有成员在这套模板上生成代码,写出来的东西就能高度一致,code review 的时候也省心不少。

新成员入职,不用再对着老代码去猜那些"约定俗成"的规则。他只要配好 EasyCode 模板,右键一生成,出来的代码跟项目里已有代码风格一模一样。这一点在实际团队协作中的价值,远高于"省了半小时手写代码"的表面价值。

所以我建议每个项目组,在新项目启动后马上去定制一套属于自己项目的 EasyCode 模板,而不是一直用默认模板。默认模板本身没问题,但它只是通用方案,项目的统一返回体、异常处理方式、租户隔离逻辑这些东西,都需要融进模板里,才能真正做到"一键生成、拿来即用"。

6.2 EasyCode 解决不了的边界

最后也要说句公道话,EasyCode 不是万能的。它解决的是 80% 的基础 CRUD 代码生成问题,剩下 20% 的复杂业务逻辑,比如复杂带筛选条件的分页查询、多表关联查询、权限控制、数据校验,它是不管的,也不该管。

还有一点很有意思:如果你用 EasyCode 生成了很多代码,但很少回头看这些代码,后面查问题时,很可能会发现项目里存在不少"没被用到的方法"和"没被走到的路径"。我的应对方式是,生成完代码后,结合 Coder 的代码审查习惯,把不需要的方法和代码直接删掉,保持项目清爽。生成的代码只是脚手架,不是保你运行不出事的免死金牌。

6.3 日常使用的一套完整工作流

整合下来,我在新项目里用 EasyCode 的标配流程是这样的:先建库建表并在建表时写清楚注释,然后 IDEA 配置数据源,接着调好 EasyCode 模板和类型映射。开始写业务时,在表上右键 Generate Code,先生成到临时目录检查一遍,再拷入项目代码目录,最后启动项目验证接口。

这套流程跑顺之后,从建表到接口可用,基本控制在几分钟以内。对于需要快速出原型的产品迭代期来说,这是实打实的效率提升。我觉得每个后端口开发者,不管喜不喜欢代码生成器,都值得尝试一下 EasyCode,用它重新审视自己日常代码里那些可以交给自动化工具的重复劳动。很多时候,效率就是从这些小地方一点一点提上来的。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询