mybatis generator逆向工程生成工具代码以及xxxExample参数详情讲解和使用

8 篇文章 0 订阅
4 篇文章 0 订阅

generator逆向工程生成代码

首先引入jar包,数据库用mysql为例

<dependency>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-core</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>

配置文件

generator.properties, 都是一些数据库基本的连接配置,没什么可说的,一看就懂

jdbc.driverClass=com.mysql.cj.jdbc.Driver
jdbc.connectionURL=jdbc:mysql://192.168.250.193:3306/micromall?serverTimezone=UTC&useSSL=false&useUnicode=true&characterEncoding=UTF-8
jdbc.userId=root
jdbc.password=root

generatorConfig.xml,生成代码时的相关配置,如数据库连接配置、生成到哪个模块或package里面,以及需要执行哪些表,表的主键等信息说明

<?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>
    <properties resource="generator.properties"/>
    <context id="MySqlContext" targetRuntime="MyBatis3" defaultModelType="flat">
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 为模型生成序列化方法-->
        <plugin type="org.mybatis.generator.plugins.SerializablePlugin"/>
        <!-- 为生成的Java模型创建一个toString方法 -->
        <plugin type="org.mybatis.generator.plugins.ToStringPlugin"/>
        <!--生成mapper.xml时覆盖原文件-->
        <plugin type="org.mybatis.generator.plugins.UnmergeableXmlMappersPlugin" />
        <commentGenerator type="com.macro.mall.CommentGenerator">
            <!-- 是否去除自动生成的注释 true:是 : false:-->
            <property name="suppressAllComments" value="true"/>
            <property name="suppressDate" value="true"/>
            <property name="addRemarkComments" value="true"/>
        </commentGenerator>

        <jdbcConnection driverClass="${jdbc.driverClass}"
                        connectionURL="${jdbc.connectionURL}"
                        userId="${jdbc.userId}"
                        password="${jdbc.password}">
            <!--解决mysql驱动升级到8.0后不生成指定数据库代码的问题-->
            <property name="nullCatalogMeansCurrent" value="true" />
        </jdbcConnection>

        <javaModelGenerator targetPackage="com.macro.mall.model" targetProject="mall-mgb\src\main\java"/>

        <sqlMapGenerator targetPackage="com.macro.mall.mapper" targetProject="mall-mgb\src\main\resources"/>

        <javaClientGenerator type="XMLMAPPER" targetPackage="com.macro.mall.mapper"
                             targetProject="mall-mgb\src\main\java"/>
        <!--生成全部表tableName设为%,指定前缀ums_%-->
        <table tableName="wang_test" enableCountByExample="true" enableUpdateByExample="true"
               enableDeleteByExample="true" enableSelectByExample="true"
               selectByExampleQueryId="true">
            <!-- generatedKey用于生成生成主键的方法,
            如果设置了该元素,MBG会在生成的<insert>元素中生成一条正确的<selectKey>元素,该元素可选
            column:主键的列名;
            sqlStatement:要生成的selectKey语句,有以下可选项:
                Cloudscape:相当于selectKey的SQL为: VALUES IDENTITY_VAL_LOCAL()
                DB2       :相当于selectKey的SQL为: VALUES IDENTITY_VAL_LOCAL()
                DB2_MF    :相当于selectKey的SQL为:SELECT IDENTITY_VAL_LOCAL() FROM SYSIBM.SYSDUMMY1
                Derby     :相当于selectKey的SQL为:VALUES IDENTITY_VAL_LOCAL()
                HSQLDB    :相当于selectKey的SQL为:CALL IDENTITY()
                Informix  :相当于selectKey的SQL为:select dbinfo('sqlca.sqlerrd1') from systables where tabid=1
                MySql     :相当于selectKey的SQL为:SELECT LAST_INSERT_ID()
                SqlServer :相当于selectKey的SQL为:SELECT SCOPE_IDENTITY()
                SYBASE    :相当于selectKey的SQL为:SELECT @@IDENTITY
                JDBC      :相当于在生成的insert元素上添加useGeneratedKeys="true"和keyProperty属性
            -->
            <generatedKey column="id" sqlStatement="MySql" identity="true"/>
        </table>
    </context>
</generatorConfiguration>

自定义注释生成器

package com.macro.mall;

