mybatis generator自定义sql以及方法生成(三)

前言

在mybatis generator自定义sql基本和自定义命名风格的流程一样,当然也需要我们去写代码,完成整个扩展

扩展方法与sql

先修改org.mybatis.generator.api.IntrospectedTable.java类,在InternalAttribute增加自己需扩展的自定义方法枚举值,如想新增一个 selectList方法,定义一个ATTR_SELECT_LIST枚举值

protected enum InternalAttribute {
          
        ---省略部分代码---

        ATTR_SELECT_LIST
    }

IntrospectedTable.java类中 新增一个setSelectListStatementIdgetSelectListStatementId方法,在calculateXmlAttributes方法中调用setSelectListStatementId方法设置需要生成的方法名

    protected void calculateXmlAttributes() {
        ---省略部分代码---

        setSelectListStatementId("selectList");
    }

    public void setSelectListStatementId(String s){
        internalAttributes.put(InternalAttribute.ATTR_SELECT_LIST,s);
    }

    public String getSelectListStatementId() {
        return internalAttributes.get(InternalAttribute.ATTR_SELECT_LIST);
    }

org.mybatis.generator.codegen.mybatis3.xmlmapper新建一个extra包,新建一个SelectListElementGenerator.java类,这个类的作用就是在mapper.xml中实现自定义的sql语句

public class SelectListElementGenerator extends AbstractXmlElementGenerator {

    public SelectListElementGenerator(){
        super();
    }

    @Override
    public void addElements(XmlElement parentElement) {
        // 添加xml节点 - <select></select>
        XmlElement answer = new XmlElement("select"); //$NON-NLS-1$

        // select 标签中id属性
        // 获取introspectedTable类中自己定义的方法名 --》setSelectListStatementId("selectList");
        answer.addAttribute(new Attribute(
                "id", introspectedTable.getSelectListStatementId())); //$NON-NLS-1$

        // select 标签中resultMap属性
        answer.addAttribute(new Attribute("resultMap", //$NON-NLS-1$
                introspectedTable.getBaseResultMapId()));

        // select 标签中parameterType属性
        answer.addAttribute(new Attribute("parameterType", //$NON-NLS-1$
                introspectedTable.getBaseRecordType()));

        // 添加注释
        context.getCommentGenerator().addComment(answer);

        // 拼接sql语句
        StringBuilder sb = new StringBuilder();
        sb.append("select "); //$NON-NLS-1$

        // 拼接 select
        answer.addElement(new TextElement(sb.toString()));

        // 拼接 需查询的字段
        answer.addElement(getBaseColumnListElement());

        // 是否有blob字段
        if (introspectedTable.hasBLOBColumns()) {
            answer.addElement(new TextElement(",")); //$NON-NLS-1$
            answer.addElement(getBlobColumnListElement());
        }
        // 设置StringBuilder长度为0 -- 清空stringBuilder
        sb.setLength(0);

        // 拼接from
        sb.append("from "); //$NON-NLS-1$

        // 拼接表名
        sb.append(introspectedTable
                .getAliasedFullyQualifiedTableNameAtRuntime());
        answer.addElement(new TextElement(sb.toString()));

        //添加where条件
        XmlElement whereXmlElement = new XmlElement("where");
        answer.addElement(whereXmlElement);

        //循环拼接所有的条件列
        for (IntrospectedColumn introspectedColumn : introspectedTable.getAllColumns()) {
            // 拼接 if判断
            XmlElement selectNotNullElement = new XmlElement("if"); //$NON-NLS-1$
            sb.setLength(0);

            // java对象字段
            sb.append(introspectedColumn.getJavaProperty());
            sb.append(" != null ");

            // 如果是字符型 增加 and column != ''
            if (introspectedColumn.isJdbcCharacterColumn()){
                sb.append("and ");

                // java对象字段
                sb.append(introspectedColumn.getJavaProperty());
                sb.append(" != '' ");
            }
            selectNotNullElement.addAttribute(new Attribute("test", sb.toString()));
            sb.setLength(0);

            // 拼接实际的 赋值 “... where and 数据库字段 = java对象字段”
            sb.append(" and "); //添加and
            sb.append(MyBatis3FormattingUtilities
                    .getEscapedColumnName(introspectedColumn));
            sb.append(" = "); //添加等号
            sb.append(MyBatis3FormattingUtilities
                    .getParameterClause(introspectedColumn));
            selectNotNullElement.addElement(new TextElement(sb.toString()));
            whereXmlElement.addElement(selectNotNullElement);
        }

        parentElement.addElement(answer);
    }
}

