更高的效率——MyBatis-plus

一、什么是MyBatis-plus?

MyBatis-plus是MyBatis的增強工具,在MyBatis基礎上只做增強不做改變,可以簡化基礎的CRUD操作(通過繼承?BaseMapper?接口可直接使用預定義的增刪改查方法)


二、MyBatis-plus快速入門

2.1 準備工作

2.1.1 數據庫數據準備
CREATE DATABASE mybatis_test DEFAULT CHARACTER SET utf8mb4;-- 使用數據庫
USE mybatis_test;-- 創建表[用戶表]
DROP TABLE IF EXISTS user_info;CREATE TABLE `user_info` (`id` INT ( 11 ) NOT NULL AUTO_INCREMENT,`username` VARCHAR ( 127 ) NOT NULL,`password` VARCHAR ( 127 ) NOT NULL,`age` TINYINT ( 4 ) NOT NULL,`gender` TINYINT ( 4 ) DEFAULT '0' COMMENT '1-男 2-女 0-默認',`phone` VARCHAR ( 15 ) DEFAULT NULL,`delete_flag` TINYINT ( 4 ) DEFAULT 0 COMMENT '0-正常,1-刪除',`create_time` DATETIME DEFAULT now(),`update_time` DATETIME DEFAULT now(),PRIMARY KEY ( `id` )
) ENGINE = INNODB DEFAULT CHARSET = utf8mb4;-- 添加用戶信息
INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone ) 
VALUES ( 'admin', 'admin', 18, 1, '18612340001' );INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone ) 
VALUES ( 'zhangsan', 'zhangsan', 18, 1, '18612340002' );INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone ) 
VALUES ( 'lisi', 'lisi', 18, 1, '18612340003' );INSERT INTO mybatis_test.user_info( username, `password`, age, gender, phone ) 
VALUES ( 'wangwu', 'wangwu', 18, 1, '18612340004' );

2.1.2 項目準備

1.創建SpringBoot項目;

2.添加MyBatis-plus和MySQL依賴,配置數據庫連接信息。

一、添加MyBatis-plus依賴(SpringBoot 3)和MySQL依賴

<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-spring-boot3-starter</artifactId><version>3.5.5</version>
</dependency>
<dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><scope>runtime</scope>
</dependency>

二、配置數據庫連接信息

# 數據庫連接配置 
spring:datasource:url: jdbc:mysql://127.0.0.1:3306/mybatis_test?
characterEncoding=utf8&useSSL=falseusername: rootpassword: rootdriver-class-name: com.mysql.cj.jdbc.Driver

2.2 代碼準備

?一、創建實體類UserInfo與表中字段對應

@Data
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;}

?二、創建Mapper接口并繼承BaseMapper

@Mapper
public interface UserInfoMapper extends BaseMapper<UserInfo> {
}

查看BaseMapper,可以發現其中已經準備了各種基礎的SQL對應的方法:

這也就是為什么使用MyBatis-plus無需手動編寫SQL以及對應方法的原因。


2.3 CRUD單元測試

@SpringBootTest
class DemoApplicationTests {@Autowiredprivate UserInfoMapper userInfoMapper;@Testvoid selectById() {UserInfo userInfo = userInfoMapper.selectById(1);System.out.println(userInfo);}@Testvoid selectByIds() {List<UserInfo> userInfos = userInfoMapper.selectByIds(List.of(22,23,24));System.out.println(userInfos);}@Testvoid insert() {UserInfo userInfo = new UserInfo();userInfo.setUsername("王五");userInfo.setPhone("381200");userInfo.setGender(3);userInfo.setAge(19);userInfoMapper.insert(userInfo);}@Testvoid deleteById() {userInfoMapper.deleteById(1);}@Testvoid update() {UserInfo userInfo = new UserInfo();userInfo.setId(1);userInfo.setUsername("宮本");userInfoMapper.updateById(userInfo);}}

測試結果如下:

全部執行成功


三、MyBatis-plus復雜操作

?3.1 Mybatis-plus常見注解

在上面的代碼中,MyBatis是如何知道我們操作的是哪個表的?表中又有那些字段?觀察一下前面的Mapper接口:

BaseMapper指定了一個泛型,這個UserInfo就是與相應表對應的實體類,Mybatis-plus會根據實體類來推斷表的信息,默認情況下:

