MyBatis Generator 自定义生成注释的方法

时间:2022-09-25 12:54:23

最近做项目,orm 使用的是 mybatis,为了偷懒,我自然而然的想到了使用 mybatis generator(mbg)来生成数据库表对应的实体代码和 mapper 代码。于是做了如下的配置(对 mbg 配置不熟悉的同学可以参考 mybatis generator最完整配置详解):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
<?xml version="1.0" encoding="utf-8"?>
<!doctype generatorconfiguration public
    "-//mybatis.org//dtd mybatis generator configuration 1.0//en"
    "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
    
<generatorconfiguration>
  <!-- 指定数据库驱动的jdbc驱动jar包的位置 -->
  <classpathentry location="./mysql-connector-java-5.1.40.jar" />
 
  <context id="mysql" defaultmodeltype="hierarchical" targetruntime="mybatis3simple" >
    <!-- 生成的 java 文件的编码 -->
    <property name="javafileencoding" value="utf-8"/>
    <!-- 格式化 java 代码 -->
    <property name="javaformatter" value="org.mybatis.generator.api.dom.defaultjavaformatter"/>
    <!-- 格式化 xml 代码 -->
    <property name="xmlformatter" value="org.mybatis.generator.api.dom.defaultxmlformatter"/>
 
    <!-- 配置数据库连接 -->
    <jdbcconnection driverclass="com.mysql.jdbc.driver" connectionurl="jdbc:mysql://localhost:3306/test?characterencoding=utf-8" userid="root" password="123456">
    </jdbcconnection>
 
    <!-- 生成实体的位置 -->
    <javamodelgenerator targetpackage="me.mizhoux.model" targetproject="src/main/java">
      <property name="enablesubpackages" value="true"/>
    </javamodelgenerator>
 
    <!-- 生成 mapper 接口的位置 -->
    <sqlmapgenerator targetpackage="me.mizhoux.mapper" targetproject="src/main/java">
      <property name="enablesubpackages" value="true"/>
    </sqlmapgenerator>
 
    <!-- 生成 mapper xml 的位置 -->
    <javaclientgenerator targetpackage="me.mizhoux.mapper" type="xmlmapper" targetproject="src/main/java">
      <property name="enablesubpackages" value="true"/>
    </javaclientgenerator>
 
    <!-- 设置数据库的表名和实体类名 -->
    <table tablename="t_user" domainobjectname="user">
      <!-- generatedkey用于生成生成主键的方法 -->
      <generatedkey column="id" sqlstatement="select last_insert_id()"/>
    </table>
 
  </context>
 
</generatorconfiguration>

数据库建库建表的代码:

?
1
2
3
4
5
6
7
8
9
10
create schema `db_test` default character set utf8 collate utf8_unicode_ci ;
 
create table `db_test`.`t_user` (
 `id` int not null auto_increment comment '用户 id',
 `username` varchar(30) null comment '用户名称',
 `password` varchar(20) null comment '用户密码',
 `birthday` date null comment '用户生日',
 primary key (`id`),
 unique index `username_unique` (`username` asc)
) comment = '用户';

开开心心,执行命令,开始生成代码:

java -jar mybatis-generator-core-1.3.7.jar -configfile generatorconfig.xml -overwrite

然后查看生成的 java 实体类:

MyBatis Generator 自定义生成注释的方法

看着这个注释,让我有点纠结啊 —— 为什么不是数据库中每个字段对应的注释呢?查找相关资料,得知 mbg 生成的是由 org.mybatis.generator.api.commentgenerator 来控制的。这是一个接口,mbg 的默认实现类是做 org.mybatis.generator.internal.defaultcommentgenerator。当你在 generatorconfig.xml 中配置了 commentgenerator 标签,那么默认状态下,生成注释的工作,将由 defaultcommentgenerator来完成。 所以我们来查看下这个 defaultcommentgenerator 的源码:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
public class defaultcommentgenerator implements commentgenerator {
  // 属性,即配置在 commentgenerator 标签之内的 property 标签
  private properties properties;
  // 是否不生成日期
  private boolean suppressdate;
  // 是否不生成注释
  private boolean suppressallcomments;
  // 是否添加数据库内的注释
  private boolean addremarkcomments;
  // 日期格式化
  private simpledateformat dateformat;
 
