如果你觉得mybatis-generator(MBG)自动生成的代码不能满足实际开发中的需要,你可以自定义插件生成规则,插件必须实现org.mybatis.generator.api.Plugin,不过通常情况下我们是需要去实现org.mybatis.generator.api.PluginAdapter。编写完成后在generatorConfig.xml配置<plugin>标签即可
PluginAdapter中有许多方法,按照生命周期执行顺序分为
- 默认构造函数创建的插件
- setContext方法:注入生成器上下文
- setProperties(Properties properties)方法:传入在配置文件中插件的参数,也就是在generatorConfig.xml配置的plugin标签属性,通过properties即可获取
- validate方法:方法一般用于验证传给参数的正确性 如果此方法返回false,则插件中不会再调用其他方法
- 对于每一张table表,又分别执行initialized方法和对应的ClientXXX,ModelXXX,SQLMapXXX
- contextGenerateAdditionalJavaFiles(IntrospectedTable):生成额外的Java文件,MBG自己是没有实现这个方法的,提供给插件一个扩展机会
- contextGenerateAdditionalXmlFiles(IntrospectedTable):同理,生成额外的XML文件,MBG自己是没有实现这个方法的,提供给插件一个扩展机会
- contextGenerateAdditionalJavaFiles()同contextGenerateAdditionalJavaFiles(IntrospectedTable)方法,只是没有参数而已;
- contextGenerateAdditionalXmlFiles()同contextGenerateAdditionalXmlFiles(IntrospectedTable)方法,只是没有提供参数;
contextXXX方法总是会被调用,而Java Client Method,Model Method和SQL Map Method是根据配置的MBG参数来选择性的执行
ClientXXX 也就是生成mapper.java接口的位置,如果clientGenerated方法返回false就不生成 XXMapper.java
ModelXXX也就是生成实体一类的方法
SQLMapXXX也就是生成xml的一类方法
返回布尔值的方法可用于绕过代码生成。如果这些方法中的任何一个返回false,那么相关项目将不会添加到生成的代码中。如果配置了多个插件,则第一个从方法返回false的插件将导致MyBatis Generator停止在所有其他插件中调用该方法。
1.org.mybatis.generator.api.IntrospectedTable
IntrospectedTable是一个抽象类,为不同版本MBG提供代码生成器,如果你要通过继承IntrospectedTable完成扩展,你需要自己来实现生成XML和Java代码的所有代码,在该类中提供了一个org.mybatis.generator.internal.rules.Rules类,来提供基础的生成规则的查询
当扩展了自己的IntrospectedTable之后,就可以在<context>的runtime中配置自己的实现类的全限定名即可;
在MBG中,所有的XML和JAVA代码的生成都是设计成DOM形式的,分别放在下面两个包中,有了解过爬虫的同学,应该知道在爬取网页得到结果是一大段html文本,那怎么获取里面我们想要的数据呢?不可能一个个字符截取把,所以需要借助第三方包比如jsoup,把html文本转换成dom这样的结构,这样就很方便获取里面的值了。所以我们只要构造一个一个的类似DOM的结构,然后根据封装好的这个DOM结构,来生成Java和XML代码;这样做很难把所有的结构都考虑在内,但是对于生成代码来说,基本足够了。
- Java DOM在org.mybatis.generator.api.dom.java包中;
- XML DOM在org.mybatis.generator.api.dom.xml包中;
这是重写sqlMapDocumentGenerated方法来自定义生成xml,从debug中可以看到parentElement对象,也就是具体生成的文档对象,默认为我们提供了6个实现的方法。
2.org.mybatis.generator.api.JavaTypeResolver
JavaTypeResolver类主要用于Jdbc类型和Java类型的一个映射关系;默认的实现是org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl;
有时候数据库设置的字段类型与期望生成的字段类型不一致,比如表设计的时候,可能会使用tinyint类型,但是在进行自动生成的时候,默认生成的是byte类型,但是我想要的是Integer类型,这就对程序中使用产生了不便。所以需要自定义映射关系实现JavaTypeResolver接口,然后在<javaTypeResolver type = " xx">标签配置具体的实现类即可。具体如何转换可参考JavaTypeResolverDefaultImpl。JavaTypeResolverDefaultImpl在构造函数中进行了转换,替换为自己想要的类型即可。
3.org.mybatis.generator.api.ShellCallback
ShellCallback主要提供了两个方面的功能:
- 把project属性或者package属性翻译成目录结构(MBG中面对的还是文件结构);
- 当Java或者XML文件存在的时候,负责怎么处理这些重复的文件;
该接口的默认实现为org.mybatis.generator.internal.DefaultShellCallback,默认的这个实现只提供了把project和package直接翻译成文件结构,如果某些文件夹不存在,则创建,另外对于重复存在的文件,默认实现也只能选择覆盖或者忽略;- 如果你想把MBG集成在其他应用环境中,这是一个相当值得扩展的类,比如在eclipse中,可以方便的扩展该接口来处理文件方法合并的功能;
但是注意一点,该扩展在generatorConfig XML文件中默认没有提供配置的地方,只能通过在org.mybatis.generator.api.MyBatisGenerator的构造方法中自己去创建一个(该类主要用于实际的生成动作,换句话说,要扩展这个扩展点,就必须要自己去实现一个运行MBG的代码,比如自己实现一个Ant应用或者Maven插件,可以参考org.mybatis.generator.api.ShellRunner来实现自己的启动类,PS:这个ShellRunner其实就是直接使用命令行运行MBG的那个main入口类);
4.org.mybatis.generator.api.ProgressCallback
当MBG在生成的过程当中,会不断的调用这个接口里面的指定方法,简单说,这个类非常适合用来做MBG生成的进度条显示;默认的实现是org.mybatis.generator.internal.NullProgressCallback,即简单的忽略所有的进度消息,可以通过实现这个接口完成自己的进度提醒甚至可以在中途取消代码的生成进度;
同样,该类也不能直接在generatorConfig.xml中配置,需要在org.mybatis.generator.api.MyBatisGenerator.generate()方法中传一个ProgressCallback类的实例即可;