1.表名:由駝峰表示法轉換為蛇形表示法(如UserInfo->user_info)

2.字段名:也是駝峰表示法轉換為蛇形表示法(如deleteFlag->delete_flag)

3.主鍵:默認為id

當然,如果設計表時或編寫實體類時沒有按照標準定義類名/表名、屬性名/字段名,MyBatis-plus就無法正確推斷,此時就需要注解來標識類名對應的表名(或屬性名對應的字段名)


3.1.1 @TableName

@TableName用于標識類所對應的表名是什么

我們先將類名UserInfo改為Userinfo:

現在,再次測試selectByIds方法:

可以看到結果報錯了,提示userinfo這個表并不存在,可以看到由于命名的不規范導致MyBatis-plus無法正確推斷表名,接下來使用注解@TableName標識:

@Data
@TableName("user_info")//告知MyBatis-plus這個類對應的是哪個表
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;
}

再次測試selectByIds方法:

程序執行成功。


3.1.2 @TableField

?@TableName用于標識屬性所對應的字段名是什么

將屬性deleteFlag改為deleteflag:

測試insert方法:

報錯,提示字段deletefalg不存在,接下來,使用注解@TableFiled標識類中屬性對應的字段名:

@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;//告知MyBatis-plus這個屬性對應的字段是什么@TableField("delete_flag")private Integer deleteflag;private Date createTime;private Date updateTime;
}

再次測試:

執行成功。


3.1.3 @TableId

?@TableId用于標識表中主鍵對應的屬性是什么,一般將屬性名id作為主鍵,但是,如果將id修改為userId,MyBatis-plus就無法識別了,此時可以使用@TableId注解的value屬性標識主鍵,如:

測試方法和上面的兩個注解類似,這里就不再測試了,下面我們要介紹的是@TableId的另一個重要屬性——type

我們先測試insert方法,往user_info中插入一個新數據并觀察:

可以看到,新插入的數據id是一個非常小的負數,這是因為@TableId注解的type屬性默認值為IdType.ASSIGN_ID一般來說,主鍵默認為自增的,但是type屬性的默認值并不是自增,接下來,修改type屬性的值為IdType.AUTO

public class Userinfo {//將id設置為自增@TableId(type = IdType.AUTO)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;
}

再次測試insert方法:

可以看到,修啊給type后,id正常自增


3.2 打印MyBatis-plus日志

?在配置文件中添加以下配置即可:

mybatis-plus:configuration: # 配置打印 MyBatis?志 log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

3.3 條件構造器(Wrapper)

前面只是使用MyBatis-plus進行一些簡單的CRUD操作,但是在實際應用中,可能還會在SQL語句中加入一些條件(如 id!=10 等),對于這種情況,MyBatis-plus為我們提供了一套強大的條件構造器(Wrapper),下面是主要的Wrapper類:

AbstractWrapper?個抽象基類,提供了所有Wrapper類共有的方法和屬性
QueryWrapper?于構造查詢條件,在AbstractWrapper的基礎上拓展了?個select?法,允許指定查詢字段
UpdateWrapper?于構造更新條件,可以在更新數據時指定條件
LambdaQueryWrapper基于Lambda表達式的查詢條件構造器,它通過Lambda表達式來引用實體類的屬性,從而避免了硬編碼字段名
LambdaupdateWrapper基于Lambda表達式的更新條件構造器,它允許你使?Lambda表達式來指定更新字段和條件,同樣避免了硬編碼字段名的問題
3.3.1 QueryWrapper

?QueryWrapper只是一個條件構造器,并不是只能用于查詢語句,其它的刪除、更新語句也同樣可以使用。

一、查詢
使用構造器構造如下SQL:

SELECT id,username,password,age FROM user_info WHERE age = 18 AND username 
"%min%"

在測試代碼中構造:

	@Testvoid testQueryWrapper(){QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>().select("id","username","age","password").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

測試代碼:

@Testvoid testQueryWrapper2(){QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>().lt("age",20);UserInfo userInfo = new UserInfo();userInfo.setDeleteFlag(0);userInfoMapper.update(userInfo,queryWrapper);}

三、刪除

使用構造器構造如下SQL:

DELETE FROM user_info WHERE age = 18

測試代碼:

   @Testvoid testQueryWrapper3() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<UserInfo>().eq("age",18);userInfoMapper.delete(queryWrapper);}

在上面使用構造器的代碼中,涉及到一些縮寫的方法,這里列舉出常見的縮寫方法的含義:

? ? ? ?lt“less than” 的縮寫,表示小于
? ? ? ?le“less than or equal to” 縮寫,表示小于或等于
? ? ? ?ge“greater than or equal to”縮寫 ,表示大于或等于
? ? ? ?gt“greater than”縮寫,表示大于
? ? ? ?eq“equals”縮寫,表示等于
? ? ? ?ne“not equals”縮寫,表示不等于

?


3.3.2 UpdateWrapper

對于更新語句,可以直接使用UpdateWrapper構造器進行構造,這要就不必創建對應的實體類(相較于QueryWrapper,多了一個set和setSql方法)

一、set方法

使用UpdateWrapper構造器構造如下SQL:

UPDATE user_info SET delete_flag=0, age=5 WHERE id IN (1,2,3)

測試代碼:

    @Testvoid testUpdateWrapper(){UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();updateWrapper.set("delete_flag",0).in("id",List.of(1,2,3));userInfoMapper.update(updateWrapper);}

二、setSql方法(基于SQL更新)

  @Testvoid testUpdateWrapper2(){UpdateWrapper<UserInfo> updateWrapper = new UpdateWrapper<>();updateWrapper.setSql("age = age + 10").eq("id",1);userInfoMapper.update(updateWrapper);}

3.3.3 LambdaQueryWrapper

?前面的QueryWrapper和UpdateWrapper都有一個共同特點,就是將字段名寫死了,如果后續字段名發生變化,這里也不會報錯,對此MyBatis-Plus 給我們提供了一種基于Lambda表達式的條件構造器,它通過 Lambda 表達式來引用實體類的屬性,從而避免了硬編碼字段名,也提高了代碼的可讀性和可維護性.

使用LambdaQueryWrapper構造以下SQL:
?

UPDATE user_info SET delete_flag=? WHERE age < 20

測試代碼:

@Testvoid lambdaQueryWrapper(){LambdaQueryWrapper<UserInfo> lambdaQueryWrapper = new LambdaQueryWrapper<>();UserInfo userInfo = new UserInfo();userInfo.setDeleteFlag(0);lambdaQueryWrapper.in(UserInfo::getId,List.of(1,2,3));userInfoMapper.update(userInfo,lambdaQueryWrapper);}

3.3.4 LambdaUpdateWrapper

?使用LambdaUpdateWrapper構造以下SQL:

UPDATE user_info SET delete_flag=0, age=5 WHERE id IN (1,2,3)

測試代碼:
?

  @Testvoid lambdaUpdateWrapper(){LambdaUpdateWrapper<UserInfo> lambdaUpdateWrapper = new LambdaUpdateWrapper<>();lambdaUpdateWrapper.set(UserInfo::getDeleteFlag,5).set(UserInfo::getAge,5).in(UserInfo::getId,List.of(1,2,3));userInfoMapper.update(lambdaUpdateWrapper);}

3.4 自定義SQL

?對于更加復雜的查詢語句(如子查詢),可能無法直接使用條件構造器完成,因此,MyBatis-plus提供了自定義SQL的功能,可以利用Wrapper構造查詢條件,再結合Mapper編寫SQL

使用自定義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> selectUserInfoByCondition (@Param(Constants.WRAPPER) Wrapper<UserInfo> ew);
}

測試代碼:
?

  @Testvoid selectUserInfoByCondition() {QueryWrapper<UserInfo> queryWrapper = new QueryWrapper<>();queryWrapper.lt("age",20);userInfoMapper.selectUserInfoByCondition(queryWrapper).forEach(System.out::println);}

?使用自定義SQL,由幾個注意事項:

? 參數命名:在自定義 SQL 時, 傳遞 Wrapper 對象作為參數時, 參數名必須為 ew ,或者使用注解 @Param(Constants.WRAPPER) 明確指定參數為 Wrapper 對象.?

? 使用?${ew.customSqlSegment} 在 SQL 語句中,使用 ${ew.customSqlSegment} 來 引用 Wrapper 對象生成的 SQL 片段.?

? 不支持基于 entity 的 where 語句自定義 SQL 時,Wrapper 對象不會基于實體類自動生成? where 子句,你需要手動編寫完整的 SQL 語句.

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/76121.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/76121.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/76121.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【算法基礎】遞歸與遞推

目錄 遞歸實現指數型枚舉 題目 算法解析 遞歸實現排列型枚舉 題目 算法解析 費解的開關 題目 算法解析 遞歸實現組合型枚舉 題目 算法解析 帶分數 題目 算法解析 飛行員兄弟 題目 算法解析 翻硬幣 題目 算法解析 遞歸實現指數型枚舉 題目 算法…

Java 大視界 -- Java 大數據在智慧礦山設備故障預測與預防性維護中的技術實現(163)

&#x1f496;親愛的朋友們&#xff0c;熱烈歡迎來到 青云交的博客&#xff01;能與諸位在此相逢&#xff0c;我倍感榮幸。在這飛速更迭的時代&#xff0c;我們都渴望一方心靈凈土&#xff0c;而 我的博客 正是這樣溫暖的所在。這里為你呈上趣味與實用兼具的知識&#xff0c;也…

綜合實驗一

實驗拓撲圖&#xff1a; 實驗要求&#xff1a; 1,內網IP地址使用172.16.0.0/16分配 2,SW1和SW2之間互為備份 3,VRRP/STP/VLAN/Eth-trunk均使用 4,所有PC均通過DHCP獲取IP地址 5,ISP只能配置IP地址 6,所有電腦可以正常訪問ISP路由器環回 實驗步驟&#xff1a; 步驟1&…

snort檢測端口掃描工具

前面兩篇文章介紹了snort3相關知識和Ubuntu上的安裝配置Ubuntu22.04上Snort3的安裝與基本配置 -CSDN博客 和Snort規則定義并進行的簡單的測試Snort規則定義與測試 -CSDN博客&#xff0c;接下來我將介紹如何編寫一個簡單的檢測端口掃描的規則進行檢測 一、實驗環境 攻擊機&…

【行測】資料分析

> 作者&#xff1a;?舊言~ > 座右銘&#xff1a;讀不在三更五鼓&#xff0c;功只怕一曝十寒。 > 目標&#xff1a;掌握 資料分析 基本題型&#xff0c;并能運用到例題中。 > 毒雞湯&#xff1a;有些事情&#xff0c;總是不明白&#xff0c;所以我不會堅持。早安! …

工地揚塵監測儀:守護藍天白云的重要工具

在城市化進程加速推進的背景下&#xff0c;建筑工地數量呈現持續增長態勢&#xff0c;揚塵污染問題亦愈發顯著。揚塵不僅對空氣質量造成負面影響&#xff0c;更對周邊居民的健康狀況及生活質量構成威脅。在此情形下&#xff0c;工地揚塵監測儀作為建筑工地環境管理中不可或缺的…

Windows10 下QT社區版的安裝記錄

0. 介紹 踩了一些坑&#xff0c;記錄一下&#xff0c;主要是鏡像源的問題。 1. 安裝 首先你先要在qt官網上有一個自己的賬號。 然后點右上角的下載 打開后&#xff0c;我們需要選擇社區版本&#xff1b;如果選擇直接下載的話&#xff0c;出來的就是商業版本。 點開后&…

自定義一個C語言字符串取整函數

一、字符串取整的主要思路 1、遍歷每個字符&#xff1b; 2、獲得0到9的字符對應的整數值&#xff1b; 3、把對應位置的十進制權重相乘&#xff1b; 4、把所有的相乘結果相加&#xff1b; 5、返回相加結果&#xff1b; 二、主要代碼 // 主要是把十進制的整數字符轉成十進制變量值…

VS Code C/C++項目設置launch.json中的environment參數解決支持庫路徑問題

問題描述 Windows 11 VS Code C/C 開發環境搭建分別寫了c和cpp兩個示例代碼&#xff0c;在運行過程中c代碼沒有發現問題&#xff08;可能簡單&#xff0c;沒有用到太多支持&#xff09;&#xff0c;但使用了stl的cpp代碼并沒有運行出來&#xff0c;如下圖&#xff1a; 出問題…

C語言pthread庫的互斥鎖使用案例

一、函數約定 1、初始化鎖 int pthread_mutex_init(pthread_mutex_t* m, const pthread_mutexattr_t* attr) 2、加鎖 int pthread_mutex_lock(pthread_mutex_t* m); 3、解鎖 int pthread_mutex_unlock(pthread_mutex_t* m); 4、銷毀 int pthread_mutex_de…

隨機2級域名引導頁HTML源碼

源碼介紹 隨機2級域名引導頁HTML源碼,每次點進去都隨機一個域名前綴。 修改跳轉域名在 350 行代碼&#xff0c;源碼由HTMLCSSJS組成&#xff0c;記事本打開源碼文件可以進行內容文字之類的修改&#xff0c;雙擊html文件可以本地運行 效果預覽 源碼免費獲取 隨機2級域名引導頁…

NQA 網絡質量分析協議

協議信息 網絡質量分析協議&#xff0c;支持 icmp 等協議測試 配置實現 華為 創建 ICMP 測試實例 NQA 與靜態路由聯動 ?ip route-static 10.1.1.0 24 10.1.2.1 track nqa admin test1??

Nginx — nginx.pid打開失敗及失效的解決方案

1、場景一&#xff1a;nginx.pid文件或者目錄不存在 1.1、報錯詳情 [rootmaster conf]# ../sbin/nginx -s reload nginx: [error] open() "/var/run/nginx/nginx.pid" failed (2: No such file or directory) #nginx.pid文件或目錄不存在。 原因&#xff1a; 1、文件…

Gitee批量刪除倉庫

Gitee批量刪除倉庫 文章目錄 Gitee批量刪除倉庫生成一個GiteeToken通過Python調用Gitee API參考文檔 生成一個GiteeToken 右上角下拉->設置->安全設置->私人令牌->生成新令牌&#xff0c;注意將令牌保存&#xff08;只會出現一次&#xff09; 通過Python調用Gite…

AireOS WLC安裝License報錯

1.概述 本文主要記錄在AireOS的WLC上安裝License錯誤的情況。License的類型也是傳統的License&#xff0c;因為設備的型號已經EOL&#xff0c;相關的資料應該較少&#xff0c;這里進行可能問題的記錄。 2.適用場景 型號&#xff1a;WLC2500&#xff0c;WLC5508 License類型…

利用 Excel 函數隨機抽取(附示例)

RANDARRAY 是 Excel 365 和 Excel 2021 引入的一個函數&#xff0c;用于生成一個隨機數數組。它的語法如下&#xff1a; RANDARRAY([rows], [columns], [min], [max], [whole_number])參數詳解 rows&#xff08;可選&#xff09; 要生成的行數&#xff08;默認值為 1&#xff…

Python:爬蟲概念與分類

網絡請求&#xff1a; https://www.baidu.com url——統一資源定位符 請求過程&#xff1a; 客戶端&#xff0c;指web瀏覽器向服務器發送請求 請求&#xff1a;請求網址(request url)&#xff1b;請求方法(request methods)&#xff1b;請求頭(request header)&…

【今日半導體行業分析】2025年3月30日

今日探針卡行業分析&#xff1a;把握機遇&#xff0c;應對挑戰 一、引言 在半導體產業的精密制造流程中&#xff0c;探針卡作為晶圓測試環節的核心設備&#xff0c;猶如一顆精密的 “心臟”&#xff0c;承擔著芯片封裝前電學性能測試與篩選的重任。其性能的優劣直接關系到芯片…

HO與OH差異之Navigation三

在上一篇內容中我們介紹了HO與OH差異之Navigator&#xff0c;我們也了解了Navigator的基本概念和大致了解了一下他的基礎用法&#xff0c;既然談到差異肯定就不止這兩種差異&#xff0c;今天就讓我們來了解第三種差異NavRouter&#xff0c;其中在HO中我們并沒有這種路由方式但是…

Java 程序員面試題:從基礎到高階的深度解析

引言 Java 作為全球最流行的編程語言之一&#xff0c;其面試題不僅考察候選人的編程能力&#xff0c;更關注對底層原理和架構設計的理解。本文將系統梳理 Java 面試中的高頻考點&#xff0c;結合代碼示例與原理分析&#xff0c;助您從容應對技術面試。 一、Java 基礎語法與核…