首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

MyBatis Generator 進階實戰:代碼生成配置、分頁插件集成、批量插入優化與條件構建技巧

     編輯:Java 綜合教學

為什麼選擇 MyBatis Generator (MBG)?

手寫 Entity、Mapper 接口、XML 映射文件重複枯燥且易出錯。MBG 根據數據庫表結構自動生成標準化代碼,配合插件機制擴展分頁、批量操作、樂觀鎖等高級功能,讓開發聚焦業務邏輯。

生成代碼結構與目標包規劃

src/main/java
├── com.example.dao.entity      # 實體類 (User.java)
├── com.example.dao.mapper      # Mapper 接口 (UserMapper.java)
└── com.example.dao.mapper.xml  # XML 映射 (UserMapper.xml) - 建議單獨目錄或 resources/mapper

核心配置文件:generatorConfig.xml 詳細解析

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE generatorConfiguration PUBLIC "-//mybatis.org//DTD MyBatis Generator Configuration 1.0//EN" 
    "https://mybatis.org/dtd/mybatis-generator-config_1_0.dtd">
<generatorConfiguration>
    <!-- 數據庫驅動 -->
    <classPathEntry location="/path/to/mysql-connector-java-8.0.28.jar"/>

    <context id="MysqlContext" targetRuntime="MyBatis3" defaultModelType="conditional">
        <!-- 去除生成代碼中的註解 -->
        <commentGenerator>
            <property name="suppressAllComments" value="true"/>
            <property name="suppressDate" value="true"/>
        </commentGenerator>

        <!-- 數據庫連接 -->
        <jdbcConnection driverClass="com.mysql.cj.jdbc.Driver"
            connectionURL="jdbc:mysql://localhost:3306/mydb?useSSL=false&serverTimezone=UTC"
            userId="root" password="123456">
        </jdbcConnection>

        <!-- 類型處理器 (Java 8 時間類型) -->
        <typeHandler handler="org.apache.ibatis.type.LocalDateTimeTypeHandler"/>
        <typeHandler handler="org.apache.ibatis.type.LocalDateTypeHandler"/>

        <!-- 生成模型 -->
        <javaModelGenerator targetPackage="com.example.dao.entity" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
            <property name="trimStrings" value="true"/>
            <property name="immutable" value="false"/>
        </javaModelGenerator>

        <!-- 生成 XML -->
        <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">
            <property name="enableSubPackages" value="true"/>
        </sqlMapGenerator>

        <!-- 生成 Mapper 接口 -->
        <javaClientGenerator type="ANNOTATEDMAPPER" targetPackage="com.example.dao.mapper" targetProject="src/main/java">
            <property name="enableSubPackages" value="true"/>
        </javaClientGenerator>

        <!-- 核心:表配置與插件 -->
        <table tableName="user" domainObjectName="User">
            <!-- 主鍵策略 -->
            <generatedKey column="id" sqlStatement="JDBC" identity="true"/>
            <!-- 忽略列 -->
            <ignoreColumn columnName="create_time" delimitedColumnName="create_time"/>
        </table>

        <!-- 插件配置 (需引入插件 JAR) -->
        <plugin type="com.github.pagehelper.PageHelperPlugin">
            <property name="dialect" value="mysql"/>
        </plugin>
        <plugin type="tk.mybatis.mapper.generator.MapperPlugin">
            <property name="mapperInterface" value="tk.mybatis.mapper.common.Mapper"/>
        </plugin>
    </context>
</generatorConfiguration>

Maven 插件方式一鍵生成

<plugin>
    <groupId>org.mybatis.generator</groupId>
    <artifactId>mybatis-generator-maven-plugin</artifactId>
    <version>1.4.1</version>
    <configuration>
        <configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
        <verbose>true</verbose>
        <overwrite>true</overwrite>
    </configuration>
    <dependencies>
        <dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.28</version></dependency>
        <dependency><groupId>com.github.pagehelper</groupId><artifactId>pagehelper</artifactId><version>5.3.0</version></dependency>
        <dependency><groupId>tk.mybatis</groupId><artifactId>mapper</artifactId><version>4.2.2</version></dependency>
    </dependencies>
</plugin>

運行 mvn mybatis-generator:generate 即可生成/覆蓋代碼。

生成代碼核心用法示例

1. 基礎 CRUD (Mapper 接口已繼承 tk.mybatis.mapper.common.Mapper)

@Autowired private UserMapper userMapper;

// 插入 (返回自增 ID)
userMapper.insertSelective(user); // 僅非空字段
Long id = user.getId();

// 主鍵查詢
User u = userMapper.selectByPrimaryKey(id);

