mybatis-generator-maven 插件与 lombok 的引入

插件介绍

mybatis通过xml配置文件将java工程中的对象与数据库建立联系, 但是当数据库中的表过多之后, 编写xml就是一件令人头疼的事. 使用 mybatis-generator 插件可以减去编写xml,pojo,dao的烦恼. 该插件的特点:

  1. 生成 pojo 与 数据库结构对应. 每个pojo类对应数据库中的一张表, 每个字段对应表中的一个属性
  2. 会为每个pojo自动生成getter/setter方法
  3. 自动生成 mapper.xml , 提供了一些基础的CRUD sql 语句
  4. 会为每个pojo生成对应的dao, 并提供一些最基本的CRUD操作

使用方法

1 引入依赖

# dependencies 节点下
<dependency>
  <groupId>org.mybatis.generator</groupId>
  <artifactId>mybatis-generator-core</artifactId>
  <version>1.3.7</version>
</dependency>
# plugins 节点下
<plugin>
  <groupId>org.mybatis.generator</groupId>
  <artifactId>mybatis-generator-maven-plugin</artifactId>
  <version>1.3.7</version>
  <configuration>
    <verbose>true</verbose>
    <overwrite>true</overwrite>
  </configuration>
</plugin>

2 编写配置文件 generatorConfig.xml , 在生成代码的时候插件会读取配置文件。一般来说,在下面的配置文件中你需要修改 数据库驱动jar地址、数据库连接 url、用户名、密码、生成的Bean存放位置、生成的mapper的位置、需要生成的表。

<?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>
    <!-- 配置文件,放在resource目录下即可 -->
    <!--数据库驱动个人配置-->
    <classPathEntry
            location="E:\JavaProject\mysql-connector-java-8.0.18.jar"/>
    <context id="MysqlTables" targetRuntime="MyBatis3">
        <property name="autoDelimitKeywords" value="true"/>
        <!--可以使用``包括字段名,避免字段名与sql保留字冲突报错-->
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <!-- optional,旨在创建class时,对注释进行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库链接地址账号密码-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;serverTimezone=UTC"
                        userId="root"
                        password="123456">
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>
        <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!--生成Bean类存放位置-->
        <javaModelGenerator targetPackage="im.yzh.mymyblog.model.pojo"
                            targetProject="src/main/java">
            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="true"/>
            <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
            <property name="trimStrings" value="true"/>
            <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>
        <!--生成mapper映射文件存放位置-->
        <sqlMapGenerator targetPackage="mappers" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!--生成Dao类存放位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="im.yzh.mymyblog.model.dao"
                             targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!--生成对应表及类名-->
        <table schema="root" tableName="post" domainObjectName="Post"
               enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false">
        </table>
        <table tableName="comment" domainObjectName="Comment" enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false">
        </table>
       
    </context>
</generatorConfiguration>

3 点击 generator 即可生成

4 生成的效果参考

存在的问题: 假如我们想要在pojo中使用lombok怎么办? 生成的时候只带了getter/setter, 一个个的删除再添加lombok好像也不是明智的行为? 而且 generatorConfig 中并不提供lombok的配置项.

如何引入lombok

我们需要对 mybatis-generator 插件本身源文件进行修改来达到引入lombok的效果.

1 编写插件, 自己的 LombokPlugin插件: 注意包名必须为 org.mybatis.generator.plugins

package org.mybatis.generator.plugins;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.PluginAdapter;
import org.mybatis.generator.api.dom.java.Interface;
import org.mybatis.generator.api.dom.java.Method;
import org.mybatis.generator.api.dom.java.TopLevelClass;

public class LombokPlugin extends PluginAdapter {

	@Override
	public boolean validate(List<String> list) {
		return true;
	}

