SpringBoot使用MyBatis Generator生成動(dòng)態(tài)SQL的詳細(xì)步驟
概述
我們將在Spring Boot項(xiàng)目中集成MyBatis Generator,并配置其生成MyBatis Dynamic SQL風(fēng)格的代碼。 MyBatis Dynamic SQL是MyBatis 3的一個(gè)特性,它允許使用Java API構(gòu)建動(dòng)態(tài)SQL查詢,避免編寫XML或使用Example類。
MyBatis Dynamic SQL 核心優(yōu)勢(shì)
- 類型安全:所有列引用都是類型安全的
- 流暢的API:鏈?zhǔn)秸{(diào)用構(gòu)建查詢
- 動(dòng)態(tài)SQL:自然處理?xiàng)l件邏輯
- 無(wú)XML:避免XML配置的繁瑣
- IDE支持:自動(dòng)補(bǔ)全和類型檢查
步驟概述:
- 創(chuàng)建Spring Boot項(xiàng)目,添加必要的依賴(包括MyBatis Spring Boot Starter、數(shù)據(jù)庫(kù)驅(qū)動(dòng)、MyBatis Generator等)。
- 配置MyBatis Generator(通過(guò)Maven插件方式)。
- 編寫generatorConfig.xml配置文件,指定生成Dynamic SQL風(fēng)格的代碼。
- 運(yùn)行MyBatis Generator生成代碼。
- 在Spring Boot中配置MyBatis,使用生成的Mapper。
詳細(xì)步驟
一、創(chuàng)建Spring Boot項(xiàng)目并添加依賴
使用Spring Initializr創(chuàng)建一個(gè)新項(xiàng)目,選擇以下依賴:
- Spring Web (如果構(gòu)建Web應(yīng)用)
- MyBatis Framework
- MySQL Driver (以MySQL為例,或者根據(jù)你的數(shù)據(jù)庫(kù)選擇)

然后在pom.xml中添加MyBatis Generator Maven插件以及MyBatis Dynamic SQL依賴:
<dependencies>
<!-- Spring Boot Starter -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- MyBatis Spring Boot Starter -->
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>3.0.3</version>
</dependency>
<!-- MySQL 驅(qū)動(dòng) -->
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>
<!-- Lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<!-- MyBatis Dynamic SQL -->
<dependency>
<groupId>org.mybatis.dynamic-sql</groupId>
<artifactId>mybatis-dynamic-sql</artifactId>
<version>1.5.0</version>
</dependency>
</dependencies>
<build>
<plugins>
<!-- MyBatis Generator 插件 -->
<plugin>
<groupId>org.mybatis.generator</groupId>
<artifactId>mybatis-generator-maven-plugin</artifactId>
<version>1.4.2</version>
<dependencies>
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<version>8.0.33</version>
</dependency>
<!-- 支持生成 Dynamic SQL -->
<dependency>
<groupId>org.mybatis.dynamic-sql</groupId>
<artifactId>mybatis-dynamic-sql</artifactId>
<version>1.5.0</version>
</dependency>
</dependencies>
<configuration>
<configurationFile>src/main/resources/generatorConfig.xml</configurationFile>
<overwrite>true</overwrite>
<verbose>true</verbose>
</configuration>
</plugin>
</plugins>
</build>
二、編寫generatorConfig.xml配置文件
在src/main/resources目錄下創(chuàng)建generatorConfig.xml文件。我們需要配置生成Dynamic SQL風(fēng)格的代碼,這通過(guò)設(shè)置targetRuntime="MyBatis3DynamicSql"來(lái)實(shí)現(xiàn)。
示例配置:
<?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>
<!-- 引入 application.properties 中的配置(可選) -->
<properties resource="application.properties"/>
<!-- 數(shù)據(jù)庫(kù)驅(qū)動(dòng)路徑(如果未通過(guò)Maven依賴管理) -->
<!-- <classPathEntry location="/path/to/mysql-connector-java-8.0.33.jar"/> -->
<context id="mysql" targetRuntime="MyBatis3DynamicSql">
<!-- 生成的Java文件編碼 -->
<property name="javaFileEncoding" value="UTF-8"/>
<!-- 生成的Java文件的注釋 -->
<commentGenerator>
<!-- 注釋配置:不生成注釋 -->
<property name="suppressAllComments" value="true"/>
<!-- 生成注釋 -->
<!-- <property name="addRemarkComments" value="true"/>-->
</commentGenerator>
<!-- 數(shù)據(jù)庫(kù)連接信息 -->
<jdbcConnection driverClass="${spring.datasource.driver-class-name}"
connectionURL="${spring.datasource.url}"
userId="${spring.datasource.username}"
password="${spring.datasource.password}">
</jdbcConnection>
<!-- Java模型生成配置 -->
<javaModelGenerator targetPackage="com.example.demo.model.entity" targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
<property name="trimStrings" value="true"/>
</javaModelGenerator>
<!-- 注意:如果使用Dynamic SQL方式,不需要XML映射文件 -->
<!-- 生成 SQL Map XML 文件的配置 -->
<!-- <sqlMapGenerator targetPackage="mapper" targetProject="src/main/resources">-->
<!-- <property name="enableSubPackages" value="true" />-->
<!-- </sqlMapGenerator>-->
<!-- Mapper接口生成配置 -->
<javaClientGenerator type="ANNOTATEDMAPPER"
targetPackage="com.example.demo.repository.generated"
targetProject="src/main/java">
<property name="enableSubPackages" value="true"/>
</javaClientGenerator>
<!-- 指定要生成的表 -->
<table tableName="user" domainObjectName="User">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
<table tableName="rule" domainObjectName="RuleEntity" mapperName="RuleMapper">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
<table tableName="rule_version" domainObjectName="RuleVersionEntity" mapperName="RuleVersionMapper">
<generatedKey column="id" sqlStatement="MySql" identity="true"/>
</table>
<!-- 生成所有表 -->
<!-- <table tableName="%" />-->
</context>
</generatorConfiguration>
注意:
- 我們使用了
targetRuntime="MyBatis3DynamicSql",這會(huì)生成Dynamic SQL風(fēng)格的代碼。 - 不需要配置
sqlMapGenerator,因?yàn)镈ynamic SQL不生成XML映射文件。 javaClientGenerator的type設(shè)置為ANNOTATEDMAPPER,表示使用注解方式(實(shí)際上Dynamic SQL的Mapper接口是通過(guò)Java API構(gòu)建的,由Dynamic SQL的運(yùn)行時(shí)庫(kù)提供支持)。- 在
jdbcConnection中,我們使用了Spring Boot的application.properties中的數(shù)據(jù)庫(kù)配置(通過(guò)${}占位符引用)。需要在generatorConfig.xml文件中配置<properties resource="application.properties"/>,并且確保application.properties中有這些屬性。
三、配置application.properties
在src/main/resources/application.properties中配置數(shù)據(jù)源:
spring.application.name=demo server.port=8088 # 數(shù)據(jù)源配置 spring.datasource.url=jdbc:mysql://localhost:3306/mydatabase spring.datasource.username=root spring.datasource.password=mysecretpassword spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
四、運(yùn)行MyBatis Generator生成代碼
在項(xiàng)目根目錄下運(yùn)行命令:
mvn mybatis-generator:generate
或者在IDE中運(yùn)行Maven插件的mybatis-generator:generate目標(biāo)。

