用过mybatis的同学应该都知道mybatis generator(下文简称MBG)这个插件,他帮助我们生成用来操作数据库的mybatis相关代码,通常包括这三类代码:java entity、mapper xml、mapper interface.关于mybatis和MBG的基本使用,这里不多做介绍,本文主要介绍MBG生成mybatis代码过程中遇到的两个问题和解决方案。本文将以一张person表作为例子,进行讲解。
1.MBG每次运行时,生成的PersonMappper.xml追加导致项目无法启动
在项目开发前期,我们经常遇到表结构设计不合理或者因需求变更,导致需要改动表字段的情况。那么,当我们再次运行插件生成代码时,新生成xml的内容,会默认追加到PersonMapper.xml文件中。这样就会导致xml里有两个id一样的sql,当我们启动项目时,会看到如下的报错:
网上也有多解决方案,多大是基于继承PluginAdapter类做一些定制化的开发的方案,这种方案固然可以,但是对于开发人员的编码能力和质量是很一定考验的,并且比较耗时,占用工作量并且有风险的事情我们不做。优雅的我,不喜欢使用这种具有破坏性的方式,坚信MBG官方一定有相应的配置来支持这种需求,功夫不负有心人,在MBG的github 1.3.7版本日志里找到了如下说明:Add UnmergeableXmlMappersPlugin by jeffgbutler · Pull Request #311 · mybatis/generator · GitHub。
所以我们只需要升级MBG版本到1.3.7,然后在MBG的配置中,增加如下一行就可以啦:
<plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
2.手写的sql被覆盖问题
另外一种情况就是,MBG生成的sql语句都是一些基本的简单数据操作,如:
- insert
- update by primary key
- update by example (using a dynamic where clause)
- delete by primary key
- delete by example (using a dynamic where clause)
- select by primary key
- select by example (using a dynamic where clause)
- count by example
当我们遇到复杂的业务需求或者想自定义sql的时候,MBG就无能为力了。通常我们会自己在PersonMapper接口类中手动添加一个方法,然后在PersonMapper.xml文件中添加一个对应的sql。正常情况下,这样做是没有问题的,可是当我们再次遇到【问题1】中表结构变化时,不得不再次生成PersonMapper.xml。当再次生成之后,新生成的文件内容会覆盖原有内容,那么我们手动写的sql就被覆盖掉了。解决这个问题的方式:增加一个PersonExtendMapper.xml,里边的namespace和PersonMapper.xml保持一致,这样,我们把需要自定义的sql写到PersonExtendMapper.xml中就ok啦,这样既不用担心自定义方法被覆盖,又可以随时生成默认的一些sql。另外,建议大家少写自定义sql,保持和数据库的交互都是简单sql,让计算上移到应用层,毕竟在微服务时代,增加一个应用服务节点,比拓展数据库成本要低很多,当然只是建议,主要还是看业务场景。