	@Override
	public boolean modelBaseRecordClassGenerated(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		//添加domain的import
		topLevelClass.addImportedType("lombok.Data");
		topLevelClass.addImportedType("lombok.Builder");
		topLevelClass.addImportedType("lombok.NoArgsConstructor");
		topLevelClass.addImportedType("lombok.AllArgsConstructor");

		//添加domain的注解
		topLevelClass.addAnnotation("@Data");
		topLevelClass.addAnnotation("@Builder");
		topLevelClass.addAnnotation("@NoArgsConstructor");
		topLevelClass.addAnnotation("@AllArgsConstructor");

		//添加domain的注释
		topLevelClass.addJavaDocLine("/**");
		topLevelClass.addJavaDocLine("* Created by Mybatis Generator on " + date2Str(new Date()));
		topLevelClass.addJavaDocLine("*/");

		return true;
	}

	@Override
	public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
		//Mapper文件的注释
		interfaze.addJavaDocLine("/**");
		interfaze.addJavaDocLine("* Created by Mybatis Generator on " + date2Str(new Date()));
		interfaze.addJavaDocLine("*/");
		return true;
	}

	@Override
	public boolean modelSetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
		//不生成getter
		return false;
	}

	@Override
	public boolean modelGetterMethodGenerated(Method method, TopLevelClass topLevelClass, IntrospectedColumn introspectedColumn, IntrospectedTable introspectedTable, ModelClassType modelClassType) {
		//不生成setter
		return false;
	}

	private String date2Str(Date date) {
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
		return sdf.format(date);
	}
}

2 编译得到 class 文件,将该文件复制到 mybatis-generator-core-1.3.7.jar 下的 org\mybatis\generator\plugins\ 目录下,该jar包存放在maven本地仓库中

3 修改 generatorConfig.xml  , 在 context 节点下, property 子节点后添加

<!--添加lombok插件配置项-->
<plugin type="org.mybatis.generator.plugins.LombokPlugin">
  <property name="hasLombok" value="true"/>
</plugin>

最终的 generatorConfig.xml 参考

<?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>
    <!-- 配置文件,放在resource目录下即可 -->
    <!--数据库驱动个人配置-->
    <classPathEntry
            location="E:\JavaLearning\mybatis-generator-lombok-test\mysql-connector-java-8.0.18.jar"/>
    
    <context id="MysqlTables" targetRuntime="MyBatis3">
        
        <property name="autoDelimitKeywords" value="true"/>
        <!--可以使用``包括字段名,避免字段名与sql保留字冲突报错-->
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <!--添加lombok插件配置项-->
        <plugin type="org.mybatis.generator.plugins.LombokPlugin">
            <property name="hasLombok" value="true"/>
        </plugin>
        <!-- optional,旨在创建class时,对注释进行控制 -->
        <commentGenerator>
            <property name="suppressDate" value="true"/>
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!--数据库链接地址账号密码-->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://127.0.0.1:3306/myblog?useUnicode=true&amp;characterEncoding=UTF-8&amp;zeroDateTimeBehavior=convertToNull&amp;serverTimezone=UTC"
                        userId="root"
                        password="123456">
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>
        <!-- 非必需,类型处理器,在数据库类型和java类型之间的转换控制-->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!--生成Model类存放位置-->
        <javaModelGenerator targetPackage="com.example.mybatisgeneratorlomboktest.pojo"
                            targetProject="src/main/java">
            <!-- 是否允许子包,即targetPackage.schemaName.tableName -->
            <property name="enableSubPackages" value="true"/>
            <!-- 是否对类CHAR类型的列的数据进行trim操作 -->
            <property name="trimStrings" value="true"/>
            <!-- 建立的Model对象是否 不可改变  即生成的Model对象不会有 setter方法,只有构造方法 -->
            <property name="immutable" value="false"/>
        </javaModelGenerator>
        <!--生成mapper映射文件存放位置-->
        <sqlMapGenerator targetPackage="mappers" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>
        <!--生成Dao类存放位置-->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.mybatisgeneratorlomboktest.dao"
                             targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>
        <!--生成对应表及类名-->
        <table schema="root" tableName="post" domainObjectName="Post"
               enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false">
        </table>
        <table tableName="comment" domainObjectName="Comment" enableCountByExample="false"
               enableUpdateByExample="false" enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false">
        </table>
    </context>
</generatorConfiguration>

生成的pojo效果参考

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class Comment {
    private Long id;
    private String nickname;

    private String email;

    private String content;
}