生成的文件將包括:
- 實(shí)體類(POJO):在
com.example.demo.model.entity包下。 - Mapper接口:在
com.example.demo.repository.generated包下。注意,生成的Mapper接口會(huì)繼承MyBatis Dynamic SQL提供的MyBatis3Mapper接口(比如CommonCountMapper, CommonDeleteMapper, CommonUpdateMapper),這些接口提供了一些基本的CRUD方法。
五、在Spring Boot中使用生成的Mapper
- 在目錄
com.example.demo.config創(chuàng)建MyBatisConfig.java配置類:
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import javax.sql.DataSource;
@Configuration
@MapperScan("com.example.demo.repository")
public class MyBatisConfig {
@Bean
public SqlSessionFactory sqlSessionFactory(DataSource dataSource) throws Exception {
SqlSessionFactoryBean sessionFactory = new SqlSessionFactoryBean();
sessionFactory.setDataSource(dataSource);
sessionFactory.setTypeAliasesPackage("com.example.demo.model.entity");
return sessionFactory.getObject();
}
}
在Spring Boot項(xiàng)目中,使用@MapperScan注解可以方便地掃描并注冊(cè)MyBatis的Mapper接口。這樣,我們就不需要在每個(gè)Mapper接口上都添加@Mapper注解。
注意事項(xiàng):
@MapperScan與@Mapper:如果使用了@MapperScan,則不需要在每個(gè)Mapper接口上再寫@Mapper。但是,如果有些Mapper接口不在掃描路徑下,那么仍然需要在該接口上使用@Mapper。- 包路徑:確保
@MapperScan指定的包路徑正確,否則Spring容器無(wú)法創(chuàng)建Mapper的Bean,導(dǎo)致注入失敗。 - 多模塊項(xiàng)目:如果項(xiàng)目有多個(gè)模塊,并且Mapper接口分布在不同的模塊中,確保這些模塊的包路徑都被掃描到。
在Service中注入Mapper并使用:
@Service
@RequiredArgsConstructor
public class UserService {
private final UserMapper userMapper;
// 創(chuàng)建用戶
public int createUser(User user) {
return userMapper.insert(user);
}
// 根據(jù)ID獲取用戶
public Optional<User> getUserById(Long id) {
return userMapper.selectByPrimaryKey(id);
}
// 更新用戶
public int updateUser(User user) {
return userMapper.updateByPrimaryKeySelective(user);
}
// 刪除用戶
public int deleteUser(Long id) {
return userMapper.deleteByPrimaryKey(id);
}
// 動(dòng)態(tài)查詢用戶
public List<User> findUsers(String username, Integer minAge, Integer maxAge) {
return userMapper.select(c -> c
.where(UserDynamicSqlSupport.username, isLikeIfPresent(username).map(s -> s + "%")
.and(UserDynamicSqlSupport.age, isBetweenWhenPresent(minAge, maxAge))
.orderBy(UserDynamicSqlSupport.createTime.descending())
.build()
.execute());
}
// 輔助方法:條件存在時(shí)使用 LIKE
private Optional<Condition> isLikeIfPresent(String value) {
return Optional.ofNullable(value)
.filter(v -> !v.isEmpty())
.map(v -> UserDynamicSqlSupport.username.like(v));
}
// 輔助方法:條件存在時(shí)使用 BETWEEN
private Optional<BetweenCondition> isBetweenWhenPresent(Integer min, Integer max) {
if (min != null && max != null) {
return Optional.of(UserDynamicSqlSupport.age.between(min, max));
}
return Optional.empty();
}
}
注意:上面的user是一個(gè)自動(dòng)生成的表對(duì)應(yīng)的對(duì)象(在UserMapper中有一個(gè)靜態(tài)字段user,用于構(gòu)建查詢)。實(shí)際使用時(shí),需要導(dǎo)入生成的Mapper和表對(duì)象。
例如,在UserService中導(dǎo)入:
import static com.example.demo.mapper.UserDynamicSqlSupport.*; import static org.mybatis.dynamic.sql.SqlBuilder.*;
- 在controller中注入service并使用
@RestController
@RequestMapping("/api/users")
@RequiredArgsConstructor
public class UserController {
private final UserService userService;
@PostMapping
public ResponseEntity<?> createUser(@RequestBody User user) {
int result = userService.createUser(user);
return result > 0
? ResponseEntity.ok("User created")
: ResponseEntity.badRequest().body("Create failed");
}
@GetMapping("/{id}")
public ResponseEntity<User> getUser(@PathVariable Long id) {
return userService.getUserById(id)
.map(ResponseEntity::ok)
.orElse(ResponseEntity.notFound().build());
}
@PutMapping("/{id}")
public ResponseEntity<?> updateUser(@PathVariable Long id, @RequestBody User user) {
user.setId(id);
int result = userService.updateUser(user);
return result > 0
? ResponseEntity.ok("User updated")
: ResponseEntity.badRequest().body("Update failed");
}
@DeleteMapping("/{id}")
public ResponseEntity<?> deleteUser(@PathVariable Long id) {
int result = userService.deleteUser(id);
return result > 0
? ResponseEntity.ok("User deleted")
: ResponseEntity.badRequest().body("Delete failed");
}
@GetMapping("/search")
public List<User> searchUsers(
@RequestParam(required = false) String username,
@RequestParam(required = false) Integer minAge,
@RequestParam(required = false) Integer maxAge) {
return userService.findUsers(username, minAge, maxAge);
}
}
六、MyBatis Dynamic SQL 生成代碼的特點(diǎn)
生成的Mapper接口包含的方法:
insert:插入記錄insertMultiple:批量插入insertSelective:選擇性插入(忽略null)selectByPrimaryKey:根據(jù)主鍵查詢select:根據(jù)條件查詢(可返回多條)selectOne:根據(jù)條件查詢一條update:更新delete:刪除
同時(shí)會(huì)生成一個(gè)與表同名的輔助類(如UserDynamicSqlSupport),其中包含表的列定義,用于構(gòu)建動(dòng)態(tài)SQL。
不需要XML映射文件,所有SQL通過(guò)Java API動(dòng)態(tài)構(gòu)建。
七、注意事項(xiàng)
- 確保數(shù)據(jù)庫(kù)表有主鍵,否則生成代碼時(shí)可能會(huì)出現(xiàn)問(wèn)題。
- 如果表名或列名是SQL關(guān)鍵字,需要在配置中使用
<columnOverride>或<table>的delimitIdentifiers屬性處理。 - 生成的代碼可能會(huì)覆蓋已有的文件,注意備份自定義代碼(通常不要修改生成的代碼,而是通過(guò)擴(kuò)展方式)。
八、總結(jié)
本方案在 Spring Boot 中集成了 MyBatis Generator,并配置生成 MyBatis Dynamic SQL 風(fēng)格的代碼,具有以下特點(diǎn):
- 代碼簡(jiǎn)潔:使用 Lombok 減少樣板代碼
- 類型安全:Dynamic SQL 提供編譯時(shí)檢查
- 易于維護(hù):無(wú)需 XML 配置
- 動(dòng)態(tài)查詢:靈活構(gòu)建復(fù)雜查詢
- 高效開(kāi)發(fā):自動(dòng)生成基礎(chǔ) CRUD 代碼
通過(guò)這種方式,你可以專注于業(yè)務(wù)邏輯開(kāi)發(fā),而無(wú)需手動(dòng)編寫重復(fù)的數(shù)據(jù)訪問(wèn)層代碼。
以上就是SpringBoot使用MyBatis Generator生成動(dòng)態(tài)SQL的詳細(xì)步驟的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot生成動(dòng)態(tài)SQL的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
- SpringBoot使用Mybatis注解實(shí)現(xiàn)分頁(yè)動(dòng)態(tài)sql開(kāi)發(fā)教程
- IDEA下創(chuàng)建SpringBoot+MyBatis+MySql項(xiàng)目實(shí)現(xiàn)動(dòng)態(tài)登錄與注冊(cè)功能
- SpringBoot整合SQLite詳細(xì)過(guò)程
- SpringBoot連接Microsoft SQL Server實(shí)現(xiàn)登錄驗(yàn)證
- IDEA中為SpringBoot項(xiàng)目接入MySQL數(shù)據(jù)庫(kù)的詳細(xì)指南
- SpringBoot使用索引來(lái)優(yōu)化SQL查詢的詳細(xì)步驟
相關(guān)文章
springboot整合ehcache和redis實(shí)現(xiàn)多級(jí)緩存實(shí)戰(zhàn)案例
這篇文章主要介紹了springboot整合ehcache和redis實(shí)現(xiàn)多級(jí)緩存實(shí)戰(zhàn)案例,從源碼角度分析下多級(jí)緩存實(shí)現(xiàn)原理,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2023-08-08
利用spring的攔截器自定義緩存的實(shí)現(xiàn)實(shí)例代碼
這篇文章主要介紹了利用spring的攔截器自定義緩存的實(shí)現(xiàn)實(shí)例代碼,分享了相關(guān)代碼示例,小編覺(jué)得還是挺不錯(cuò)的,具有一定借鑒價(jià)值,需要的朋友可以參考下2018-02-02
Java將文件內(nèi)容讀取為字符串的實(shí)現(xiàn)步驟
在Java編程中,經(jīng)常需要將文件內(nèi)容讀取為字符串進(jìn)行處理,比如配置文件讀取、文本數(shù)據(jù)解析等場(chǎng)景,不同版本的Java提供了多種實(shí)現(xiàn)方式,同時(shí)也有一些外部庫(kù)可以簡(jiǎn)化操作,本文給大家介紹了Java將文件內(nèi)容讀取為字符串的實(shí)現(xiàn)步驟,需要的朋友可以參考下2025-06-06
SpringBoot中?Jackson?日期的時(shí)區(qū)和日期格式問(wèn)題解決
因?yàn)樽罱?xiàng)目需要國(guó)際化,需要能夠支持多種國(guó)際化語(yǔ)言,目前需要支持三種(法語(yǔ)、英語(yǔ)、簡(jiǎn)體中文),這篇文章主要介紹了SpringBoot中?Jackson?日期的時(shí)區(qū)和日期格式問(wèn)題,需要的朋友可以參考下2022-12-12
Java map.getOrDefault()方法的用法詳解
這篇文章主要介紹了Java map.getOrDefault()方法的用法詳解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2020-12-12
Spring Boot Dubbo 構(gòu)建分布式服務(wù)的方法
這篇文章主要介紹了Spring Boot Dubbo 構(gòu)建分布式服務(wù)的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2019-05-05
Mybatis?連接mysql數(shù)據(jù)庫(kù)底層運(yùn)行的原理分析
這篇文章主要介紹了Mybatis?連接mysql數(shù)據(jù)庫(kù)底層運(yùn)行的原理分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-03-03

