手寫 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
<?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>
<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 即可生成/覆蓋代碼。
@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);
// 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));
}
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());
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;
}
}
// 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(*) 獲取總數。
Mapper.xml 對應 <sql> 片段或擴展 Mapper 接口。<where>, <if>, <choose>)。startPage 與查詢方法。<table> 節點重新生成。MyBatis Generator 配合 PageHelper、Mapper 通用接口、批量插件,構建了從表結構到業務代碼的自動化管道。掌握 generatorConfig.xml 核心配置、Example/Criteria 動態條件構建、分頁與批量優化技巧,可將 80% 的持久層代碼生成工作自動化,顯著提升交付效率。