Mybatis-Plus進階分頁與樂觀鎖插件及通用枚舉和多數(shù)據(jù)源詳解
分頁插件
MP中自帶了分頁插件的功能,只需要在配置類中進行簡單的配置即可使用分頁的相關功能。分頁插件常常與前端的分頁顯示功能相關,為了在前端美觀的顯示查詢到的數(shù)據(jù),通常會使用分頁插件,將所有的數(shù)據(jù)分成許多頁一頁一頁的進行顯示,不同頁的切換使用按鈕來完成
MP的插件配置類
@Configuration
public class MybatisPlusConfiguration {
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
// 創(chuàng)建一個MybatisPlus的插件攔截器
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
// 創(chuàng)建分頁的插件對象并設置數(shù)據(jù)庫類型
PaginationInnerInterceptor paginationInnerInterceptor = new PaginationInnerInterceptor(DbType.MYSQL);
// 設置請求的頁面大于最大頁后操作, true調(diào)回到首頁,false 繼續(xù)請求 默認false
paginationInnerInterceptor.setOverflow(true);
// 設置分頁的單頁最多條數(shù),默認 500 條,-1 不受限制
paginationInnerInterceptor.setMaxLimit(500L);
// 將這個分頁插件添加到攔截器中并返回
interceptor.addInnerInterceptor(paginationInnerInterceptor);
return interceptor;
}
}自定義方法并調(diào)用分頁
mapper定義方法
@Mapper
@Repository
public interface UserMapper extends BaseMapper<User> {
/**
* 通過年齡查詢用戶信息并分頁返回
* @param page 傳入一個page對象
* @param age 年齡
* @return 返回一個page對象
*/
Page<User> selectPageVo(@Param("page") Page<User> page, @Param("age") Integer age);
}映射文件編寫SQL語句
<mapper namespace="com.xiaochen.mapper.UserMapper">
<select id="selectPageVo" resultType="com.xiaochen.domain.User">
select id,name,age,email from user where age > #{age}
</select>
</mapper>測試方法調(diào)用自定義方法
@Autowired
UserMapper mapper;
@Test
public void testpage() {
// 創(chuàng)建一個page對象,設置當前頁是第1頁,每頁包含3條記錄
Page<User> page = new Page<>(2, 3);
// mapper調(diào)用selectPage方法之后將結(jié)果返回給上面的page對象
// 第二個參數(shù)null的話就是查詢所有的記錄,如果有查詢條件的話就傳一個wrapper對象
mapper.selectPageVo(page, 20);
// 當前頁的數(shù)據(jù)
System.out.println(page.getRecords());
// 當前是第幾頁
System.out.println(page.getCurrent());
// 總頁數(shù)
System.out.println(page.getPages());
// 每頁的記錄數(shù)
System.out.println(page.getSize());
// 總記錄數(shù)
System.out.println(page.getTotal());
// 是否有下一頁
System.out.println(page.hasNext());
// 是否有上一頁
System.out.println(page.hasPrevious());
}樂觀鎖插件
要想使用樂觀鎖插件,首先要知道什么是樂觀鎖以及樂觀鎖出現(xiàn)的原因。現(xiàn)實生活中,一個管理系統(tǒng)往往不僅僅只有一個管理員,以修改商品價格為例,如果有兩個管理員小李和小王商品的原價為100,老板先是讓小李將商品的價格上調(diào)50,一段時間后讓小王將商品的價格下調(diào)20,由于小李有事耽擱,兩個人同時登錄管理系統(tǒng)獲取到商品的價格對其分別進行修改操作。如果小李最后完成操作的話商品最終為150元,如果小王最后完成操作的話商品最終為80元,這樣的話就會造成最終的價格不是老板想要的130。
要想使用代碼實現(xiàn)上述案例的話,使用線程來實現(xiàn)的話更加真實(可以模擬兩人處理先后的不確定性),但是為了簡化操作,設定最后完成操作的是小王,也即是說最后商品的價格為80
@Test
public void happyLockTest() {
// 小李查詢商品的價格
Product productLi = mapper.selectById(1);
// 小王查詢到商品的價格
Product productWang = mapper.selectById(1);
// +50
productLi.setPrice(productLi.getPrice() + 50);
mapper.updateById(productLi);
// -20
productWang.setPrice(productWang.getPrice() - 20);
mapper.updateById(productWang);
// 查詢最終的商品價格
System.out.println("最終價格為:" + mapper.selectById(1).getPrice());
}// 控制臺最終打印 -> 最終價格為:80
有問題就有解決問題的方法,出現(xiàn)這個問題的原因就是兩個管理員同時獲取到了商品的信息并對他進行了修改,如果可以使用鎖限制同一時間只能有一個管理員對數(shù)據(jù)進行修改操作的話,就可以避免這個問題了,這就是悲觀鎖。
不對啊,不是說要講樂觀鎖的嘛怎么講到了悲觀鎖了?悲觀鎖將整張表鎖住了,阻止其他人對表進行修改操作,這樣的話對效率有很大的折損。于是樂觀鎖應運而生,樂觀鎖允許任何人任何時候?qū)Ρ碇袛?shù)據(jù)進行修改,只不過數(shù)據(jù)表中要添加一個字段表示數(shù)據(jù)的當前版本號,數(shù)據(jù)每經(jīng)過一次更新版本號就相應加一,數(shù)據(jù)每次更新的時候都會帶上版本號字段作為更新的條件。這樣的話就可以避免之前的問題了,兩人同時獲取到的版本都是0,小李修改之后就會將版本字段值加一也就是1,這時小王修改的時候就會查不到表中版本號為0的數(shù)據(jù)而無法修改。
這樣的話就會避免修改沖突,但是還是無法得到想要的結(jié)果,于是可以對兩人的修改結(jié)果進行判斷,如果更新操作的返回結(jié)果不是0的話就說明更新成功,否則就再次獲取數(shù)據(jù)表中的信息(這次就是為了獲得最新的版本號)再次進行更新操作
使用MP中的樂觀鎖插件,首先需要在配置類中將樂觀鎖插件添加到攔截器中,然后再在實體類中的版本號字段上使用@Version標志,然后就是和平常一樣的操作數(shù)據(jù)庫即可,執(zhí)行更新操作的時候會自動將當前查詢到的版本號當做條件拼接到SQL語句中
// 將樂觀鎖插件添加到攔截器中
interceptor.addInnerInterceptor(new OptimisticLockerInnerInterceptor());
// 實體類標注版本號
@Version
private Integer version;
// 測試方法,測試兩個人最后的修改結(jié)果
@Test
public void happyLockTest() {
// 小李查詢商品的價格
Product productLi = mapper.selectById(1);
// 小王查詢到商品的價格
Product productWang = mapper.selectById(1);
// +50
int result = 0;
do {
// 更新失敗,重新查詢并修改
productLi = mapper.selectById(1);
productLi.setPrice(productLi.getPrice() + 50);
result = mapper.updateById(productLi);
} while (result == 0);
// -20
do {
// 更新失敗,重新查詢并修改
productWang = mapper.selectById(1);
productWang.setPrice(productWang.getPrice() - 20);
result = mapper.updateById(productWang);
} while (result == 0);
// 查詢最終的商品價格
System.out.println("最終價格為:" + mapper.selectById(1).getPrice());
}// 控制臺最終打印 -> 最終價格為:130
通用枚舉類
對于表中擁有固定幾個值的一些字段,可以使用枚舉類將比較簡單的數(shù)字或字符存入到數(shù)據(jù)庫表中,然后將這個簡單的數(shù)字或字符對應著其具體的字符串表示,比如性別0代表女1代表男。這樣就會減輕數(shù)據(jù)庫的存儲壓力,提高用戶的使用體驗。 使用MP的通用枚舉必須先創(chuàng)建一個枚舉類,向外提供屬性的getter方法和全參構造器,并使用@EnumValue注解將標識的屬性值在數(shù)據(jù)庫中存儲
@Getter
@AllArgsConstructor
public enum SexEnum {
FEMALE(0, "女"),
MALE(1, "男");
// 將注解標識的屬性值存儲到數(shù)據(jù)庫中
@EnumValue
private Integer sex;
private String sexName;
}然后實體類中修改字段對應屬性的類型為枚舉類型,然后重寫toString方法,方便查詢結(jié)果顯示為數(shù)據(jù)表中數(shù)字或字符對應的具體的字符串表示
// 修改字段對應屬性的類型為枚舉類型
private SexEnum sex;
// 重寫toString方法
@Override
public String toString() {
return "User{" +
"id=" + id +
", name='" + name + '\'' +
", sex=" + sex.getSexName() +
", age=" + age +
", email='" + email + '\'' +
", isDeleted=" + isDeleted +
'}';
}最后在配置文件中設置通用枚舉的包,也就是相當于讓你寫的枚舉類生效
mybatis-plus: # 設置通用枚舉的包 type-enums-package: com.xiaochen.enums
測試
@Test
public void enumTest() {
User user = new User();
user.setName("張三");
user.setAge(23);
user.setSex(SexEnum.FEMALE);
mapper.insert(user);
User user1 = mapper.selectById(6);
System.out.println(user1);
}測試結(jié)果

多數(shù)據(jù)源
多數(shù)據(jù)源就是在一個程序中同時配置多個數(shù)據(jù)庫作為數(shù)據(jù)源進行操作,適用于多種場景:純粹多庫、 讀寫分離、 一主多從、 混合模式等。目前我們就來模擬一個純粹多庫的一個場景,配置兩個數(shù)據(jù)庫的兩張表,通過一個測試用例分別獲取兩張表的數(shù)據(jù),如果獲取到說明多庫模擬成功
第一步: 導入依賴
<!--mybatis-的場景啟動器-->
<dependency>
<groupId>com.baomidou</groupId>
<artifactId>mybatis-plus-boot-starter</artifactId>
<version>3.5.1</version>
</dependency>第二步: 配置文件配置多數(shù)據(jù)源
spring:
# 配置數(shù)據(jù)源信息
datasource:
dynamic:
# 設置默認的數(shù)據(jù)源或者數(shù)據(jù)源組,當設置的數(shù)據(jù)源都找不到時使用默認數(shù)據(jù)源,默認值即為master
primary: master
# 嚴格匹配數(shù)據(jù)源,默認false.true未匹配到指定數(shù)據(jù)源時拋異常,false匹配不到指定數(shù)據(jù)源時使用默認數(shù)據(jù)源
strict: false
datasource:
# 主數(shù)據(jù)源
master:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/mybatis_plus
username: root
password: 123456
# 從數(shù)據(jù)源
slave_1:
driver-class-name: com.mysql.jdbc.Driver
url: jdbc:mysql://localhost:3306/test
username: root
password: 123456
第三步: 照常使用方法測試在兩個數(shù)據(jù)庫查詢兩張表,唯一不同的就是在service的實現(xiàn)類上使用@DS注解,標注service實現(xiàn)類的所有方法都是對指定數(shù)據(jù)源進行操作的