org.mybatis.generator.codegen.mybatis3.xmlmapper.XMLMapperGenerator.java中新增addSelectListElement方法,方法中调用新建的SelectListElementGenerator类,同时在getSqlMapElement方法中调用addSelectListElement方法

 protected XmlElement getSqlMapElement() {
        ---省略代码---

        // mapper.xml中 -> 生成resultMap 标签内容
        addResultMapWithoutBLOBsElement(answer);

        // mapper.xml中 -> 生成sql 标签内容
        addBaseColumnListElement(answer);

        // mapper.xml中 -> 生成 select标签 id = selectOne
        addSelectByPrimaryKeyElement(answer);

        // mapper.xml中 -> 生成 insert标签 id = insert
        addInsertSelectiveElement(answer);

        // mapper.xml中 -> 生成 update标签 id = update
        addUpdateByPrimaryKeySelectiveElement(answer);

        // mapper.xml中 -> 生成 delete标签 id = delete
        addDeleteByPrimaryKeyElement(answer);

        // mapper.xml中 -> 生成 select标签 id = selectList
        addSelectListElement(answer);

        return answer;
    }

protected void addSelectListElement(XmlElement parentElement) {
        if (introspectedTable.getRules().generateSelectByPrimaryKey()) {
            AbstractXmlElementGenerator elementGenerator = new SelectListElementGenerator();
            initializeAndExecuteGenerator(elementGenerator, parentElement);
        }
    }

上面的步骤完成后,运行测试类,生成的mapper.xml文件中已经有了扩展sql

<?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="com.cloud.dao.mapper.SysUserMapper">
  <resultMap id="BaseResultMap" type="com.cloud.dao.po.SysUser">
    <id column="id" jdbcType="VARCHAR" property="id" />
    <result column="username" jdbcType="VARCHAR" property="username" />
    <result column="password" jdbcType="VARCHAR" property="password" />
    <result column="nickname" jdbcType="VARCHAR" property="nickname" />
    <result column="dep_id" jdbcType="INTEGER" property="depId" />
    <result column="pos_id" jdbcType="VARCHAR" property="posId" />
  </resultMap>
  <sql id="Base_Column_List">
    id, username, password, nickname, dep_id, pos_id
  </sql>
  <select id="selectOne" parameterType="java.lang.String" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from t_sys_user
    where id = #{id,jdbcType=VARCHAR}
  </select>
  <insert id="insert" parameterType="com.cloud.dao.po.SysUser">
    insert into t_sys_user
    <trim prefix="(" suffix=")" suffixOverrides=",">
      <if test="id != null">
        id,
      </if>
      <if test="username != null">
        username,
      </if>
      <if test="password != null">
        password,
      </if>
      <if test="nickname != null">
        nickname,
      </if>
      <if test="depId != null">
        dep_id,
      </if>
      <if test="posId != null">
        pos_id,
      </if>
    </trim>
    <trim prefix="values (" suffix=")" suffixOverrides=",">
      <if test="id != null">
        #{id,jdbcType=VARCHAR},
      </if>
      <if test="username != null">
        #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null">
        #{password,jdbcType=VARCHAR},
      </if>
      <if test="nickname != null">
        #{nickname,jdbcType=VARCHAR},
      </if>
      <if test="depId != null">
        #{depId,jdbcType=INTEGER},
      </if>
      <if test="posId != null">
        #{posId,jdbcType=VARCHAR},
      </if>
    </trim>
  </insert>
  <update id="update" parameterType="com.cloud.dao.po.SysUser">
    update t_sys_user
    <set>
      <if test="username != null">
        username = #{username,jdbcType=VARCHAR},
      </if>
      <if test="password != null">
        password = #{password,jdbcType=VARCHAR},
      </if>
      <if test="nickname != null">
        nickname = #{nickname,jdbcType=VARCHAR},
      </if>
      <if test="depId != null">
        dep_id = #{depId,jdbcType=INTEGER},
      </if>
      <if test="posId != null">
        pos_id = #{posId,jdbcType=VARCHAR},
      </if>
    </set>
    where id = #{id,jdbcType=VARCHAR}
  </update>
  <delete id="delete" parameterType="java.lang.String">
    delete from t_sys_user
    where id = #{id,jdbcType=VARCHAR}
  </delete>
  <select id="selectList" parameterType="com.cloud.dao.po.SysUser" resultMap="BaseResultMap">
    select 
    <include refid="Base_Column_List" />
    from t_sys_user
    <where>
      <if test="id != null and id != '' ">
         and id = #{id,jdbcType=VARCHAR}
      </if>
      <if test="username != null and username != '' ">
         and username = #{username,jdbcType=VARCHAR}
      </if>
      <if test="password != null and password != '' ">
         and password = #{password,jdbcType=VARCHAR}
      </if>
      <if test="nickname != null and nickname != '' ">
         and nickname = #{nickname,jdbcType=VARCHAR}
      </if>
      <if test="depId != null ">
         and dep_id = #{depId,jdbcType=INTEGER}
      </if>
      <if test="posId != null and posId != '' ">
         and pos_id = #{posId,jdbcType=VARCHAR}
      </if>
    </where>
  </select>