import org.mybatis.generator.api.IntrospectedColumn;
import org.mybatis.generator.api.IntrospectedTable;
import org.mybatis.generator.api.dom.java.CompilationUnit;
import org.mybatis.generator.api.dom.java.Field;
import org.mybatis.generator.api.dom.java.FullyQualifiedJavaType;
import org.mybatis.generator.internal.DefaultCommentGenerator;
import org.mybatis.generator.internal.util.StringUtility;

import java.util.Properties;

/**
 * 自定义注释生成器
 */
public class CommentGenerator extends DefaultCommentGenerator {
    private boolean addRemarkComments = false;
    private static final String EXAMPLE_SUFFIX="Example";
    private static final String API_MODEL_PROPERTY_FULL_CLASS_NAME="io.swagger.annotations.ApiModelProperty";

    /**
     * 设置用户配置的参数
     */
    @Override
    public void addConfigurationProperties(Properties properties) {
        super.addConfigurationProperties(properties);
        this.addRemarkComments = StringUtility.isTrue(properties.getProperty("addRemarkComments"));
    }

    /**
     * 给字段添加注释
     */
    @Override
    public void addFieldComment(Field field, IntrospectedTable introspectedTable,
                                IntrospectedColumn introspectedColumn) {
        String remarks = introspectedColumn.getRemarks();
        //根据参数和备注信息判断是否添加备注信息
        if(addRemarkComments&&StringUtility.stringHasValue(remarks)){
//            addFieldJavaDoc(field, remarks);
            //数据库中特殊字符需要转义
            if(remarks.contains("\"")){
                remarks = remarks.replace("\"","'");
            }
            //给model的字段添加swagger注解
            field.addJavaDocLine("@ApiModelProperty(value = \""+remarks+"\")");
        }
    }

    /**
     * 给model的字段添加注释
     */
    private void addFieldJavaDoc(Field field, String remarks) {
        //文档注释开始
        field.addJavaDocLine("/**");
        //获取数据库字段的备注信息
        String[] remarkLines = remarks.split(System.getProperty("line.separator"));
        for(String remarkLine:remarkLines){
            field.addJavaDocLine(" * "+remarkLine);
        }
        addJavadocTag(field, false);
        field.addJavaDocLine(" */");
    }

    @Override
    public void addJavaFileComment(CompilationUnit compilationUnit) {
        super.addJavaFileComment(compilationUnit);
        //只在model中添加swagger注解类的导入
        if(!compilationUnit.isJavaInterface()&&!compilationUnit.getType().getFullyQualifiedName().contains(EXAMPLE_SUFFIX)){
            compilationUnit.addImportedType(new FullyQualifiedJavaType(API_MODEL_PROPERTY_FULL_CLASS_NAME));
        }
    }
}

执行生成代码的主类

package com.macro.mall;

import org.mybatis.generator.api.MyBatisGenerator;
import org.mybatis.generator.config.Configuration;
import org.mybatis.generator.config.xml.ConfigurationParser;
import org.mybatis.generator.internal.DefaultShellCallback;

import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;

/**
 * 用于生产MBG的代码
 */
public class Generator {
    public static void main(String[] args) throws Exception {
        //MBG 执行过程中的警告信息
        List<String> warnings = new ArrayList<String>();
        //当生成的代码重复时,覆盖原代码
        boolean overwrite = true;
        //读取我们的 MBG 配置文件
        InputStream is = Generator.class.getResourceAsStream("/generatorConfig.xml");
        ConfigurationParser cp = new ConfigurationParser(warnings);
        Configuration config = cp.parseConfiguration(is);
        is.close();

        DefaultShellCallback callback = new DefaultShellCallback(overwrite);
        //创建 MBG
        MyBatisGenerator myBatisGenerator = new MyBatisGenerator(config, callback, warnings);
        //执行生成代码
        myBatisGenerator.generate(null);
        //输出警告信息
        for (String warning : warnings) {
            System.out.println(warning);
        }
    }
}

xxxEXample参数说明

参数的整体结构如下:
在这里插入图片描述

说明:

1、WangTestExample就是WangTest的参数类(WangTest是表wang_test的java实体类)。
该参数类中包含三个属性,一个是list集合,一个是排序字符串,一个是是否去重
List oredCriteria:这个里面在进行sql查询时使用的是OR 即 id = 1 or name = ‘jin’

2、Criteria:有两个属性,一个是所有的字段集合,一个是该批参数是否有效
下面用代码来说明图中表示的意思的具体实现:
注:因为这个参数类代码太多,只拿一个字段进行详细说明

package com.macro.mall.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class WangTestExample {
    protected String orderByClause; // 排序字段 如  name asc

    protected boolean distinct;// 是否去重

    protected List<Criteria> oredCriteria;// 参数集合 该集合循环时用 or 表示并联查询

    public WangTestExample() {
        oredCriteria = new ArrayList<Criteria>();
    }
	//往 oredCriteria集合里面放入的Criteria 都是属于or查询,这种方法是先创建一个串联查询    criteria,然后再添加到集合中。即先创建赋值,再添加到集合中
    public void or(Criteria criteria) {
        oredCriteria.add(criteria);
    }
	// 先创建Criteria 添加到集合中,然后在进行参数赋值设置
    public Criteria or() {
        Criteria criteria = createCriteriaInternal();
        oredCriteria.add(criteria);
        return criteria;
    }
	//创建Criteria 
    public Criteria createCriteria() {
        Criteria criteria = createCriteriaInternal();
        if (oredCriteria.size() == 0) {
            oredCriteria.add(criteria);
        }
        return criteria;
    }
//创建Criteria 
    protected Criteria createCriteriaInternal() {
        Criteria criteria = new Criteria();
        return criteria;
    }
	//清除所有的参数
    public void clear() {
        oredCriteria.clear();
        orderByClause = null;
        distinct = false;
    }

    protected abstract static class GeneratedCriteria {
        protected List<Criterion> criteria;//所有字段属性设置类集合

        protected GeneratedCriteria() {
            super();
            criteria = new ArrayList<Criterion>();
        }
		//是否有效,表示该参数类是否生效
        public boolean isValid() {
            return criteria.size() > 0;
        }
        //设置条件的方法 condition 的值 如 name = 或 name is null
        protected void addCriterion(String condition) {
            if (condition == null) {
                throw new RuntimeException("Value for condition cannot be null");
            }
            criteria.add(new Criterion(condition));
        }
		//设置条件和值的方法 
		//condition 同上 
		// value 值 如 jin 
		//property 属性名,如 name
        protected void addCriterion(String condition, Object value, String property) {
            if (value == null) {
                throw new RuntimeException("Value for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value));
        }
		//设置两个值的方法
        protected void addCriterion(String condition, Object value1, Object value2, String property) {
            if (value1 == null || value2 == null) {
                throw new RuntimeException("Between values for " + property + " cannot be null");
            }
            criteria.add(new Criterion(condition, value1, value2));
        }
		//添加参数 id 为null 的方法
        public Criteria andIdIsNull() {
            addCriterion("id is null");
            return (Criteria) this;
        }
		// id 不为 null 的方法
        public Criteria andIdIsNotNull() {
            addCriterion("id is not null");
            return (Criteria) this;
        }
		//id等于某个值的方法
        public Criteria andIdEqualTo(Long value) {
            addCriterion("id =", value, "id");
            return (Criteria) this;
        }
		// 不等于
        public Criteria andIdNotEqualTo(Long value) {
            addCriterion("id <>", value, "id");
            return (Criteria) this;
        }
		// id 大于 某个值
        public Criteria andIdGreaterThan(Long value) {
            addCriterion("id >", value, "id");
            return (Criteria) this;
        }
		// id 大于等于 某个值
        public Criteria andIdGreaterThanOrEqualTo(Long value) {
            addCriterion("id >=", value, "id");
            return (Criteria) this;
        }
		//id 小于 某个值
        public Criteria andIdLessThan(Long value) {
            addCriterion("id <", value, "id");
            return (Criteria) this;
        }
		//id 小于等于 某个值
        public Criteria andIdLessThanOrEqualTo(Long value) {
            addCriterion("id <=", value, "id");
            return (Criteria) this;
        }
		//id 在 某些值中
        public Criteria andIdIn(List<Long> values) {
            addCriterion("id in", values, "id");
            return (Criteria) this;
        }
		//id 不在 某些值中
        public Criteria andIdNotIn(List<Long> values) {
            addCriterion("id not in", values, "id");
            return (Criteria) this;
        }
		//id 在 某些值之间
        public Criteria andIdBetween(Long value1, Long value2) {
            addCriterion("id between", value1, value2, "id");
            return (Criteria) this;
        }
		//id 不在 某些值中
        public Criteria andIdNotBetween(Long value1, Long value2) {
            addCriterion("id not between", value1, value2, "id");
            return (Criteria) this;
        }
		//下面还有字段说明和id都是一样的用法,就不再一一累述,敲的累
        //字符串有like ,模糊匹配 value值 为 %xxx%
        public Criteria andNameLike(String value) {
            addCriterion("name like", value, "name");
            return (Criteria) this;
        }

        public Criteria andNameNotLike(String value) {
            addCriterion("name not like", value, "name");
            return (Criteria) this;
        }
    }

    public static class Criteria extends GeneratedCriteria {

        protected Criteria() {
            super();
        }
    }
	//此类是某个字段的 属性说明
    public static class Criterion {
        private String condition;// 某字段的条件 如 name = 

        private Object value;//某字段的值 ,如果listValue为true则表示是个集合值

        private Object secondValue;//某字段的第二个值 一般用于between

        private boolean noValue;//是否无值

        private boolean singleValue;// 是否一个值

        private boolean betweenValue;//是否 between查询,用于二个值

        private boolean listValue;//是否是list 值

        private String typeHandler;//类型处理,暂时还未发现其用在何处
    }
}

example的使用

都是自动生成的代码,下面只是简单的说明一下

int updateByExampleSelective(@Param("record") WangTest record, @Param("example") WangTestExample example);

List<WangTest> selectByExample(WangTestExample example);

为什么拿出来两个进行说明呢,主要是参数不一样,
@Param(“example”) WangTestExample example) 这种写法在,xml的sql中 与
List selectByExample(WangTestExample example);的用法有点小区别。下面看代码

<!--List<WangTest> selectByExample(WangTestExample example); 当一个参数的时候,默认是
_parameter ,所以在collection="oredCriteria" 时候省略了-->
<sql id="Example_Where_Clause">
	首先先来个where
    <where>   
    	循环所有的参数集合,表示是并联查询,所以用or。criteria这里面表示的是一组串联参数集合
      <foreach collection="oredCriteria" item="criteria" separator="or">
      	表示一组参数是否有效
        <if test="criteria.valid">
        	如果参数有效,则进行串联查询 用and 连接
          <trim prefix="(" prefixOverrides="and" suffix=")">
          	循环每个参数
            <foreach collection="criteria.criteria" item="criterion">
              <choose>
              	//如果该参数无值,则进行该步操作
                <when test="criterion.noValue">
                  and ${criterion.condition}
                </when>
                //如果该参数有一个值,则进行该步操作
                <when test="criterion.singleValue">
                  and ${criterion.condition} #{criterion.value}
                </when>
                //如果between为true,则进行该步操作
                <when test="criterion.betweenValue">
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                //如果listValue为true,则进行该步操作
                <when test="criterion.listValue">
                  and ${criterion.condition}
                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  <!-- int updateByExampleSelective(@Param("record") WangTest record, @Param("example") WangTestExample example);
  下面这个查询条件的where与上面的一样,就example.oredCriteria不一样,主要是接口中有声明
  @Param("example")
-->
  <sql id="Update_By_Example_Where_Clause">
    <where>
      <foreach collection="example.oredCriteria" item="criteria" separator="or">
        <if test="criteria.valid">
          <trim prefix="(" prefixOverrides="and" suffix=")">
            <foreach collection="criteria.criteria" item="criterion">
              <choose>
                <when test="criterion.noValue">
                  and ${criterion.condition}
                </when>
                <when test="criterion.singleValue">
                  and ${criterion.condition} #{criterion.value}
                </when>
                <when test="criterion.betweenValue">
                  and ${criterion.condition} #{criterion.value} and #{criterion.secondValue}
                </when>
                <when test="criterion.listValue">
                  and ${criterion.condition}
                  <foreach close=")" collection="criterion.value" item="listItem" open="(" separator=",">
                    #{listItem}
                  </foreach>
                </when>
              </choose>
            </foreach>
          </trim>
        </if>
      </foreach>
    </where>
  </sql>
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值