首先说说上一篇最后提到的关于自定义注释的问题,想实现这个功能就需要修改 org.mybatis.generator.internal.DefaultCommentGenerator 这个类。我将里面一些主要的方法讲下。
addJavaFileComment(CompilationUnit compilationUnit)
给 Java 文件加注释,这个注释是在文件的顶部,也就是 package 上面。
addComment(XmlElement xmlElement)
给生成的 XML 文件加注释。大象将这个方法清空了,不生成注释。
addClassComment(InnerClass innerClass,IntrospectedTable introspectedTable)
Java类的类注释。
请注意红线的getRemarks()方法,这个remarks属性在原来的FullyQualifiedTable里面是没有的,这是大象自己加上去的,就是为了保存表的注释信息。那是在哪里加进去的呢?请看org.mybatis.generator.internal.db.DatabaseIntrospector这个类,大概浏览下就会发现,数据库表以及列的信息读取,类型设置都是由它来完成的,定位到608行,正好这里是个空行,插入几行代码。如下:
这样我们就取到了表的注释信息,看到这里应该就会明白了吧?
另外我需要说明的是,想通过 databaseMetaData . getTables() 来获得表注释的童鞋,这个做法是没用的,大象已经试过了,这个结果集里面的 rs.getString( "REMARKS" ) 得到的是一个空字符串,什么都木有。而且大象还想吐槽下,网上一大堆说返回的这个结果集是 10 列,呵呵,是的么?我 debug 了好久发现它还是只有 5 列,不知道这 10 列是从哪来的,请打印出 10 列的童鞋告之是怎么做的,我用的 mysql 驱动是 5.1.29
addFieldComment(Field field, IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn)
Java 属性注释。注释为空就不给属性添加。
addGetterComment(Method method,IntrospectedTable introspectedTable,IntrospectedColumn introspectedColumn)
给 getter 方法加注释。这里添加注释的方法和 Field 一样,大象把这个方法以及 addSetterComment 方法都清空了,因为我比较习惯把注释加到属性上面,如果你习惯在 getter 方法上面加注释可以自行改一下。
上面这些修改做完后,记得要在 org.mybatis.generator.codegen.mybatis3.model.BaseRecordGenerator 的 61 行增加下面这行代码:
commentGenerator.addClassComment(topLevelClass, introspectedTable );
因为 mybatis-generator 源码中本来就是不加类注释的。
大家都在不同的公司,要求肯定都不一样,大象没法满足所有人,只对该类做了一定程度的修改,姑且把它当做一个示例模板吧,主要是弄明白怎么改就成了。
mybatis-generator 在 1.3.2 版里对生成 xml 的 namespace 作了修改,不再用表名当为 namespace 的值,而是用包结构 + 类名 +Mapper 后缀的形式设置,大象不喜欢这么复杂做法,所以这里需要改一改,只保留类名 +Mapper 的命名形式。去掉 org.mybatis.generator.api.IntrospectedTable 类的 907 行与 908 行代码。
接下来再来说说对大对象类型的处理, mybatis-generator 默认会把所有 jdbcType 为: BINARY 、 BLOB 、 CLOB 、 LONGVARBINARY 、 LONGVARCHAR 、 VARBINARY 这些类型都作为大对象,反应出来的效果就是生成的 pojo 类会多一个类名 +WithBLOBs.java 的文件 ( 含有的大对象个数大于 1 时 ) ,而在 XML 里面也会增加一个 id 为 ResultMapWithBLOBs 的 resultMap ,它继承 BaseResultMap ,大象一向喜欢简单的风格,这看得太不爽了。如果你觉得无所谓,不需要修改,请跳过这段往下看。
表中的 text 或 blob 等类型,通过 databaseMetaData . getColumns() 取出来后,它的 rs.getInt( "DATA_TYPE" ) 值是与 java.sql.Types 对应的。
text 类型的值: Types. LONGVARCHAR
blob 类型是 值: Types. LONGVARBINARY
它用 org.mybatis.generator.internal.types.JavaTypeResolverDefaultImpl 解析 java 类型与 jdbc 类型,然后设置到 org.mybatis.generator.api.IntrospectedColumn 的 jdbcTypeName 属性里,最关键的地方到了, IntrospectedColumn 类第 156 行有个 isBLOBColumn() 方法,它就是用来判断是否生成 xxxWithBLOBs.java 和 ResultMapWithBLOBs 的条件。当然 mybatis-generator 不会这么直接用,它在里面定义了一个 Rules 接口,由它来统一进行调用。所以我们只需要把 isBLOBColumn() 里面的代码都去掉,直接返回 false 就可以了 ,再结合配置文件中的 columnOverride 属性就能达到目的。
jdbcType 指定的值就是生成 xml 后 result 里面对应的类型, javaType 与生成的 pojo 里面属性类型一致,这里其实可以不定义 javaType ,但是当数据库的表字段有的定义为 tinyint 时,如果不给它指定类型,那么默认生成的 java 类型就是 java.lang.Byte ,假如你想转换类型,而且保证不会超出字段类型的大小限制,那么你可以将它的 javaType 设为 java.lang.Integer
经过这么一番修改之后,输出结果已经比较理想了,但是 xml 文件看上去还是有点问题,元素与元素之间没空行,看起来好别扭。恩,这里要给它加上空行,所以请找到 org.mybatis.generator.api.dom.xml.XmlElement 类的 getFormattedContent 方法,这个方法有个参数: indentLevel ,通过名字我们可以很直观的理解它的作用就是来控制缩进等级,它的初始值为 0 ,这表示不缩进,当变成 1 时就是缩进一级,也即缩进四个空格,后面以此类推,我们应该还注意到,方法内部用到了递归,所以它是从最底元素开始,再一步步返回,所以我们就应该在 indentLevel 为 1 的元素后面加上换行。
在生成 xml 的文件里面,我们看到有一个 update 元素, id 为 updateByPrimaryKey ,这个基本上用不到,但是你还不能在 table 里加上 enableUpdateByPrimaryKey = "false" ,如果你这么做,虽然 updateByPrimaryKey 没有了,但 updateByPrimaryKeySelective 也会消失。所以这时 请看看 org.mybatis.generator.codegen.mybatis3.xmlmapper.XMLMapperGenerator 这个类, getSqlMapElement() 里面,有大量的 addXXX 方法,这些方法里面每个都用到了 Rules 规则来处理是否执行,比如我们在 table 里面加了 enableDeleteByExample = "false" ,它对应的是 addDeleteByExampleElement() ,而它又调用了 introspectedTable. getRules().generateDeleteByExample() 方法,再进入到 generateDeleteByExample() 里面,我们可以看到红线部分,上一篇大象讲过,在加载配置文件的时候, TableConfiguration 会将 table 中的这些属性设置到对应的属性里,所以说其实最后还是回到了判断 enableDeleteByExample 的布尔值上面。
上面啰嗦了一大堆,现在再来解决之前提到的问题,如何去掉 id 为 updateByPrimaryKey 的 update 元素,注释掉 addUpdateByPrimaryKeyWithoutBLOBsElement() 或直接去掉这行代码,跟踪代码你会发现,它和 addUpdateByPrimaryKeySelectiveElement() 的 rules 验证里面都用到了 enableUpdateByPrimaryKey 的值。或者你不想采取我说的这个办法,而是改 BaseRules 的 generateUpdateByPrimaryKeyWithoutBLOBs() ,让它直接返回 false
最后大象再唠叨一句,这些 addXXX 方法的顺序决定了生成 xml 文件中的元素顺序,所以有代码洁癖的人可以作下调整。
上一篇加这一篇都是讲怎么少量的改动源码以实现自定义文件输出,写的比较凌乱,不是很系统,完全是从实用的角度出发,关键还是大象水平有限,有什么错误还请大家帮我指出来,谢谢!
改了这么多 ,总要看下效果吧,下一篇大象将写个测试看看生成的结果,然后用 maven assembly 将它打包生成一个 zip ,它将包含: