Mybatis Generator自定义扩展

最近在使用Mybatis Generator生成代码的时候,发现只能生成部分增删改查的方法。

研究了一下自定义扩展的方法。

本次扩展中使用的包:mysql-connector-java-5.1.30.jar,mybatis-generator-core-1.3.5.jar

项目已经添加到码云上

码云地址 :https://gitee.com/xxxcxy/support-generator

生成之后的Mapper文件

其中:find,list,pageList是自定义生成的。

public interface TaskModelMapper {
    int deleteByPrimaryKey(String taskid);

    int insert(TaskModel record);

    int insertSelective(TaskModel record);

    TaskModel selectByPrimaryKey(String taskid);

    int updateByPrimaryKeySelective(TaskModel record);

    int updateByPrimaryKey(TaskModel record);

    TaskModel find(TaskModel record);

    List<TaskModel> list(TaskModel record);

    List<TaskModel> pageList(TaskModel record);
}

生成之后的XML文件

其中:base_query,find,list,pageList是自定义生成的。

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="dao.TaskModelMapper">
  <resultMap id="BaseResultMap" type="model.TaskModel">
    <id column="taskid" jdbcType="VARCHAR" property="taskid" />
    <result column="types" jdbcType="INTEGER" property="types" />
    <result column="taskname" jdbcType="VARCHAR" property="taskname" />
    <result column="taskmx" jdbcType="VARCHAR" property="taskmx" />
    <result column="taskrcm" jdbcType="INTEGER" property="taskrcm" />
    <result column="taskwccs" jdbcType="INTEGER" property="taskwccs" />
    <result column="tasksx" jdbcType="INTEGER" property="tasksx" />
    <result column="tasktime" jdbcType="TIME" property="tasktime" />
    <result column="zt" jdbcType="INTEGER" property="zt" />
    <result column="jilx" jdbcType="INTEGER" property="jilx" />
    <result column="taskicon" jdbcType="VARCHAR" property="taskicon" />
    <result column="explain_id" jdbcType="VARCHAR" property="explainId" />
  </resultMap>
  <sql id="Base_Column_List">
    taskid, types, taskname, taskmx, taskrcm, taskwccs, tasksx, tasktime, zt, jilx, taskicon, 
    explain_id
  </sql>
  <select id="selectByPrimaryKey" parameterType="java.lang.String" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from task
    where taskid = #{taskid,jdbcType=VARCHAR}
  </select>
  <delete id="deleteByPrimaryKey" parameterType="java.lang.String">
    delete from task
    where taskid = #{taskid,jdbcType=VARCHAR}
  </delete>
  <insert id="insert" parameterType="model.TaskModel">
    insert into task (taskid, types, taskname, 
      taskmx, taskrcm, taskwccs, 
      tasksx, tasktime, zt, 
      jilx, taskicon, explain_id
      )
    values (#{taskid,jdbcType=VARCHAR}, #{types,jdbcType=INTEGER}, #{taskname,jdbcType=VARCHAR}, 
      #{taskmx,jdbcType=VARCHAR}, #{taskrcm,jdbcType=INTEGER}, #{taskwccs,jdbcType=INTEGER}, 
      #{tasksx,jdbcType=INTEGER}, #{tasktime,jdbcType=TIME}, #{zt,jdbcType=INTEGER}, 
      #{jilx,jdbcType=INTEGER}, #{taskicon,jdbcType=VARCHAR}, #{explainId,jdbcType=VARCHAR}
      )
  </insert>
  <insert id="insertSelective" parameterType="model.TaskModel">
    insert into task
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="taskid != null">
        taskid,
      </if>
      <if test="types != null">
        types,
      </if>
      <if test="taskname != null">
        taskname,
      </if>
      <if test="taskmx != null">
        taskmx,
      </if>
      <if test="taskrcm != null">
        taskrcm,
      </if>
      <if test="taskwccs != null">
        taskwccs,
      </if>
      <if test="tasksx != null">
        tasksx,
      </if>
      <if test="tasktime != null">
        tasktime,
      </if>
      <if test="zt != null">
        zt,
      </if>
      <if test="jilx != null">
        jilx,
      </if>
      <if test="taskicon != null">
        taskicon,
      </if>
      <if test="explainId != null">
        explain_id,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="taskid != null">
        #{taskid,jdbcType=VARCHAR},
      </if>
      <if test="types != null">
        #{types,jdbcType=INTEGER},
      </if>
      <if test="taskname != null">
        #{taskname,jdbcType=VARCHAR},
      </if>
      <if test="taskmx != null">
        #{taskmx,jdbcType=VARCHAR},
      </if>
      <if test="taskrcm != null">
        #{taskrcm,jdbcType=INTEGER},
      </if>
      <if test="taskwccs != null">
        #{taskwccs,jdbcType=INTEGER},
      </if>
      <if test="tasksx != null">
        #{tasksx,jdbcType=INTEGER},
      </if>
      <if test="tasktime != null">
        #{tasktime,jdbcType=TIME},
      </if>
      <if test="zt != null">
        #{zt,jdbcType=INTEGER},
      </if>
      <if test="jilx != null">
        #{jilx,jdbcType=INTEGER},
      </if>
      <if test="taskicon != null">
        #{taskicon,jdbcType=VARCHAR},
      </if>
      <if test="explainId != null">
        #{explainId,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="updateByPrimaryKeySelective" parameterType="model.TaskModel">
    update task
    <set>
      <if test="types != null">
        types = #{types,jdbcType=INTEGER},
      </if>
      <if test="taskname != null">
        taskname = #{taskname,jdbcType=VARCHAR},
      </if>
      <if test="taskmx != null">
        taskmx = #{taskmx,jdbcType=VARCHAR},
      </if>
      <if test="taskrcm != null">
        taskrcm = #{taskrcm,jdbcType=INTEGER},
      </if>
      <if test="taskwccs != null">
        taskwccs = #{taskwccs,jdbcType=INTEGER},
      </if>
      <if test="tasksx != null">
        tasksx = #{tasksx,jdbcType=INTEGER},
      </if>
      <if test="tasktime != null">
        tasktime = #{tasktime,jdbcType=TIME},
      </if>
      <if test="zt != null">
        zt = #{zt,jdbcType=INTEGER},
      </if>
      <if test="jilx != null">
        jilx = #{jilx,jdbcType=INTEGER},
      </if>
      <if test="taskicon != null">
        taskicon = #{taskicon,jdbcType=VARCHAR},
      </if>
      <if test="explainId != null">
        explain_id = #{explainId,jdbcType=VARCHAR},
      </if>
    </set>
    where taskid = #{taskid,jdbcType=VARCHAR}
  </update>
  <update id="updateByPrimaryKey" parameterType="model.TaskModel">
    update task
    set types = #{types,jdbcType=INTEGER},
      taskname = #{taskname,jdbcType=VARCHAR},
      taskmx = #{taskmx,jdbcType=VARCHAR},
      taskrcm = #{taskrcm,jdbcType=INTEGER},
      taskwccs = #{taskwccs,jdbcType=INTEGER},
      tasksx = #{tasksx,jdbcType=INTEGER},
      tasktime = #{tasktime,jdbcType=TIME},
      zt = #{zt,jdbcType=INTEGER},
      jilx = #{jilx,jdbcType=INTEGER},
      taskicon = #{taskicon,jdbcType=VARCHAR},
      explain_id = #{explainId,jdbcType=VARCHAR}
    where taskid = #{taskid,jdbcType=VARCHAR}
  </update>
  <sql id="base_query">
    <trim prefix="WHERE" prefixOverrides="AND | OR">
      <if test="null != taskid">
         and t.taskid = #{taskid,jdbcType=VARCHAR}
      </if>
      <if test="null != types">
         and t.types = #{types,jdbcType=INTEGER}
      </if>
      <if test="null != taskname">
         and t.taskname = #{taskname,jdbcType=VARCHAR}
      </if>
      <if test="null != taskmx">
         and t.taskmx = #{taskmx,jdbcType=VARCHAR}
      </if>
      <if test="null != taskrcm">
         and t.taskrcm = #{taskrcm,jdbcType=INTEGER}
      </if>
      <if test="null != taskwccs">
         and t.taskwccs = #{taskwccs,jdbcType=INTEGER}
      </if>
      <if test="null != tasksx">
         and t.tasksx = #{tasksx,jdbcType=INTEGER}
      </if>
      <if test="null != tasktime">
         and t.tasktime = #{tasktime,jdbcType=TIME}
      </if>
      <if test="null != zt">
         and t.zt = #{zt,jdbcType=INTEGER}
      </if>
      <if test="null != jilx">
         and t.jilx = #{jilx,jdbcType=INTEGER}
      </if>
      <if test="null != taskicon">
         and t.taskicon = #{taskicon,jdbcType=VARCHAR}
      </if>
      <if test="null != explainId">
         and t.explain_id = #{explainId,jdbcType=VARCHAR}
      </if>
    </trim>
  </sql>
  <select id="find" parameterType="model.TaskModel" resultMap="BaseResultMap">
    select t.* from task t
    <include refid="base_query" />
  </select>
  <select id="list" parameterType="model.TaskModel" resultMap="BaseResultMap">
    select t.* from task t
    <include refid="base_query" />
  </select>
  <select id="pageList" parameterType="model.TaskModel" resultMap="BaseResultMap">
    select t.* from task t
    <include refid="base_query" />
  </select>
</mapper>

generatorConfiguration.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>
    <classPathEntry location="D:\Repository\mysql\mysql-connector-java\5.1.30\mysql-connector-java-5.1.30.jar"/>
    <context id="sqlserverTables" targetRuntime="MyBatis3">
        <!-- 生成的pojo,将implements Serializable -->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"></plugin>
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
        <plugin type="org.mybatis.generator.plugins.CustomPlugin">
        </plugin>
        <commentGenerator>
            <!-- 是否去除自动生成的注释 true:是 : false:否 -->
            <property name="suppressAllComments" value="true" />
        </commentGenerator>

        <!-- 数据库链接URL、用户名、密码 -->
        <jdbcConnection driverClass="com.mysql.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/xxx"
            userId="root" password="root">
        </jdbcConnection>

        <!-- 默认false,把JDBC DECIMAL 和 NUMERIC 类型解析为 Integer true,把JDBC DECIMAL 和 
            NUMERIC 类型解析为java.math.BigDecimal -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false" />
        </javaTypeResolver>

        <!-- 生成model模型,对应的包路径,以及文件存放路径(targetProject),targetProject可以指定具体的路径,如./src/main/java, 
            也可以使用“MAVEN”来自动生成,这样生成的代码会在target/generatord-source目录下 -->
        <!--<javaModelGenerator targetPackage="com.joey.mybaties.test.pojo" targetProject="MAVEN"> -->
        <javaModelGenerator targetPackage="model"
            targetProject="src">
            <property name="enableSubPackages" value="true" />
            <!-- 从数据库返回的值被清理前后的空格 -->
            <property name="trimStrings" value="true" />
        </javaModelGenerator>

        <!--对应的mapper.xml文件 -->
        <sqlMapGenerator targetPackage="mappers"
            targetProject="src">
            <property name="enableSubPackages" value="true" />
        </sqlMapGenerator>

        <!-- 对应的Mapper接口类文件 -->
        <javaClientGenerator type="XMLMAPPER"
            targetPackage="dao" targetProject="src">
            <property name="enableSubPackages" value="true" />
        </javaClientGenerator>

        <!-- 列出要生成代码的所有表,这里配置的是不生成Example文件 -->
        <table tableName="xxx" domainObjectName="XxxModel"
            enableCountByExample="false" enableUpdateByExample="false"
            enableDeleteByExample="false" enableSelectByExample="false"
            selectByExampleQueryId="false">
            <property name="useActualColumnNames" value="false" />
        </table>
        

    </context>
</generatorConfiguration>

这个是自定义的插件

<plugin type="org.mybatis.generator.plugins.CustomPlugin">

 继承MyBatisGenerator 的 PluginAdapter

/**
 * 自定义插件
 * 增加
 * 1. find
 * 2. list
 * 3. pageList
 * 
 * 参考
 * @see org.mybatis.generator.plugins.ToStringPlugin
 * @author My
 */
public class CustomPlugin extends PluginAdapter {

    @Override
    public boolean validate(List<String> warnings) {
        return true;
    }
    
    @Override
    public boolean sqlMapDocumentGenerated(Document document, IntrospectedTable introspectedTable) {
        AbstractXmlElementGenerator elementGenerator = new CustomAbstractXmlElementGenerator();
        elementGenerator.setContext(context);
        elementGenerator.setIntrospectedTable(introspectedTable);
        elementGenerator.addElements(document.getRootElement());
        return super.sqlMapDocumentGenerated(document, introspectedTable);
    }

    @Override
    public boolean clientGenerated(Interface interfaze, TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        AbstractJavaMapperMethodGenerator methodGenerator = new CustomJavaMapperMethodGenerator();
        methodGenerator.setContext(context);
        methodGenerator.setIntrospectedTable(introspectedTable);
        methodGenerator.addInterfaceElements(interfaze);
        return super.clientGenerated(interfaze, topLevelClass, introspectedTable);
    }
}

 CustomAbstractXmlElementGenerator 代码

public class CustomAbstractXmlElementGenerator extends AbstractXmlElementGenerator {

    @Override
    public void addElements(XmlElement parentElement) {
        // 增加base_query
        XmlElement sql = new XmlElement("sql");
        sql.addAttribute(new Attribute("id", "base_query"));
        //在这里添加where条件
        XmlElement selectTrimElement = new XmlElement("trim"); //设置trim标签
        selectTrimElement.addAttribute(new Attribute("prefix", "WHERE"));  
        selectTrimElement.addAttribute(new Attribute("prefixOverrides", "AND | OR")); //添加where和and
        StringBuilder sb = new StringBuilder();
        for(IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) {
            XmlElement selectNotNullElement = new XmlElement("if"); //$NON-NLS-1$
            sb.setLength(0);
            sb.append("null != ");
            sb.append(introspectedColumn.getJavaProperty());
            selectNotNullElement.addAttribute(new Attribute("test", sb.toString()));
            sb.setLength(0);
            // 添加and
            sb.append(" and ");
            // 添加别名t
            sb.append("t.");
            sb.append(MyBatis3FormattingUtilities.getEscapedColumnName(introspectedColumn));
            // 添加等号
            sb.append(" = ");
            sb.append(MyBatis3FormattingUtilities.getParameterClause(introspectedColumn));
            selectNotNullElement.addElement(new TextElement(sb.toString()));
            selectTrimElement.addElement(selectNotNullElement);
        }
        sql.addElement(selectTrimElement);
        parentElement.addElement(sql);
        
        // 公用select
        sb.setLength(0);
        sb.append("select ");
        sb.append("t.* ");
        sb.append("from ");
        sb.append(introspectedTable.getFullyQualifiedTableNameAtRuntime());
        sb.append(" t");
        TextElement selectText = new TextElement(sb.toString());
        
        // 公用include
        XmlElement include = new XmlElement("include");
        include.addAttribute(new Attribute("refid", "base_query"));
        
        // 增加find
        XmlElement find = new XmlElement("select");
        find.addAttribute(new Attribute("id", "find"));
        find.addAttribute(new Attribute("resultMap", "BaseResultMap"));
        find.addAttribute(new Attribute("parameterType", introspectedTable.getBaseRecordType()));
        find.addElement(selectText);
        find.addElement(include);
        parentElement.addElement(find);
        
        // 增加list
        XmlElement list = new XmlElement("select");
        list.addAttribute(new Attribute("id", "list"));
        list.addAttribute(new Attribute("resultMap", "BaseResultMap"));
        list.addAttribute(new Attribute("parameterType", introspectedTable.getBaseRecordType()));
        list.addElement(selectText);
        list.addElement(include);
        parentElement.addElement(list);
        
        // 增加pageList
        XmlElement pageList = new XmlElement("select");
        pageList.addAttribute(new Attribute("id", "pageList"));
        pageList.addAttribute(new Attribute("resultMap", "BaseResultMap"));
        pageList.addAttribute(new Attribute("parameterType", introspectedTable.getBaseRecordType()));
        pageList.addElement(selectText);
        pageList.addElement(include);
        parentElement.addElement(pageList);
    }

}

CustomJavaMapperMethodGenerator 代码

public class CustomJavaMapperMethodGenerator extends AbstractJavaMapperMethodGenerator {

    @Override
    public void addInterfaceElements(Interface interfaze) {
        
        addInterfaceFind(interfaze);
        addInterfaceList(interfaze);
        addInterfacePageList(interfaze);
    }
    
    private void addInterfaceFind(Interface interfaze) {
        // 先创建import对象
        Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();
        // 添加Lsit的包
        importedTypes.add(FullyQualifiedJavaType.getNewListInstance());
        // 创建方法对象
        Method method = new Method();
        // 设置该方法为public
        method.setVisibility(JavaVisibility.PUBLIC);
        // 设置返回类型是List
        FullyQualifiedJavaType returnType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        // 方法对象设置返回类型对象
        method.setReturnType(returnType);
        // 设置方法名称为我们在IntrospectedTable类中初始化的 “selectByObject”
        method.setName("find");

        // 设置参数类型是对象
        FullyQualifiedJavaType parameterType;
        parameterType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        // import参数类型对象
        importedTypes.add(parameterType);
        // 为方法添加参数,变量名称record
        method.addParameter(new Parameter(parameterType, "record")); //$NON-NLS-1$
        //
        addMapperAnnotations(interfaze, method);
        context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);
        if (context.getPlugins().clientSelectByPrimaryKeyMethodGenerated(method, interfaze, introspectedTable)) {
            interfaze.addImportedTypes(importedTypes);
            interfaze.addMethod(method);
        }
    }
    
    private void addInterfaceList(Interface interfaze) {
        // 先创建import对象
        Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();
        // 添加Lsit的包
        importedTypes.add(FullyQualifiedJavaType.getNewListInstance());
        // 创建方法对象
        Method method = new Method();
        // 设置该方法为public
        method.setVisibility(JavaVisibility.PUBLIC);
        // 设置返回类型是List
        FullyQualifiedJavaType returnType = FullyQualifiedJavaType.getNewListInstance();
        FullyQualifiedJavaType listType;
        // 设置List的类型是实体类的对象
        listType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        importedTypes.add(listType);
        // 返回类型对象设置为List
        returnType.addTypeArgument(listType);
        // 方法对象设置返回类型对象
        method.setReturnType(returnType);
        // 设置方法名称为我们在IntrospectedTable类中初始化的 “selectByObject”
        method.setName("list");

        // 设置参数类型是对象
        FullyQualifiedJavaType parameterType;
        parameterType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        // import参数类型对象
        importedTypes.add(parameterType);
        // 为方法添加参数,变量名称record
        method.addParameter(new Parameter(parameterType, "record")); //$NON-NLS-1$
        //
        addMapperAnnotations(interfaze, method);
        context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);
        if (context.getPlugins().clientSelectByPrimaryKeyMethodGenerated(method, interfaze, introspectedTable)) {
            interfaze.addImportedTypes(importedTypes);
            interfaze.addMethod(method);
        }
    }
    
    private void addInterfacePageList(Interface interfaze) {
        // 先创建import对象
        Set<FullyQualifiedJavaType> importedTypes = new TreeSet<FullyQualifiedJavaType>();
        // 添加Lsit的包
        importedTypes.add(FullyQualifiedJavaType.getNewListInstance());
        // 创建方法对象
        Method method = new Method();
        // 设置该方法为public
        method.setVisibility(JavaVisibility.PUBLIC);
        // 设置返回类型是List
        FullyQualifiedJavaType returnType = FullyQualifiedJavaType.getNewListInstance();
        FullyQualifiedJavaType listType;
        // 设置List的类型是实体类的对象
        listType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        importedTypes.add(listType);
        // 返回类型对象设置为List
        returnType.addTypeArgument(listType);
        // 方法对象设置返回类型对象
        method.setReturnType(returnType);
        // 设置方法名称为我们在IntrospectedTable类中初始化的 “selectByObject”
        method.setName("pageList");

        // 设置参数类型是对象
        FullyQualifiedJavaType parameterType;
        parameterType = new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());
        // import参数类型对象
        importedTypes.add(parameterType);
        // 为方法添加参数,变量名称record
        method.addParameter(new Parameter(parameterType, "record")); //$NON-NLS-1$
        //
        addMapperAnnotations(interfaze, method);
        context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);
        if (context.getPlugins().clientSelectByPrimaryKeyMethodGenerated(method, interfaze, introspectedTable)) {
            interfaze.addImportedTypes(importedTypes);
            interfaze.addMethod(method);
        }
    }

    public void addMapperAnnotations(Interface interfaze, Method method) {
    }
}

 执行代码

public class TestGenerator {

    private static File configFile;
    static {
        String path = System.getProperty("user.dir").concat("\\src\\resource\\generatorConfiguration.xml");
        System.out.println(path);
        configFile = new File(path);
    }
    
    public static void main(String[] args)
            throws IOException,
                    XMLParserException,
                    InvalidConfigurationException,
                    SQLException,
                    InterruptedException {
        
        if(!configFile.exists()) {
            System.out.println("配置文件不存在");
            return;
        }
        
        List<String> warnings = new ArrayList<String>();
        boolean overwrite = true;
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(configFile);
        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        myBatisGenerator.generate(null);
    }
}

自此,扩展结束。 

作者:Se7end

声明:本博客文章为原创,只代表本人在工作学习中某一时间内总结的观点或结论。转载时请在文章页面明显位置给出原文链接。
原文地址:https://www.cnblogs.com/se7end/p/9293755.html