java

关注公众号 jb51net

关闭
首页 > 软件编程 > java > MyBatis Generator 生成接口和XML映射文件

MyBatis Generator配置生成接口和XML映射文件的实现

作者:HaYiBoy

本文介绍了配置MBG以生成Mapper接口和XML映射文件,过合理使用MBG和自定义生成策略,可以有效解决生成的Example类可能带来的问题,使代码更加简洁和易于维护

在使用 MyBatis 进行项目开发时,MyBatis Generator(MBG)是一个非常实用的工具,它能够根据数据库表结构自动生成实体类、Mapper 接口以及 XML 映射文件,大大提高了开发效率。本文将详细介绍如何配置 MyBatis Generator 以生成接口和 XML 映射文件,并对不同的 targetRuntime 风格进行介绍和推荐。

一、环境准备

在开始之前,确保你的项目中已经添加了 MyBatis Generator 的相关依赖。如果你使用的是 Maven 项目,可以在 pom.xml 文件中添加如下依赖:

<dependencies>
    <!-- MyBatis -->
    <dependency>
        <groupId>org.mybatis.spring.boot</groupId>
        <artifactId>mybatis-spring-boot-starter</artifactId>
        <version>2.2.2</version>
    </dependency>
    <!-- MySQL -->
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-j</artifactId>
        <version>8.0.33</version>
    </dependency>
</dependencies>
<build>
    <plugins>
        <!-- MyBatis Generator 插件 -->
        <plugin>
            <groupId>org.mybatis.generator</groupId>
            <artifactId>mybatis-generator-maven-plugin</artifactId>
            <version>1.3.5</version>
            <configuration>
                <configurationFile>${basedir}/src/main/resources/generatorConfig.xml</configurationFile>
                <verbose>true</verbose>
                <overwrite>true</overwrite>
            </configuration>
            <dependencies>
                <dependency>
                    <groupId>mysql</groupId>
                    <artifactId>mysql-connector-j</artifactId>
                    <version>8.0.33</version>
                </dependency>
            </dependencies>
        </plugin>
    </plugins>
</build>

二、配置文件详解

在 src/main/resources 目录下创建 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>
    <!-- 配置上下文,id 唯一标识,targetRuntime 指定生成代码的方式,风格 MyBatis3DynamicSql,MyBatis3,MyBatis3Simple,MyBatis3Kotlin -->
    <context id="mysqlTables" targetRuntime="MyBatis3" defaultModelType="flat">
        <!-- 自动检查关键字,为关键字增加反引号,如:`type` -->
        <property name="autoDelimitKeywords" value="true"/>
        <property name="beginningDelimiter" value="`"/>
        <property name="endingDelimiter" value="`"/>
        <!-- 指定生成的 Java 文件编码 -->
        <property name="javaFileEncoding" value="UTF-8"/>
        <!-- 对生成的注释进行控制 -->
        <commentGenerator>
            <!-- 由于此插件生成的注释不太美观,这里设置不生成任何注释 -->
            <property name="suppressAllComments" value="true"/>
        </commentGenerator>
        <!-- 数据库链接 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
                        connectionURL="jdbc:mysql://127.0.0.1:3306/your_database"
                        userId="your_username"
                        password="your_password">
            <!-- 解决多个重名的表生成表结构不一致问题 -->
            <property name="nullCatalogMeansCurrent" value="true"/>
        </jdbcConnection>
        <!-- 不强制将所有的数值类型映射为 Java 的 BigDecimal 类型 -->
        <javaTypeResolver>
            <property name="forceBigDecimals" value="false"/>
        </javaTypeResolver>
        <!-- 配置生成实体类的位置和包名 -->
        <javaModelGenerator targetPackage="com.example.model" targetProject="src/main/java"/>
        <!-- 配置生成 XML 映射文件的位置和包名 -->
        <sqlMapGenerator targetPackage="com.example.mapper" targetProject="src/main/resources"/>
        <!-- 配置生成 Mapper 接口的位置和包名,type="XMLMAPPER" 表示生成 XML 映射文件 -->
        <javaClientGenerator type="XMLMAPPER" targetPackage="com.example.mapper" targetProject="src/main/java"/>
        <!-- 配置要生成代码的表,tableName 指定数据库中的表名,domainObjectName 指定生成的实体类名 -->
<!-- 要生成对应表配置,若想要生成全部表 使用 tableName="%" 即可 -->
        <!-- 订单详情表 -->
        <table tableName="order_detail" domainObjectName="OrderDetail"
               <!-- 不生成Example -->
               enableCountByExample="false"
               enableDeleteByExample="false"
               enableSelectByExample="false"
               enableUpdateByExample="false">
            <!-- 自增主键列 -->
            <generatedKey column="id" sqlStatement="MYSQL" identity="true"/>
            <!-- 根据实际需求添加其他列的映射配置 -->
        </table>

    </context>
</generatorConfiguration>

三、生成代码

在项目根目录下打开终端,运行以下命令生成代码:

mvn mybatis-generator:generate

或者点击 mybatis-generator 组件

运行命令后,MyBatis Generator 会根据 generatorConfig.xml 配置文件生成 Mapper 接口和对应的 XML 映射文件。

四、不同 targetRuntime 风格介绍和推荐

1. MyBatis3

2. MyBatis3Simple

3. MyBatis3DynamicSql

4. MyBatis3Kotlin

五、生成的 Example 类及解决办法