// 條件查詢 + 分頁 (PageHelper)
PageHelper.startPage(1, 10);
UserExample ex = new UserExample();
ex.createCriteria().andStatusEqualTo(1).andNameLike("%張%");
ex.setOrderByClause("create_time DESC");
List<User> list = userMapper.selectByExample(ex);
PageInfo<User> page = new PageInfo<>(list); // 含 total、pages、list

// 更新
user.setStatus(2);
userMapper.updateByPrimaryKeySelective(user);

// 刪除
userMapper.deleteByPrimaryKey(id);

2. 批量插入優化 (MySQL batch insert)

// Mapper 接口新增方法 (需手動添加或插件生成)
@Insert("<script> INSERT INTO user (name, email, status) VALUES <foreach collection='list' item='item' separator=','>(#{item.name}, #{item.email}, #{item.status})</foreach> </script>")
int batchInsert(@Param("list") List<User> list);

// Service 層調用
public void batchSaveUsers(List<User> users) {
    // 分批 500 條,避免 SQL 過長
    Lists.partition(users, 500).forEach(batch -> userMapper.batchInsert(batch));
}

3. 複雜條件構建:Example Criteria 進階用法

UserExample ex = new UserExample();
UserExample.Criteria c = ex.createCriteria();

// 基礎條件
c.andStatusEqualTo(1);

// OR 條件:使用 or() 創建新 Criteria
c.andNameLike("%張%");
UserExample.Criteria c2 = ex.or();
c2.andEmailLike("%@gmail.com");

// 等價 SQL: WHERE status=1 AND (name LIKE '%張%' OR email LIKE '%@gmail.com%')

// 原生 SQL 片段 (慎用)
c.addCriterion("id IN (SELECT user_id FROM user_role WHERE role_id = 1)");

// 子查詢構建器 (MBG 3.5+ 支持)
c.andIdIn(SelectBuilder.select("user_id").from("user_role").where("role_id = 1").build().toString());

4. 修改 ExampleGenerator 讓 Criteria 構造器公有 (解決動態構建限制)

MBG 默認生成 protected 構造器,導致無法外部 new Criteria。修改插件源碼或使用 MapperPlugin 重寫:

// 在 generatorConfig.xml 中配置
<plugin type="com.example.custom.PublicCriteriaPlugin"/>

// 插件核心代碼
public class PublicCriteriaPlugin extends PluginAdapter {
    @Override public boolean validate(List<String> warnings) { return true; }
    @Override public void initialized(IntrospectedTable table) {
        // 修改 Example 類中 Criteria 構造器為 public
        table.getRules().generatePrimaryKeyClass(); // 觸發生成
    }
    @Override public boolean modelExampleClassGenerated(TopLevelClass topLevelClass, IntrospectedTable table) {
        for (InnerClass innerClass : topLevelClass.getInnerClasses()) {
            if (innerClass.getType().getShortName().equals("Criteria")) {
                for (Method m : innerClass.getMethods()) {
                    if (m.isConstructor()) m.setVisibility(JavaVisibility.PUBLIC);
                }
            }
        }
        return true;
    }
}

分頁插件 PageHelper 集成與原理

// Spring Boot 配置
@Bean
public PageHelper pageHelper() {
    PageHelper helper = new PageHelper();
    Properties props = new Properties();
    props.setProperty("dialect", "mysql");
    props.setProperty("reasonable", "true"); // 頁碼超出範圍時查第一頁/最後一頁
    props.setProperty("supportMethodsArguments", "true");
    props.setProperty("params", "count=countSql");
    helper.setProperties(props);
    return helper;
}

原理:攔截 Executor.query,根據方言重寫 SQL 追加 LIMIT offset, pageSize,並自動執行 COUNT(*) 獲取總數。

最佳實踐總結

  1. 生成即用,勿手改生成代碼:自定義 SQL 放在 Mapper.xml 對應 <sql> 片段或擴展 Mapper 接口。
  2. Example 僅用於動態條件:固定查詢優先寫 XML,利用 MyBatis 動態 SQL 標籤 (<where>, <if>, <choose>)。
  3. 分頁參數校驗:PageHelper 依賴 ThreadLocal,確保在同一線程調用 startPage 與查詢方法。
  4. 批量操作分批提交:單次 500-1000 條,防止 SQL 超長或鎖表過久。
  5. 版本控制 generatorConfig.xml:團隊共享配置,新增表只需添加 <table> 節點重新生成。

總結

MyBatis Generator 配合 PageHelper、Mapper 通用接口、批量插件,構建了從表結構到業務代碼的自動化管道。掌握 generatorConfig.xml 核心配置、Example/Criteria 動態條件構建、分頁與批量優化技巧,可將 80% 的持久層代碼生成工作自動化,顯著提升交付效率。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved