MyBatis-Plus注解配置、條件構(gòu)造器與自定義SQL的復(fù)雜操作實例詳解
一、MyBatis-Plus介紹
MyBatis-Plus(簡稱 MP) 是一個 MyBatis 的增強工具, 在 MyBatis 的基礎(chǔ)上只做增強不做改變, 為簡化開發(fā)、提高效率而生。
特性
- 潤物無聲: 只做增強不做改變,引入它不會對現(xiàn)有工程產(chǎn)生影響,如絲般順滑。
- 效率至上: 只需簡單配置,即可快速進行單表 CRUD 操作,從而節(jié)省大量時間。
- 豐富功能: 代碼生成、自動分頁、邏輯刪除、自動填充、攔截器等功能一應(yīng)俱全。
- 廣泛認可: 連續(xù) 5 年獲得開源中國年度最佳開源項目殊榮,Github 累計 16K Star。
支持數(shù)據(jù)庫
PostgreSQL, MySQL, MariaDB, Oracle, SQL Server, OceanBase, H2, DB2…
(任何能使用 MyBatis 進行增刪改查,并且支持標準 SQL 的數(shù)據(jù)庫應(yīng)該都在 MyBatis-Plus 的支持范圍內(nèi))
官網(wǎng)地址:Mybatis-Plus 簡化開發(fā)
二、MyBatis-Plus 入門使用
Mybatis-Plus操作數(shù)據(jù)庫的步驟:
2.1 依賴引入與配置
- 創(chuàng)建springboot工程
- 添加MyBatis-Plus和MySQL依賴, 配置數(shù)據(jù)庫連接信息
Spring Boot2依賴:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.7</version>
</dependency>Spring Boot3依賴:
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-spring-boot3-starter</artifactId>
<version>3.5.5</version>
</dependency>MySQL依賴:
<dependency>
<groupId>com.mysql</groupId>
<artifactId>mysql-connector-j</artifactId>
<scope>runtime</scope>
</dependency>配置數(shù)據(jù)庫(application.yml文件):
# 數(shù)據(jù)庫連接配置
spring:
datasource:
url: jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false
username: root
password: root
driver-class-name: com.mysql.cj.jdbc.Driver配置數(shù)據(jù)庫(application.properties文件):
#驅(qū)動類名稱 spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver #數(shù)據(jù)庫連接的url spring.datasource.url=jdbc:mysql://127.0.0.1:3306/mybatis_test?characterEncoding=utf8&useSSL=false #連接數(shù)據(jù)庫的用戶名 spring.datasource.username=root #連接數(shù)據(jù)庫的密碼 spring.datasource.password=root
2.2 入門使用
- 創(chuàng)建實體類,實體類的屬性名與表中的字段名一一對應(yīng):
- 編寫Mapper接口類
MybatisPlus提供了一個基礎(chǔ)的BaseMapper 接口,已經(jīng)實現(xiàn)了單表的CRUD,自定義的 Mapper只需要繼承這個BaseMapper,就無需自己實現(xiàn)單表CRUD了。
BaseMapper包含了很多方法,示例:

Mapper接口代碼:
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}
也可以在啟動類上添加 @MapperScan ,掃描Mapper文件夾,如下:(二選一即可)

- CRUD單元測試
在創(chuàng)建出來的SpringBoot工程中,在src下的test目錄下,創(chuàng)建測試類,可以直接使用這個測試類來進行測試。
編寫單元測試,測試基本的CRUD功能:
@SpringBootTest
class MybatisPlusDemoApplicationTests {
@Autowired
private UserInfoMapper userInfoMapper;
@Test
public void testSelect() {
System.out.println(("----- selectAll method test ------"));
List<UserInfo> userList = userInfoMapper.selectList(null);
userList.forEach(System.out::println);
}
}運行結(jié)果如下:

三、MyBatis-Plus復(fù)雜操作
3.1 注解配置
MyBatis是如何知道,我們要操作的是哪張表,表里有哪些字段呢?
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}
UserInfoMapper 在繼承BaseMapper 時, 指定了一個泛型, 這個UserInfo就是與數(shù)據(jù)庫表相對應(yīng)的實體類。MyBatis-Plus會根據(jù)這個實體類來推斷表的信息。
默認情況下:
- 表名: 實體類的駝峰表示法轉(zhuǎn)換成蛇形表示法(下劃線分割), 作為表名。比如UserInfo -> user_info
- 字段: 根據(jù)實體類的屬性名轉(zhuǎn)換為蛇形表示法作為字段名。比如deleteFlag -> delete_flag
- 主鍵: 默認為id
如果實體類和數(shù)據(jù)庫不是按照上述規(guī)則定義。MyBatis-Plus也給我們提供了一些注解,用來標識表的信息。
3.1.1 @TableName
該注解用于指定實體類對應(yīng)的數(shù)據(jù)庫表名。當實體類名與數(shù)據(jù)庫表名不一致,或者實體類名不是數(shù)據(jù)庫表名的駝峰寫法時,可以使用這個注解來明確指定表名。
示例:
@Data
@TableName("user_info")
public class Userinfo {
private Integer id;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
private Integer deleteFlag;
private Date createTime;
private Date updateTime;
}
3.1.2 @TableField
該注解用于標記實體類中的非主鍵字段,它告訴 MyBatis-Plus 如何映射實體類字段到數(shù)據(jù)庫表字段。如果實體類字段名遵循駝峰命名規(guī)則,并且與數(shù)據(jù)庫表字段名一致,可以省略這個注解。
示例:
@Data
@TableName("user_info")
public class Userinfo {
private Integer id;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
@TableField("delete_flag")
private Integer deleteflag;
private Date createTime;
private Date updateTime;
}
3.1.3 @TableId
該注解用于標記實體類中的主鍵字段。如果你的主鍵字段名為 id,可以省略這個注解。
示例:
@Data
@TableName("user_info")
public class Userinfo {
@TableId("id")
private Integer userId;
private String username;
private String password;
private Integer age;
private Integer gender;
private String phone;
@TableField("delete_flag")
private Integer deleteflag;
private Date createTime;
private Date updateTime;
}
如果屬性名和字段名不一致, 需要在@TableId 指明對應(yīng)的字段名;屬性名和字段一致的情況下, 直接加@TableId 注解就可以。
@TableId 參數(shù)介紹:
- value
- 類型:String
- 默認值:
"" - 描述:指定數(shù)據(jù)庫表的主鍵字段名。如果不設(shè)置,MyBatis-Plus 將使用實體類中的字段名作為數(shù)據(jù)庫表的主鍵字段名。
- type
- 類型:Enum
- 默認值:IdType.NONE
- 描述:指定主鍵的生成策略。
IdType 枚舉類型定義
- IdType.AUTO:使用數(shù)據(jù)庫自增 ID 作為主鍵。
- IdType.NONE:無特定生成策略,如果全局配置中有 IdType 相關(guān)的配置,則會跟隨全局配置。
- IdType.INPUT:在插入數(shù)據(jù)前,由用戶自行設(shè)置主鍵值。
- IdType.ASSIGN_ID:自動分配 ID,適用于 Long、Integer、String 類型的主鍵。默認使用雪花算法通過 IdentifierGenerator 的 nextId 實現(xiàn)。
- IdType.ASSIGN_UUID:自動分配 UUID,適用于 String 類型的主鍵。默認實現(xiàn)為 IdentifierGenerator 的 nextUUID 方法。
詳情參考網(wǎng)址:注解配置
3.2 打印日志
Mybatis-Plus配置日志如下(application.yml):
mybatis-plus:
configuration: # 配置打印 MyBatis日志
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl3.3 條件構(gòu)造器
MyBatis-Plus 提供了一套強大的條件構(gòu)造器(Wrapper), 用于構(gòu)建復(fù)雜的數(shù)據(jù)庫查詢條件。Wrapper 類允許開發(fā)者以鏈式調(diào)用的方式構(gòu)造查詢條件, 無需編寫繁瑣的 SQL 語句, 從而提高開發(fā)效率并減少 SQL 注入的風(fēng)險。
以下是主要的 Wrapper 類及其功能:
- AbstractWrapper:這是一個抽象基類, 提供了所有 Wrapper 類共有的方法和屬性。詳細參考官網(wǎng)介紹: 條件構(gòu)造器
- QueryWrapper:用于構(gòu)造查詢條件, 在AbstractWrapper的基礎(chǔ)上拓展了一個select方法, 允許指定查詢字段。
- UpdateWrapper:用于構(gòu)造更新條件, 可以在更新數(shù)據(jù)時指定條件。
- LambdaQueryWrapper:基于 Lambda 表達式的查詢條件構(gòu)造器, 它通過 Lambda 表達式來引用實體類的屬性,從而避免了硬編碼字段名。
- LambdaUpdateWrapper:基于 Lambda 表達式的更新條件構(gòu)造器, 它允許你使用 Lambda 表達式來指定更新字段和條件,同樣避免了硬編碼字段名的問題。
3.3.1 QueryWrapper
QueryWrapper并不只用于查詢語句, 無論是修改, 刪除, 查詢, 都可以使用QueryWrapper來構(gòu)建查詢條件。
- 查詢
完成SQL:
SELECT id,username,password,age FROM user_info WHERE age = 18 AND username LIKE "%min%"
測試代碼:
@Test
@Test
void testQueryWrapper(){
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.select("id","username","password","age")
.eq("age",18)
.like("username","min");
List<UserInfo> userInfos = userInfoMapper.selectList(queryWrapper);
userInfos.forEach(System.out::println);
}
- 更新
完成SQL:
UPDATE user_info SET delete_flag=? WHERE age < 20
測試代碼:
@Test
@Test
void testUpdateByQueryWrapper(){
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();
queryWrapper.lt("age",20);
UserInfo userInfo = new UserInfo();
userInfo.setDeleteFlag(1);
userInfoMapper.update(userInfo,queryWrapper);
}
條件方法說明:
- lt : “less than” 的縮寫,表示小于
- le : "less than or equal to"的縮寫, 表示小于等于
- ge : “greater than or equal to” 的縮寫, 表示大于等于
- gt : “greater than” 的縮寫, 表示大于
- eq : “equals” 的縮寫, 表示等于
- ne : “not equals” 的縮寫, 表示不等于
- 刪除
完成SQL:
DELETE FROM user_info WHERE age = 18
測試代碼:
@Test
void testDeleteByQueryWrapper(){
QueryWrapper<UserInfo> userInfoQueryWrapper = new QueryWrapper<UserInfo>()
.eq("age",18);
userInfoMapper.delete(userInfoQueryWrapper);
}
3.3.2 UpdateWrapper
對于更新,也可以直接使用 UpdateWrapper,在不創(chuàng)建實體對象的情況下,直接設(shè)置更新字段和條件。
- 基礎(chǔ)更新
完成SQL:
UPDATE user_info SET delete_flag=0, age=5 WHERE id IN (1,2,3)
測試代碼:
@Test
void testUpdateWrapper(){
UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();
updateWrapper.set("delete_flag",1).set("age",5).in("id",List.of(2,3,5,8));
userInfoMapper.update(updateWrapper);
}- 基于SQL更新
完成SQL:
UPDATE user_info SET age = age+10 WHERE id IN (1,2,3)
測試代碼:
@Test
void testUpdateBySQLUpdateWrapper(){
UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<UserInfo>()
.setSql("age = age+10")
.in("id", List.of(1,2,3));
userInfoMapper.update(null, updateWrapper);
}
3.3.3 LambdaQueryWrapper
QueryWrapper 和 UpdateWrapper存在一個問題, 就是需要寫死字段名, 如果字段名發(fā)生變更, 可能會因為測試不到位釀成事故。
MyBatis-Plus 提供了一種基于Lambda表達式的條件構(gòu)造器, 它通過 Lambda 表達式來引用實體類的屬性,從而避免了硬編碼字段名,也提高了代碼的可讀性和可維護性。
- LambdaQueryWrapper
- LambdaUpdateWrapper
分別對應(yīng)上述的QueryWrapper和UpdateWrapper。
@Test
void testLambdaQueryWrapper(){
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>();
queryWrapper.lambda()
.select(UserInfo::getUsername, UserInfo::getPassword,UserInfo::getAge)
.eq(UserInfo::getId, 1);
userInfoMapper.selectList(queryWrapper).forEach(System.out::println);
}
3.3.4 LambdaUpdateWrapper
LambdaUpdateWrapper用法和 LambdaQueryWrapper相似:
@Test
void testLambdaUpdateByUpdateWrapper(){
UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<UserInfo>();
updateWrapper.lambda()
.set(UserInfo::getDeleteFlag, 0)
.set(UserInfo::getAge, 5)
.in(UserInfo::getId, List.of(1,2,3));
userInfoMapper.update(null, updateWrapper);
}
3.4 自定義SQL
在實際的開發(fā)中, MyBatis-Plus提供的操作不能滿足所有的實際需求, MyBatis-Plus 也提供了自定義 SQL的功能, 可以利用Wrapper構(gòu)造查詢條件, 再結(jié)合Mapper編寫SQL。
- 注:為了使用這一功能, mybatis-plus 版本不低于 3.0.7。
代碼示例1
完成下述SQL查詢:
select id,username,password,age FROM user_info WHERE username = "admin"
Mapper:
@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
@Select("select id,username,password,age FROM user_info ${ew.customSqlSegment}")
List<UserInfo> queryUserByCustom(@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);
}
測試代碼:
@Test
void testQueryUserByCustom(){
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>()
.eq("username","admin");
userInfoMapper.queryUserByCustom(queryWrapper).forEach(System.out::println);
}
注意:
- 參數(shù)命名:在自定義 SQL 時, 傳遞 Wrapper 對象作為參數(shù)時, 參數(shù)名必須為 ew ,或者使用注解 @Param(Constants.WRAPPER) 明確指定參數(shù)為 Wrapper 對象。
- 使用
${ew.customSqlSegment}:在 SQL 語句中,使用${ew.customSqlSegment}來引用 Wrapper 對象生成的 SQL 片段。 - 不支持基于 entity 的 where 語句:自定義 SQL 時,Wrapper 對象不會基于實體類自動生成 where 子句,你需要手動編寫完整的 SQL 語句。
代碼示例2
MyBatis-Plus 在 MyBatis 的基礎(chǔ)上只做增強不做改變, 所以也支持XML的實現(xiàn)方式。上述功能也可以使用XML的方式完成。
配置mapper路徑(application.yml):
mybatis-plus: mapper-locations: "classpath*:/mapper/**.xml" # Mapper.xml
Mapper:
List<UserInfo> queryUserByCustom2(@Param(Constants.WRAPPER) Wrapper<UserInfo> wrapper);
編寫XML:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.bite.mybatis.plus.mapper.UserInfoMapper">
<select id="queryUserByCustom2" resultType="com.bite.mybatis.plus.entity.UserInfo">
select id,username,password,age FROM user_info ${ew.customSqlSegment}
</select>
</mapper>測試:
@Test
void testQueryUserByCustom2(){
QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>()
.eq("username","admin");
userInfoMapper.queryUserByCustom2(queryWrapper).forEach(System.out::println);
}到此這篇關(guān)于MyBatis-Plus注解配置、條件構(gòu)造器與自定義SQL的復(fù)雜操作實例詳解的文章就介紹到這了,更多相關(guān)MyBatisPlus注解條件構(gòu)造器內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
關(guān)于ArrayList的動態(tài)擴容機制解讀
這篇文章主要介紹了關(guān)于ArrayList的動態(tài)擴容機制解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
關(guān)于Controller層和Service層的類報錯問題及解決方案
這篇文章主要介紹了關(guān)于Controller層和Service層的類報錯問題及解決方案,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-02-02
Springboot整合Swagger2后訪問swagger-ui.html 404報錯問題解決方案
這篇文章主要介紹了Springboot整合Swagger2后訪問swagger-ui.html 404報錯,本文給大家分享兩種解決方案,結(jié)合實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2023-06-06
詳解springboot設(shè)置cors跨域請求的兩種方式
這篇文章主要介紹了詳解springboot設(shè)置cors跨域請求的兩種方式,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-11-11

