勿忘初心

个人签名

529篇博客

Mybatis Generator的使用及源码浅析(下篇)

勿忘初心2018-09-04 09:35

作者:李哲


二、Mybatis  Generator源码浅析

在几个项目中尝试着使用了MBG后,觉得确实比原来开发方便了许多。其实感觉要做一个这样的功能也不难,最简单的方式就是根据配置的数据库信息读取数据库中的表字段,利用模板去替换这些字段,最后生成文件。很好奇地看了下MBG的源码,它并不是通过这种方式实现的。

首先看一下MBG核心代码的包组织结构,如下图所示:

这里先简单介绍下源码中各个包的作用,ant包下的类是该工具配置到ant任务中使用,api包是提供给外部使用接口,codegen包中主要是生成代码的类,config包中主要是读取配置文件并将配置文件中的信息解析保存,exception包是封装的异常处理,internal包中主要是该工程中使用的一些类,logging是处理日志相关的类,plugins是用到的插件类,主要是对生成的代码做二次处理。主要业务相关的包有apiconfigcodegen。下面介绍MBG是如何生成代码的。

因为MBG可以通过命令行java命令生成代码,所以其一定有main方法的入口,在工程中搜索main方法,它是在api包下ShellRunner中。如下图所示,从ShellRunner类中截取了核心的一段代码。从代码中可以看到,生成的过程大概分为两个部分,第一读取配置文件,解析配置文件中的信息,第二通过MyBatisGenerator类生成代码。其中,warnings是一个List<String>,主要用于收集生成代码过程中警告错误信息;ShellCallback接口中规范了命令行环境需要用到条件;ProgressCallback接口规范了生成代码过程中的阶段性回调。

1)对于配置文件的解析处理,这里不做过多研究,这和一般的xml文件解析处理没有太多差别,解析完的信息都放到Configuration类中的List<Context> contexts属性下,context对应着配置文件中的<context>标签下的元素信息。

   (2)主要生成代码的方法是MyBatisGenerator类中的generate方法,这是个重载方法,可以提供不同的参数调用。在MyBatisGenerator类中是如何使用Configuration中的配置信息,Configuration类中是以什么形式保存配置信息的?或许看了下面的UML类图可以得到答案。

从图中可以看到,MyBatisGenerator中包含Configuration,而IntrospectedTable类的主要作用是将数据库的表字段转换成要生成的JavaXML所需的元素,TableConfiguration中是每一张表的配置信息。MyBatisGeneratorIntrospectedTable是通过Context联系在一起的,每一个Context即是对应着配置文件中的一个<context>标签中的信息。所以,整个生成代码的过程是MyBatisGenerator通过configuration.getContexts()拿到Context,然后调用其introspectTables()方法把数据库中的表字段转化为生成文件时需要的元素,然后再调用generateFiles()方法生成对应文件。如下图代码所示:

上面用到了Context中的两个重要的方法introspectTablesgenerateFiles,它们是怎么实现的呢?下图是introspectTables方法的代码,首先说明tableConfigurationsContext类。

的一个属性,它是在配置文件解析的时候就addContext中的。然而,introspectTables真正的过程是通过DatabaseIntrospector类的introspectTables方法完成的,它从数据库中读取表的信息,根据字段类型和配置信息生成List<IntrospectedTable>,最后保存到Context中。由于篇幅原因,此处不再跟踪DatabaseIntrospector类中的方法,有兴趣的可以自己研究。此时,你可以认为数据库中表的信息都已经变成了一些元素放在introspectedTables中了。然后调用Context类的generateFiles方法处理,如下代码所示:

从上面的代码中可以看到,生成文件的过程是遍历introspectedTables,分别生成配置信息中对应的Java文件和XML文件,如果配置文件中配置了plugin,则插件还会对生成的文件做处理,但是源码本身的插件没有做任何处理,代码如下:

如果我们自己写插件时可以覆盖上面的方法,可以对生成的文件进一步处理,这样可以很方便地扩展程序。更细节的实现在IntrospectedTablegetGeneratedJavaFiles方法里面,这里不做更详细的介绍,感兴趣的自己研究。总之,MBG的实现方式是根据配置文件信息生成与数据库中表字段对应的元素,根据元素利用拼接字符串的方式生成代码。这种方式与利用模板替换方式还是有一点区别。这种方式可以非常细粒度的控制生成的代码,而利用模板的方式可能要更容易实现一些。

本文主要介绍了如何利用Mybatis Generator生成代码以及对其源码进行了简单的分析。通过使用MBG生成代码确实提高了开发的效率,可以把精力集中在业务处理上,推荐没有试过的可以尝试着使用。经常阅读好的源码也可以提高我们自己的编程水平,相对于其它复杂的开源项目源码,如springHibernate等,MBG应该说是比较简单的。所以,如果是刚开始阅读源码可以选择一些简单的,学习一些阅读技巧后再循序渐进。由于作者水平有限且时间仓促,分析难免存在一些问题,如有发现或有其他问题可以及时与作者联系。




相关阅读:Mybatis Generator的使用及源码浅析(上篇)

网易云大礼包:https://www.163yun.com/gift

本文来自网易实践者社区,经作者李哲授权发布