</mapper>

在mapper.xml中已经成功生成了自定义sql,紧接着去完成方法的生成,在org.mybatis.generator.codegen.mybatis3.javamapper.elements包新建extra包,同时新增SelectListExtraMethodGenerator.java类。在这个类中我们完成对mapper方法的组装

public class SelectListExtraMethodGenerator extends AbstractJavaMapperMethodGenerator {

    @Override
    public void addInterfaceElements(Interface interfaze) {
        // 组装方法[ 方法权限 返回类型 方法名 输入参数]
        // selectList
        Method method = new Method(introspectedTable.getSelectListStatementId());
        method.setVisibility(JavaVisibility.PUBLIC);
        method.setAbstract(true);

        /* 导入相对应数据类型的包 */
        Set<FullyQualifiedJavaType> importedTypes = new TreeSet<>();

        /* 数据返回结果-List<Bean> */
        FullyQualifiedJavaType returnType = FullyQualifiedJavaType.getNewListInstance();

        FullyQualifiedJavaType listType =
                new FullyQualifiedJavaType(introspectedTable.getBaseRecordType());

        // importedType -> 导入对象的包
        // import xxx.xxx
        importedTypes.add(returnType);
        importedTypes.add(listType);

        // List<Object>
        returnType.addTypeArgument(listType);
        method.setReturnType(returnType);

        /* 请求参数 */
        FullyQualifiedJavaType parameterType = introspectedTable.getRules().calculateAllFieldsClass();
        importedTypes.add(parameterType);

        /* 设置请求参数 (Param param) */
        method.addParameter(new Parameter(parameterType, "param")); //$NON-NLS-1$

        /* 生成注释 */
        context.getCommentGenerator().addGeneralMethodComment(method, introspectedTable);

        if (context.getPlugins().clientSelectByPrimaryKeyMethodGenerated(method, interfaze, introspectedTable)) {
            interfaze.addImportedTypes(importedTypes);
            interfaze.addMethod(method);
        }
    }
}

org.mybatis.generator.codegen.mybatis3.javamapper.JavaMapperGenerator.java中新增addSelectListeMethod方法,方法中new SelectListExtraMethodGenerator(),最后在getCompilationUnits中调用addSelectListeMethod方法

@Override
    public List<CompilationUnit> getCompilationUnits() {
        ---省略部分代码---

//        addCountByExampleMethod(interfaze);
//        addDeleteByExampleMethod(interfaze);
//        addDeleteByPrimaryKeyMethod(interfaze);
//        addInsertMethod(interfaze);
//        addInsertSelectiveMethod(interfaze);
//        addSelectByExampleWithBLOBsMethod(interfaze);
//        addSelectByExampleWithoutBLOBsMethod(interfaze);
//        addSelectByPrimaryKeyMethod(interfaze);
//        addUpdateByExampleSelectiveMethod(interfaze);
//        addUpdateByExampleWithBLOBsMethod(interfaze);
//        addUpdateByExampleWithoutBLOBsMethod(interfaze);
//        addUpdateByPrimaryKeySelectiveMethod(interfaze);
//        addUpdateByPrimaryKeyWithBLOBsMethod(interfaze);
//        addUpdateByPrimaryKeyWithoutBLOBsMethod(interfaze);

        addDeleteByPrimaryKeyMethod(interfaze);
        addInsertSelectiveMethod(interfaze);
        addUpdateByPrimaryKeySelectiveMethod(interfaze);
        addSelectByPrimaryKeyMethod(interfaze);
        addSelectListeMethod(interfaze);

        ---省略部分代码---

        return answer;
    }

