ARTICLE DETAIL

资讯详情

深耕编程入门与网站建设的一线实战洞察。

IDEA插件MyBatisCodeHelperPro实操:MySQL 5与8下逆向生成全套代码

IDEA插件MyBatisCodeHelperPro实操:MySQL 5与8下逆向生成全套代码 作为一个Java后端开发最耗费时间的事情之一就是对着数据库表结构手写实体类、Mapper接口和XML映射文件。尤其项目一多、表一密这套纯体力的重复劳动不仅效率低还特别容易因为字段漏写、类型对不上而出各种低级Bug。我去年在重构一个老项目时实在受不了这种机械操作开始认真研究IDEA里的MyBatisCodeHelperPro插件。折腾了一周多把这套逆向生成流程彻底跑通了包括MySQL 5和MySQL 8两种版本下连接配置的差异问题。这篇文章就把我完整的实操记录和踩坑经验整理出来希望能帮到同样被CRUD折磨的各位。这个插件现在是我的必备工具了。它的核心价值在于只要数据库连接配好就能直接把数据表逆向生成对应的实体类、Mapper接口、XML映射文件和Service层方法整个流程从原来小半天压缩到几分钟。而且生成的代码风格统一、注释规范团队协作时大家维护起来也省心。接下来我按照从环境准备到最终代码生成的实际顺序把每一步的细节和为什么这么做拆开讲清楚。1. 插件选型与核心能力拆解1.1 为什么不用MyBatis Generator而选MyBatisCodeHelperPro很多同学第一反应是用官方MyBatis Generator也就是MBG。我以前也是MBG的老用户但用多了就会发现它的痛点很明显生成的代码风格偏老派对Lombok支持不够彻底写Service层还得自己再封装。更关键的是MBG的XML文件是覆盖式生成的我手工加的一些复杂查询SQL经常在重新生成时被直接抹掉。虽然可以通过配置避免覆盖但那套XML配置写起来本身就已经够繁琐了。MyBatisCodeHelperPro在这个场景下要顺手得多。它有两种生成模式一种是类似MBG的database工具逆向生成另一种是我最常用的选中数据库表直接生成。它的核心优势在于对Lombok的支持非常友好可以生成带Data注解的实体类代码量直接少一半自动生成Mapper接口和对应XML映射文件方法名和SQL语句直接匹配好免去了来回切换检查的麻烦内置了强力的代码跳转功能从Mapper接口的方法能直接跳到XML里的SQL从Service能直接跳到Mapper这个在排查问题时效率提升非常明显生成的代码不会破坏手动修改的内容增量更新比MBG安全得多我当时在团队里推广这个插件时不少同事一开始是抵触的觉得又是个花架子。但实际用了一周后没人愿意回到手写状态就是因为它在生成效率和代码质量两个维度上都是实打实的提升。1.2 插件的三大核心功能定位根据我的实际使用经验这个插件最常用的功能可以归为三类对应到日常开发的不同阶段第一类是表结构可视化与设计。连接数据库后直接在IDEA右侧的数据库面板里就能看到表、字段、索引这些信息。改字段名、加注释都不用再切到Navicat或命令行工具尤其对前端转后端、对数据库操作不熟的同学特别友好。第二类是代码生成。这是本文的重点选中数据库表后通过右键菜单就能一键生成实体类、Mapper接口、XML文件、Service接口和Service实现类。生成时可以自由勾选字段是否参与查询、更新、插入非常灵活。第三类是代码辅助增强。包括Mapper方法和XML之间的跳转、XML里SQL语句的语法高亮和自动补全、以及一键生成测试用例这类小工具。这些功能单个看不算什么但在写复杂SQL时加起来确实省了不少时间。明白了它能做什么我们来看看怎么把它跑起来。2. 环境准备与插件安装实操2.1 本地环境的基本要求我这边的主力开发机是一台Windows 11笔记本IDEA版本用的是2023.2.5JDK是1.8。需要重新装环境的同学要注意虽然IDEA新版本对插件兼容性做得不错但我实测在IDEA 2020.3以下的版本装最新版MyBatisCodeHelperPro时偶尔会出现菜单不显示或者生成按钮点了没反应的兼容性问题。如果你的IDEA版本较老建议优先升级。MySQL这边的环境比较特殊因为标题里也提到了5和8两个版本我的建议是新项目直接用MySQL 8.0以上版本它无论从性能、默认字符集还是窗口函数这些功能特性上都比5.7时期强太多。如果是维护老项目那就保持原有版本这点在后面的连接配置里会有具体的差异说明。我本机同时装了MySQL 5.7和MySQL 8.0两个实例分别跑在3306和3307端口目的就是方便验证两个版本下的插件行为差异。如果条件允许建议大家也这么做能省去很多我本地可以但服务器不行的烦恼。2.2 插件获取与激活要点MyBatisCodeHelperPro是一款付费插件在IDEA的插件市场里搜mybatiscodehelperpro就能找到官方版本。我的做法是在IDEA里直接打开File - Settings - Plugins - Marketplace搜索框输入插件名点Install就行。这种方式装的是官方正版更新及时也不存在从第三方渠道下载导致的安全风险。这里要专门说下激活问题。这个插件虽然需要激活码但JetBrains官方提供了30天免费试用期。我的建议是先激活试用在真实项目里用一周确认这个工具对你的开发效率确实有提升再考虑购买。目前Plugin价格大概是个人版一年一百多块钱说实话对于节省下来的时间成本来说完全值得。官方也支持开源项目免费申请授权如果你是开源项目的维护者可以去官网提交申请试试。网上有些人分享的离线激活方式我不推荐使用一方面版本更新后大概率失效另一方面这些破解方式可能在插件里夹带私货给项目代码埋雷得不偿失。2.3 安装后的基础校验清单插件装好以后别急着连接数据库。我先做一个快速自检确认插件真正生效了重新打开项目IDEA底部工具栏应该出现一个MyBatisCodeHelper或者类似的面板入口右键点击一个已有的Mapper接口菜单里能看到Generate相关选项打开任意XML文件右键能看到MyBatis相关的生成或跳转菜单File - Settings - Other Settings下面出现了MyBatisCodeHelper的配置项这一套走下来都正常再进入下一步。如果菜单没出现大概率是IDEA版本兼容问题或者插件没被正确加载。遇到这种情况先重启IDEA再不行就检查IDEA版本是否在插件支持范围内。我见过有的同事装完插件不开新项目直接在旧项目里找来找去结果发现是缓存问题File - Invalidate Caches清一遍就好了。3. 数据库连接配置MySQL 5与8的差异详解3.1 驱动选择是第一个分水岭连接数据库是整个逆向生成流程的地基这一步出问题后面全白搭。而MySQL 5和8在连接方式上最大的区别就在驱动类名和连接参数上。如果你连的是MySQL 5.x驱动类名用com.mysql.jdbc.Driver连接URL大致长这样jdbc:mysql://localhost:3306/database_name?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/Shanghai如果你连的是MySQL 8.x驱动类名必须换成com.mysql.cj.jdbc.DriverURL则是jdbc:mysql://localhost:3306/database_name?useUnicodetruecharacterEncodingutf8useSSLfalseserverTimezoneAsia/ShanghaiallowPublicKeyRetrievaltrue注意第二个URL多了个allowPublicKeyRetrievaltrue参数。这个东西在MySQL 8默认的caching_sha2_password认证插件下是必须的不加的话插件连接时经常报Public Key Retrieval is not allowed错误。我第一次在8.0环境下配置时就被这个参数卡了快半小时日志翻来覆去看了好几遍后来加上这个参数立马通了。3.2 配置数据库连接的两处关键位置在IDEA里配置数据库连接常见的有两个入口很多新手容易弄混。第一个是IDEA自带的Database工具窗口在右侧边栏或者通过View - Tool Windows - Database打开。点左上角的加号选择Data Source - MySQL然后填主机、端口、用户名、密码。这里有个坑如果本机没有下载对应的MySQL驱动IDEA会提示你下载记得选MySQL Connector/J这个官方驱动别选那些奇怪的名字。第二个是插件的MyBatisCodeHelperPro配置窗口在File - Settings - Other Settings - MyBatisCodeHelperPro里。它的数据库配置和IDEA自带的Database工具是打通的共用一份配置。也就是说你在IDEA的Database窗口里配好数据源插件这边不需要重复配置直接就能识别到。3.3 连接不上的常见排查路径连接失败是最常见的问题虽然网上一搜一堆解决方案但很多都写得模棱两可。我根据自己的经验整理了一套排查顺序先看驱动包有没有加载成功。在Database窗口的数据源配置界面有个Test Connection按钮点之前先确认驱动下拉框里选的不是No driver这种空选项。选了驱动之后如果提示找不到驱动类十有八九是驱动版本和你MySQL版本不匹配。再看URL参数填全了没有。MySQL 5和8的共同点是都必须带useUnicodetruecharacterEncodingutf8否则中文注释和中文数据会乱码都要带serverTimezoneAsia/Shanghai否则MySQL 8会报The server time zone value Öйú±ê׼ʱ¼ä is unrecognized这种一看就是时区编码乱掉的问题。最后检查端口和权限。本机多个MySQL实例时端口一定不能填错。还有远程连接时要确认MySQL用户有远程访问权限。我第一次在阿里云服务器上配置时就忘了GRANT ALL ON *.* TO user%这一步导致IDEA一直报Access denied for user。有一个小技巧无论MySQL 5还是8我习惯先通过命令行确认能正常连上MySQL再回IDEA里配置数据源。命令行都连不上那就别提插件能连上了。用下面的命令验证mysql -u root -p -h localhost -P 3306连上之后执行SELECT VERSION();看版本号是否和自己预期一致。这一步能过滤掉大部分环境自身的问题。3.4 连接成功的标志与验证当数据库连接配置正确后IDEA的Database窗口会显示所有数据库和表的列表。此时右键任意一张表菜单里能看到MyBatisCodeHelperPro相关的生成选项。我的习惯是配置好数据源后先不急着生成代码而是先点开一张表查看字段列表、索引信息是否正常显示。这个动作能提前发现字符集、驱动版本的一系列隐藏问题。如果表结构数据有的显示有的不显示多半是驱动版本和数据库版本不匹配需要更换驱动版本再试。连接这关过了就可以正式进入代码生成环节了。4. 逆向生成全流程实操4.1 生成前要做的三件小事在右键表开始生成之前我建议先花五分钟把生成配置调好这个步骤决定了生成出来的代码是不是你想要的风格。打开File - Settings - Other Settings - MyBatisCodeHelperPro的配置界面重点看三块内容第一块是注释模板。这个插件可以按模板生成类注释和方法注释默认模板通常不太符合我们的规范。我一般会把类注释改成这样的/** * ${TABLE_COMMENT}实体类 * * author ${USER} * date ${DATE} */方法注释、字段注释同理。把模板配置好以后生成的每一行注释都会自动带上表注释和字段注释后续写API文档时非常有用。第二块是实体类风格。这里有个核心选择用不用Lombok。如果项目里已经引入了Lombok强烈建议在配置中勾选生成Data注解如果项目没用Lombok那就生成标准的getter/setter。注意一点这个选择一旦确定项目里最好统一不要混着来否则Lombok的类和非Lombok的类并存新同事接手时会很头疼。第三块是Mapper接口的生成风格。这个插件支持生成类似MyBatis-Plus的BaseMapper风格也支持纯MyBatis的标准Mapper风格。如果你的项目用了MyBatis-Plus生成时可以勾选继承BaseMapperT这样会少写很多CRUD方法。如果是标准MyBatis项目就选中标准风格按表自动生成增删改查方法。4.2 选中表并执行生成的完整步骤配置好了之后正式生成流程就非常简单了。回到IDEA的Database窗口找到要生成的表可以按住Ctrl多选多张表右键选中它在弹出的菜单里找到MyBatisCodeHelperPro然后选择Generate。此时会弹出一个生成配置的窗口里面可以勾选生成哪些文件实体类、Mapper接口、XML、Service接口、Service实现类实体类字段是否包含数据库中的注释信息Mapper方法生成的风格比如是否生成批量插入、批量更新是否生成带注解的实体字段比如TableField、TableName这类生成的包名和路径这里我要提醒一句生成的文件路径一定要先规划好。默认情况下插件会按照你配置的base package路径输出所有文件。如果项目是多模块的比如common、dal、service分开的建议把生成路径手动改成对应的模块目录否则生成完了还得逐个文件移动非常麻烦。选好所有选项点击确定代码就自动生成好了。整个过程不到十秒生成的代码结构如下示例Data TableName(user) public class User { TableId(value id, type IdType.AUTO) private Integer id; private String username; private String email; }4.3 生成结果的结构解读我拿最近在做的用户管理模块举例。表名是t_user字段有id、username、email、password、create_time、update_time。生成的代码长这样User.java一个标准的实体类带Lombok注解createTime和updateTime字段会按照驼峰命名规则自动转换过来。如果表里设置了字段注释注释也会自动带过来。UserMapper.javaMapper接口里面包含基础的增删改查方法。如果用MyBatis-Plus风格会继承BaseMapperUser自带selectById、insert、deleteById等十几个方法你什么都不用写。如果是纯MyBatis风格会自动生成selectByPrimaryKey、insert、updateByPrimaryKey、deleteByPrimaryKey这几个。UserMapper.xmlXML映射文件SQL语句和Mapper接口的方法一一对应。这里有个细节我特别满意它生成的SQL都是不带select *的而是按表字段逐一列出来对线上问题排查和代码审查都更友好。UserService.java和UserServiceImpl.javaService层接口和实现类里面默认提供了一个最简单的insert和selectById的Demo方法。这个方法是给你的参考模板实际业务方法需要根据自己的需求继续扩展。我一般会把默认生成的这几个示例方法删掉只保留实体和Mapper部分因为我的Service层方法都是按业务命名的插件很难自动生成这一层。4.4 多表批量生成的效率技巧在真实项目里通常不会只生成一张表。比如一个订单模块可能有订单表、订单明细表、物流信息表、用户表等七八张表关联在一起。这时如果一张张右键生成来回点配置窗口也挺费时间的。我的做法是在Database窗口里按Ctrl多选所有需要生成代码的表然后一次性右键生成。插件会按表逐个生成对应的实体、Mapper、XML。所有文件生成后再批量调整一下包路径就行。这个方法在实际项目中效率提升最明显我第一次用的时候一个十几张表的模块从连接数据库到所有代码生成完毕也就用了十来分钟。不过要注意多表生成时如果某些表没有主键插件会给出警告。因为MyBatis的selectByPrimaryKey和updateByPrimaryKey都依赖主键无主键表要么手动在表结构里补上逻辑主键要么生成后手动删掉这些方法。我的建议是无论如何都要给表加一个物理主键哪怕它业务上没啥用至少对数据维护和代码生成都是必要条件。5. 常见问题排查与避坑经验5.1 连接阶段的经典报错汇总我把这一年多实际遇到过的高频报错、原因分析和解决办法整理成了一张速查表遇到问题可以直接对号入座报错信息根本原因解决办法Public Key Retrieval is not allowedMySQL 8默认认证插件是caching_sha2_password需要客户端先获取公钥URL参数里加allowPublicKeyRetrievaltrueThe server time zone value Öйú±ê׼ʱ¼ä is unrecognized数据库时区和IDEA时区不一致URL参数加serverTimezoneAsia/ShanghaiCannot load driver class: com.mysql.cj.jdbc.Driver驱动包版本太老不包含cj驱动类在IDEA里重新选择最新版本MySQL Connector/J 8.xAccess denied for user rootlocalhost用户密码错误或用户没有远程访问权限确认本地密码远程场景执行授权SQLGRANT ALL ON *.* TO user%Communications link failureMySQL服务没启动或端口被防火墙拦了先mysql -u root -p命令行测试本地连接Connection refused数据库端口和IDEA配置端口不一致确认实际监听端口本机多实例场景特别容易踩坑我在文章前面提到的那个allowPublicKeyRetrievaltrue参数当时查了很多资料大多数答案只说加这个参数没解释为什么。后来看了MySQL官方文档才明白MySQL 8默认的caching_sha2_password认证机制下客户端在首次连接时如果没有通过SSL加密通道就需要主动向服务器请求RSA公钥来完成密码交换。驱动默认行为是不自动获取公钥所以必须显式打开这个开关。理解了原理之后以后再遇到连接错误我基本都是按认证机制-传输加密-时区这套思路快速定位问题。5.2 生成阶段的高频问题实操记录连接成功不代表生成过程就一帆风顺。我在使用过程中也遇到过不少生成阶段的坑这里挑几个典型的说。第一个是表名和字段名的大小写问题。在Windows上开发MySQL默认对表名大小写不敏感但Linux环境下区分大小写。如果开发机和服务器环境不一致生成的实体类名和表名可能对不上。后来我做了一个约定数据库表名和字段名统一使用小写加下划线比如user_name这样在任何平台上行为都一致也符合Java的驼峰命名转换规则。第二个是字段类型映射不完全符合预期。比如数据库的datetime类型插件默认映射成Java的时间类。在MySQL 8下会映射成LocalDateTime在MySQL 5下可能映射成Date或Timestamp。这个跟驱动版本有关系。如果项目统一用java.util.Date就得在插件配置里改字段类型映射规则。不过从我现在的习惯来说新项目一律推荐LocalDateTime配合Jackson的JsonFormat处理序列化完全够用。第三个是XML文件没有正常生成。这种情况多半是表名里包含特殊字符或者表名过长导致IDEA生成文件时路径非法。解决方案是给表名加上反引号不过更好的做法是从命名阶段就避免使用连字符之类的特殊字符。第四个是Lombok生成的实体类在编译时找不到getter/setter。这个不是插件的问题是项目里Lombok依赖或者IDEA的注解处理器配置不正确。需要在File - Settings - Build, Execution, Deployment - Compiler - Annotation Processors里勾选Enable annotation processing。5.3 我总结的三条独家避坑心得用了这么久这个插件我总结出三条在别处很少被提到的经验写在这里供大家参考第一条生成代码前务必仔细核对表注释和字段注释是否完整。这个插件最大的隐藏价值在于它能把数据库表结构的注释直接带进Java代码。如果表设计阶段没写注释生成的实体类就是一堆光秃秃的字段团队成员接手时还是得去数据库里翻注释。反过来如果表注释写得规范生成的代码基本不需要额外维护文档IDE里悬浮就能看到字段含义这种自文档化的效果在团队协作中价值非常大。第二条XML映射文件和Mapper接口的对应关系在插件生成后一定要做一次快速校验。方法是在Mapper接口的方法名上按住Ctrl键点击方法名如果配置正确应能直接跳到XML里对应的SQL语句。这个功能正常说明生成过程没有发生映射错乱后续维护时也能享受同样的跳转便利。第三条每用一次逆向生成后建议顺手执行一遍项目的编译命令确认生成的代码没有语法错误。不要想着插件生成的一定是对的我就遇到过插件生成的实体类中包含了数据库中的虚拟列而实际Java类里又没有对应的字段导致编译直接报错的情况。跑一次编译几秒钟的事能省掉后续排查问题的大量时间。6. 让逆向生成的价值最大化6.1 与MyBatis-Plus组合使用的效率倍增方案我现在的技术栈里MyBatisCodeHelperPro和MyBatis-Plus是搭配使用的。逆向生成解决了基础代码从无到有的问题MyBatis-Plus则解决了日常CRUD不必重复写SQL的问题。具体操作是逆向生成时实体类勾选生成TableName和TableId注解Mapper接口勾选继承BaseMapperT。这样生成出来的Mapper接口就有了selectPage、selectList、selectOne、insert等一整套现成的单表操作方法。大部分简单业务根本不用在XML里写SQL直接在Service里调用BaseMapper的方法就能搞定。这套组合拳下来业务代码里剩下的基本上就是纯业务逻辑了。比如用户分页查询ServiceImpl里一行代码就搞定Override public IPageUser getUserPage(PageUser page, WrapperUser queryWrapper) { return userMapper.selectPage(page, queryWrapper); }不用写XML不用写SQL可读性和可维护性都远超传统方式。当然前提是项目成员都对MyBatis-Plus的Wrapper机制比较熟悉否则建议先从基础的LambdaQueryWrapper用起。6.2 复杂场景下的XML手动补充技巧逆向生成能覆盖80%的常规场景但总有些特殊查询是插件生成不了的比如多表关联查询、子查询、动态SQL。这时候就要在生成的XML文件基础上手动补充。我的做法是在生成的XML里把Mapper接口新加的查询方法对应的select标签补上。补写时注意利用插件的代码补全能力它能在XML里自动提示表名、字段名这个功能写动态SQL时特别有用不用来回切换到数据库工具里复制表名和字段名。具体到一个订单列表分页查询我可能会在生成的Mapper接口里加一个方法ListOrderVO selectOrderDetailList(PageOrderVO page, Param(query) OrderQuery query);然后在XML里补上对应的select用where标签做动态条件拼接再用foreach处理IN子句。这些SQL插件不会自动生成但XML文件的代码补全开着写起来速度也不慢质量还有保障。6.3 团队协作时的生成规范建议在团队里推广这个插件最怕的是每个人生成出来的代码风格都不一样反而加剧代码混乱。我现在负责的项目组里定了一份简单的使用规范效果不错也分享出来供大家参考所有数据库表的逆向生成统一由一个人或固定几个人操作生成完commit到代码仓库其他人直接拉代码不要再各自生成一份生成路径和包名必须遵循模块划分的目录结构不允许生成后手动移动文件实体类统一使用Lombok风格禁止混用传统getter/setterMapper接口统一继承BaseMapperT除非有明确的性能或架构要求生成的XML文件可以手动添加自定义SQL但要保持原有格式和注释风格表结构变更后优先在数据库端修改再通过插件增量更新代码不要直接改Java实体类字段这套规范执行了大概半年最直观的好处是代码评审时几乎没有任何关于实体类和Mapper的争论大家看代码就像在看同一个人的风格效率提升非常明显。6.4 我的最终使用建议如果你是在传统MyBatis项目里被CRUD折磨的开发或者刚接手一个数据库表特别多的老系统我建议你花一个下午的时间把这篇文章里的内容完整过一遍。先安装插件再配置好数据库连接随便找三五张表逆向生成一版代码对比一下自己手写的时间基本就能体会到这个工具的含金量了。插件只是个工具真正有价值的是把重复劳动交给自动化这个思维套用到工作流中。MyBatisCodeHelperPro帮我省下的时间我用来补业务知识、写测试用例、做代码重构这些才是对项目和自身成长更有价值的事情。希望这篇实操笔记也能帮你把时间花在更有意义的地方。
返回列表