1. 生成的 Example 类

当使用 MyBatis3 风格时,MyBatis Generator 会生成 Example 类,这些类用于构建复杂的查询条件。例如,生成的 UserExample 类可能如下所示:

package com.example.model;

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

public class UserExample {
    protected String orderByClause;
    protected boolean distinct;
    protected List<Criteria> oredCriteria;

    public UserExample() {
        oredCriteria = new ArrayList<Criteria>();
    }

    public void setOrderByClause(String orderByClause) {
        this.orderByClause = orderByClause;
    }

    public String getOrderByClause() {
        return orderByClause;
    }

    public void setDistinct(boolean distinct) {
        this.distinct = distinct;
    }

    public boolean isDistinct() {
        return distinct;
    }

    public List<Criteria> getOredCriteria() {
        return oredCriteria;
    }

    public void or(Criteria criteria) {
        oredCriteria.add(criteria);
    }

    public Criteria or() {
        Criteria criteria = createCriteriaInternal();
        oredCriteria.add(criteria);
        return criteria;
    }

    public Criteria createCriteria() {
        Criteria criteria = createCriteriaInternal();
        if (oredCriteria.size() == 0) {
            oredCriteria.add(criteria);
        }
        return 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;
        }

        public List<Criterion> getAllCriteria() {
            return criteria;
        }

        public List<Criterion> getCriteria() {
            return criteria;
        }

        protected void addCriterion(String condition) {
            if (condition == null) {
                throw new RuntimeException("Value for condition cannot be null");
            }
            criteria.add(new Criterion(condition));
        }

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

        public Criteria andIdIsNull() {
            addCriterion("id is null");
            return (Criteria) this;
        }

        public Criteria andIdIsNotNull() {
            addCriterion("id is not null");
            return (Criteria) this;
        }

        public Criteria andIdEqualTo(Integer value) {
            addCriterion("id =", value, "id");
            return (Criteria) this;
        }

        // 其他条件方法...
    }

    public static class Criteria extends GeneratedCriteria {

        protected Criteria() {
            super();
        }
    }

    public static class Criterion {
        private String condition;
        private Object value;
        private Object secondValue;
        private boolean noValue;
        private boolean singleValue;
        private boolean betweenValue;
        private boolean listValue;
        private String typeHandler;

        public String getCondition() {
            return condition;
        }

        public Object getValue() {
            return value;
        }

        public Object getSecondValue() {
            return secondValue;
        }

        public boolean isNoValue() {
            return noValue;
        }

        public boolean isSingleValue() {
            return singleValue;
        }

        public boolean isBetweenValue() {
            return betweenValue;
        }

        public boolean isListValue() {
            return listValue;
        }

        public String getTypeHandler() {
            return typeHandler;
        }

        protected Criterion(String condition) {
            super();
            this.condition = condition;
            this.noValue = true;
        }

        protected Criterion(String condition, Object value, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.typeHandler = typeHandler;
            if (value instanceof List<?>) {
                this.listValue = true;
            } else {
                this.singleValue = true;
            }
        }

        protected Criterion(String condition, Object value) {
            this(condition, value, null);
        }

        protected Criterion(String condition, Object value, Object secondValue, String typeHandler) {
            super();
            this.condition = condition;
            this.value = value;
            this.secondValue = secondValue;
            this.typeHandler = typeHandler;
            this.betweenValue = true;
        }

        protected Criterion(String condition, Object value, Object secondValue) {
            this(condition, value, secondValue, null);
        }
    }
}

2. 问题及解决办法

问题 1:Example 类过于复杂,导致代码冗余

解决办法

问题 2:Example 类的使用导致代码可读性差

解决办法

List<User> users = userMapper.selectMany(SelectStatementProvider.builder()
    .select(UserDynamicSqlSupport.id, UserDynamicSqlSupport.name, UserDynamicSqlSupport.email)
    .from(UserDynamicSqlSupport.user)
    .where(UserDynamicSqlSupport.name, isEqualTo("张三"))
    .build());
public class UserQuery {
    private UserExample example;

    public UserQuery() {
        this.example = new UserExample();
    }

    public UserQuery idIsNull() {
        example.createCriteria().andIdIsNull();
        return this;
    }

    public UserQuery idIsNotNull() {
        example.createCriteria().andIdIsNotNull();
        return this;
    }

    public UserQuery idEqualTo(Integer id) {
        example.createCriteria().andIdEqualTo(id);
        return this;
    }

    // 其他条件方法...

    public UserExample build() {
        return example;
    }
}

// 使用封装的查询条件构建器
List<User> users = userMapper.selectByExample(new UserQuery().idEqualTo(1).build());

六、总结

通过以上步骤,我们成功配置了 MyBatis Generator 以生成接口和 XML 映射文件。在实际开发中,合理使用 MyBatis Generator 可以显著提高开发效率,减少手动编写重复代码的工作量。不同的 targetRuntime 风格各有优缺点,根据项目的具体需求选择合适的风格可以更好地满足开发需求。

生成的 Example 类虽然功能强大,但也可能导致代码冗余和可读性差。通过选择合适的风格或自定义生成策略,可以有效解决这些问题,使代码更加简洁和易于维护。

到此这篇关于MyBatis Generator配置生成接口和XML映射文件的实现的文章就介绍到这了,更多相关MyBatis Generator 生成接口和XML映射文件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

您可能感兴趣的文章:
阅读全文