  public defaultcommentgenerator() {
    super();
    properties = new properties();
    suppressdate = false;
    suppressallcomments = false;
    addremarkcomments = false;
  }
 
  @override
  public void addconfigurationproperties(properties properties) {
    this.properties.putall(properties);
 
    suppressdate = istrue(properties
        .getproperty(propertyregistry.comment_generator_suppress_date));
    
    suppressallcomments = istrue(properties
        .getproperty(propertyregistry.comment_generator_suppress_all_comments));
 
    addremarkcomments = istrue(properties
        .getproperty(propertyregistry.comment_generator_add_remark_comments));
    
    string dateformatstring = properties.getproperty(propertyregistry.comment_generator_date_format);
    if (stringutility.stringhasvalue(dateformatstring)) {
      dateformat = new simpledateformat(dateformatstring);
    }
  }
  
  // 其他代码
  ...
}

addremarkcomments 这个属性,看来就是用来生成数据库注释用的 —— 好开心,那把它设置为 true 试试:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<generatorconfiguration>
  <!-- 指定数据库驱动的jdbc驱动jar包的位置 -->
  <classpathentry location="./mysql-connector-java-5.1.40.jar" />
  
  <context id="mysql" defaultmodeltype="hierarchical" targetruntime="mybatis3simple" >
    <property name="javafileencoding" value="utf-8"/>
    <!-- 其他 property -->
 
    <commentgenerator>
      <property name="suppressdate" value="true"/>
      <property name="addremarkcomments" value="true"/>
    </commentgenerator>
    
    ...
  </context>
</generatorconfiguration>

运行命令:

java -jar mybatis-generator-core-1.3.7.jar -configfile generatorconfig.xml -overwrite

MyBatis Generator 自定义生成注释的方法

数据库注释倒是拿到了,但是生成的一堆其他信息,看着实在是太扎眼了。查看源码,发现这些内容已经写死在 defaultcommentgenerator 中了,没有办法自定义。

MyBatis Generator 自定义生成注释的方法

自己动手丰衣足食,我们为啥不自己写个类实现 commentgenerator 接口,然后自定义自己想要的注释呢。查看 commentgenerator 的 dtd,发现正好 commentgenerator 有个 type 属性,可以用来指定自己的注释实现类:

MyBatis Generator 自定义生成注释的方法

查看 commentgenerator 接口,发现里面的方法非常多,不仅包含了生成 java 实体注释对应的方法,还包括了生成 xml 中注释的方法。所以我们先写一个默认的实现类,实现commentgenerator 接口,但不做任何操作 —— 因为 defaultcommentgenerator 本文已经存在了,为了避免混淆,就叫它simplecommentgenerator吧。然后定义我们自己的注释类,mysqlcommentgenerator,继承 simplecommentgenerator,重写我们需要的方法:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
public class mysqlcommentgenerator extends simplecommentgenerator {
 
  private properties properties;
 
  public mysqlcommentgenerator() {
    properties = new properties();
  }
 
  @override
  public void addconfigurationproperties(properties properties) {
    // 获取自定义的 properties
    this.properties.putall(properties);
  }
 
  @override
  public void addmodelclasscomment(toplevelclass toplevelclass, introspectedtable introspectedtable) {
    string author = properties.getproperty("author");
    string dateformat = properties.getproperty("dateformat", "yyyy-mm-dd");
    simpledateformat dateformatter = new simpledateformat(dateformat);
 
    // 获取表注释
    string remarks = introspectedtable.getremarks();
 
    toplevelclass.addjavadocline("/**");
    toplevelclass.addjavadocline(" * " + remarks);
    toplevelclass.addjavadocline(" *");
    toplevelclass.addjavadocline(" * @author " + author);
    toplevelclass.addjavadocline(" * @date " + dateformatter.format(new date()));
    toplevelclass.addjavadocline(" */");
  }
 