測試類及結(jié)果

到此這篇關于Mybatis-Plus進階分頁與樂觀鎖插件及通用枚舉和多數(shù)據(jù)源詳解的文章就介紹到這了,更多相關Mybatis-Plus 分頁插件內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
SpringBoot中多環(huán)境yml的配置與打包問題
這篇文章主要介紹了SpringBoot中多環(huán)境yml的配置與打包問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-09-09
Springboot 使用 JSR 303 對 Controller 控制層校驗及 Service 服務層 AOP 校驗
這篇文章主要介紹了Springboot 使用 JSR 303 對 Controller 控制層校驗及 Service 服務層 AOP 校驗 使用消息資源文件對消息國際化的相關知識,需要的朋友可以參考下2017-12-12
使用zip4j實現(xiàn)Java中的ZIP文件加密壓縮的操作方法
本文介紹如何通過Maven集成zip4j 1.3.2庫創(chuàng)建帶密碼保護的ZIP文件,涵蓋依賴配置、代碼示例及加密原理,確保數(shù)據(jù)安全性,感興趣的朋友一起看看吧2025-07-07
SpringBoot整合Kafka、Flink實現(xiàn)流式處理的方法
這篇文章給大家介紹SpringBoot整合Kafka、Flink實現(xiàn)流式處理,本文將指導您如何在SpringBoot應用中整合Kafka和Flink,從而實現(xiàn)一個完整的實時數(shù)據(jù)處理流水線,感興趣的朋友跟隨小編一起看看吧2025-06-06