protected void addSelectListeMethod(Interface interfaze) {
        if (introspectedTable.getRules().generateSelectByPrimaryKey()) {
            AbstractJavaMapperMethodGenerator methodGenerator = new SelectListExtraMethodGenerator();
            initializeAndExecuteGenerator(methodGenerator, interfaze);
        }
    }

最后运行下测试类,selectList方法也已经有了

public interface SysUserMapper {
    int delete(String id);

    int insert(SysUser row);

    int update(SysUser row);

    SysUser selectOne(String id);

    List<SysUser> selectList(SysUser param);
}

扩展一

mapper.xml中的 xml节点间隔太紧凑了,在他们中间增加一个空行,修改org.mybatis.generator.codegen.mybatis3.xmlmapper.XMLMapperGenerator.java中的initializeAndExecuteGenerator即可

protected void initializeAndExecuteGenerator(AbstractXmlElementGenerator elementGenerator,
                                                 XmlElement parentElement) {
        elementGenerator.setContext(context);
        elementGenerator.setIntrospectedTable(introspectedTable);
        elementGenerator.setProgressCallback(progressCallback);
        elementGenerator.setWarnings(warnings);
        // 标签与标签之间,增加空白隔行
        parentElement.addElement(new TextElement(""));
        elementGenerator.addElements(parentElement);
    }

扩展二

mybatis-generator生成的注释实在是不太友好,自己重新定义了mapper方法的注释以及po类注释

org.mybatis.generator.internal包中新建一个extra包,在extra包下新建NotesCommentGenerator.java类,重新定义注释内容

public class NotesCommentGenerator extends DefaultCommentGenerator {


    // 在mapper方法上添加注释
    @Override
    public void addGeneralMethodComment(Method method, IntrospectedTable introspectedTable) {
        method.addJavaDocLine("/**"); //$NON-NLS-1$
        // 方法名
        method.addJavaDocLine(" * " + method.getName());
        // 输入参数
        if (method.getParameters() != null && method.getParameters().size() > 0){
            for (Parameter parameter : method.getParameters()){
                method.addJavaDocLine(" * @param " + parameter.getName());
            }
        }
        // 返回结果
        method.addJavaDocLine(" * @return " + method.getReturnType().get());
        method.addJavaDocLine(" */"); //$NON-NLS-1$
    }

    // 在po类上添加注释
    @Override
    public void addModelClassComment(TopLevelClass topLevelClass, IntrospectedTable introspectedTable) {
        topLevelClass.addJavaDocLine("/**");
        String remark = introspectedTable.getRemarks();
        if (remark != null && !"".equals(remark)) {
            topLevelClass.addJavaDocLine(" * " + remark);
        }
        topLevelClass.addJavaDocLine(" * ");
        // 作者
        topLevelClass.addJavaDocLine(" * " + "@author " + getAuthor());
        // 日期
        topLevelClass.addJavaDocLine(" * " + "@date " + getDateContent());
        topLevelClass.addJavaDocLine(" */");
    }

    // 在po类属性上添加注释
    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable, IntrospectedColumn introspectedColumn) {
        // 字段注释 - 数据库中对字段的说明
        String remark = introspectedColumn.getRemarks();
        if (remark != null && !"".equals(remark)) {
            field.addJavaDocLine("/**");
            field.addJavaDocLine(" * " + remark);
            field.addJavaDocLine(" */");
        }
    }

}

 在org.mybatis.generator.internal.DefaultCommentGenerator.java类中声明以下属性,同时在addConfigurationProperties方法中对新声明的属性赋值

    /** 扩展属性 - 生成中文注释 */
    private String author;
    private String date;
    private String dateContent;
    private static final String DEFAULT_DATE_FORMAT = "yyyy/MM/dd";


    @Override
    public void addConfigurationProperties(Properties props) {
        this.properties.putAll(props);

        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);
        }

        // 从配置文件中读取值
        author = properties.getProperty("author");
        author = author == null ? "" : author;
        date = properties.getProperty("date");
        date = date == null ? DEFAULT_DATE_FORMAT : date;
        SimpleDateFormat sf = new SimpleDateFormat(date);
        dateContent = sf.format(new Date());
    }

    public String getAuthor() {
        return author;
    }

    public String getDateContent() {
        return dateContent;
    }

修改后的mybatis-generator-config.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="E:\development\repository\mysql\mysql-connector-java\8.0.28\mysql-connector-java-8.0.28.jar"/>

    <context id="context" targetRuntime="MyBatis3">
        <commentGenerator type="org.mybatis.generator.internal.extra.NotesCommentGenerator">
            <!-- 文件编码 -->
            <property name="javaFileEncoding" value="UTF-8" />
            <!-- 忽略所有注解,使用自定义的注解生成 -->
            <property name="suppressAllComments" value="true" />
            <!-- 作者 -->
            <property name="author" value="cloud" />
            <!-- 时间 value值为时间格式-->
            <property name="date" value="yyyy/MM/dd" />
        </commentGenerator>

        <!-- 数据库的相关配置 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc-url"
                        userId="name"
                        password="password"/>
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!-- 实体类生成的位置 -->
        <javaModelGenerator targetPackage="com.cloud.dao.po"
                            targetProject="E:/local_project/idea/example/core/mybatis-example/src/main/java">
            <property name="enableSubPackages" value="false"/>
            <property name="trimStrings" value="true"/>
        </javaModelGenerator>
        <!-- *Mapper.xml 文件的位置 -->
        <sqlMapGenerator targetPackage="mapper"
                         targetProject="E:/local_project/idea/example/core/mybatis-example/src/main/resources">
            <property name="enableSubPackages" value="false"/>
        </sqlMapGenerator>
        <!-- Mapper 接口文件的位置 -->
        <javaClientGenerator targetPackage="com.cloud.dao.mapper"
                             targetProject="E:/local_project/idea/example/core/mybatis-example/src/main/java"
                             type="XMLMAPPER">
            <property name="enableSubPackages" value="false"/>
        </javaClientGenerator>
        <!-- 相关表的配置 -->
        <table tableName="t_sys_user" domainObjectName="SysUser"
               enableCountByExample="false" enableUpdateByExample="false"
               enableDeleteByExample="false" enableSelectByExample="false"
               selectByExampleQueryId="false"/>
    </context>
</generatorConfiguration>

运行生成的结果如下 

public interface SysUserMapper {
    /**
     * delete
     * @param id
     * @return int
     */
    int delete(String id);

    /**
     * insert
     * @param row
     * @return int
     */
    int insert(SysUser row);

    /**
     * update
     * @param row
     * @return int
     */
    int update(SysUser row);

    /**
     * selectOne
     * @param id
     * @return com.cloud.dao.po.SysUser
     */
    SysUser selectOne(String id);

    /**
     * selectList
     * @param param
     * @return java.util.List<com.cloud.dao.po.SysUser>
     */
    List<SysUser> selectList(SysUser param);
}

/**
 * 
 * @author cloud
 * @date 2022/03/11
 */
public class SysUser {
    /**
     * 主键
     */
    private String id;

    /**
     * 用户账号
     */
    private String username;

    /**
     * 用户密码
     */
    private String password;

    /**
     * 昵称
     */
    private String nickname;

    /**
     * 部门id
     */
    private Integer depId;

    /**
     * 岗位id
     */
    private String posId;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id == null ? null : id.trim();
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username == null ? null : username.trim();
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password == null ? null : password.trim();
    }

    public String getNickname() {
        return nickname;
    }

    public void setNickname(String nickname) {
        this.nickname = nickname == null ? null : nickname.trim();
    }

    public Integer getDepId() {
        return depId;
    }

    public void setDepId(Integer depId) {
        this.depId = depId;
    }

    public String getPosId() {
        return posId;
    }

    public void setPosId(String posId) {
        this.posId = posId == null ? null : posId.trim();
    }
}

最后

        没有下一篇了 

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值