  @override
  public void addfieldcomment(field field, introspectedtable introspectedtable, introspectedcolumn introspectedcolumn) {
    // 获取列注释
    string remarks = introspectedcolumn.getremarks();
    field.addjavadocline("/**");
    field.addjavadocline(" * " + remarks);
    field.addjavadocline(" */");
  }
}

因为我们现在要使用到我们自己自定义的 commentgenerator ,所以我们 通过代码的方式来操作 mbg

?
1
2
3
4
5
6
7
8
9
10
11
12
13
public class generator {
 
  public static void main( string[] args ) throws exception {
    list<string> warnings = new arraylist<>();
    file configfile = new file("generatorconfig.xml");
    configurationparser cp = new configurationparser(warnings);
    configuration config = cp.parseconfiguration(configfile);
    defaultshellcallback callback = new defaultshellcallback(true);
    mybatisgenerator mybatisgenerator = new mybatisgenerator(config, callback, warnings);
    mybatisgenerator.generate(null);
  }
 
}

然后配置 generatorconfig.xml设置我们自己的注释生成器:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<!doctype generatorconfiguration public
    "-//mybatis.org//dtd mybatis generator configuration 1.0//en"
    "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
 
<generatorconfiguration>
  <!-- 指定数据库驱动的jdbc驱动jar包的位置 -->
  <!-- 不再需要,因为 jar 包已经在 classpath 中
  <classpathentry location="./mysql-connector-java-5.1.40.jar" />
  -->
 
  <context id="mysql" defaultmodeltype="hierarchical" targetruntime="mybatis3simple" >
    ...
    
    <!-- 自定义注释生成器 -->
    <commentgenerator type="me.mizhoux.mbgcomment.mysqlcommentgenerator">
      <property name="author" value="michael chow"/>
      <property name="dateformat" value="yyyy/mm/dd"/>
    </commentgenerator>
    
    ...
  </context>
 
</generatorconfiguration>

完整的 maven 项目在 我的 github。现在,我们运行主类 generator,成功生成了数据库中的注释:

MyBatis Generator 自定义生成注释的方法

等等,好像有点不对劲!

MyBatis Generator 自定义生成注释的方法

类的注释怎么没有了!

想来应该是 jdbc 连接 mysql 的时候需要添加什么属性才能获取表的注释,上网查询,发现是 useinformationschema,需要将其设置为 true(看来是 mbg 给自己的 defaultcommentgenerator 开了小灶):

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?xml version="1.0" encoding="utf-8"?>
<!doctype generatorconfiguration public
    "-//mybatis.org//dtd mybatis generator configuration 1.0//en"
    "http://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
 
<generatorconfiguration>
  <context id="mysql" defaultmodeltype="hierarchical" targetruntime="mybatis3simple" >
    ...
    
    <!-- 自定义注释生成器 -->
    <commentgenerator type="me.mizhoux.mbgcomment.mysqlcommentgenerator">
      <property name="author" value="michael chow"/>
      <property name="dateformat" value="yyyy/mm/dd"/>
    </commentgenerator>
 
    <!-- 配置数据库连接 -->
    <jdbcconnection driverclass="com.mysql.jdbc.driver" connectionurl="jdbc:mysql://localhost:3306/test?characterencoding=utf-8" userid="root" password="123456">
       <!-- 设置 useinformationschema 属性为 true -->
       <property name="useinformationschema" value="true" />
    </jdbcconnection>
    
    ...
  </context>
</generatorconfiguration>

然后再次运行主类 generator

MyBatis Generator 自定义生成注释的方法

成功的生成了类主食和字段注释~

我这里并没有处理注释是多行文本的情况 —— 留给有兴趣的读者吧~

小项目地址:https://github.com/mizhoux/mbg-comment

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://segmentfault.com/a/1190000016525887