文章背景
最近在測試業務需求時通讀了研發指定需求的代碼,發現研發大佬們用到了如下的內容,有些內容我還不是十分的清楚,比如下述真實代碼;作為后端大佬肯定爐火純青,但是我剛剛看到這段代碼時確實有點懵;
快速理解的方式
直接借助joycoder解釋代碼的能力就可以快速理解

于是乎有了下述的探索

但是我為了理解的透徹點還是又去翻找了一些其它資料做一個記錄吧,后續萬一在遺忘了也方便快速查找

MyBatis-Plus的LambdaQueryWrapper簡介
LambdaQueryWrapper是MyBatis-Plus提供的一種類型安全的查詢條件構造器,它利用Java 8的Lambda表達式特性,避免了硬編碼字段名,提高了代碼的可讀性和可維護性。
基本用法示例
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper?>();
queryWrapper.eq(User::getName, "張三")
.ge(User::getAge, 18)
.orderByDesc(User::getCreateTime);
List userList = userMapper.selectList(queryWrapper);
LambdaQueryWrapper的優勢
類型安全:通過方法引用而非字符串指定字段,編譯器可檢查類型
代碼可讀性高:鏈式調用,語義清晰
防止SQL注入:自動處理參數綁定
智能提示:IDE可自動補全字段名
Spring Boot的@Async異步處理
@Async是Spring框架提供的注解,用于標記方法為異步執行。被@Async注解的方法會在調用時立即返回,而實際執行將發生在單獨的線程中。
基本配置
首先需要在Spring Boot啟動類或配置類上添加@EnableAsync注解:
@SpringBootApplication
@EnableAsync
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
簡單使用示例
@Service
public class AsyncService {
@Async
public void asyncMethod() {
// 這個方法將在單獨的線程中執行
System.out.println("執行異步方法: " + Thread.currentThread().getName());
}
}
LambdaQueryWrapper與@Async的結合實踐
將兩者結合使用可以實現高效的異步數據庫操作,特別適合那些不需要立即返回結果的復雜查詢或批量操作。
示例1:異步查詢用戶列表
@Service @RequiredArgsConstructor public class UserService { private final UserMapper userMapper; @Async public CompletableFuture> asyncFindUsers(String name, Integer minAge) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper?>(); queryWrapper.like(StringUtils.isNotBlank(name), User::getName, name) .ge(minAge != null, User::getAge, minAge); List users = userMapper.selectList(queryWrapper); return CompletableFuture.completedFuture(users); } }
示例2:異步統計與保存
@Async
public void asyncStatAndSave(Long departmentId) {
// 統計部門人數
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper?>();
queryWrapper.eq(User::getDepartmentId, departmentId);
long count = userMapper.selectCount(queryWrapper);
// 更新統計結果
Department department = new Department();
department.setId(departmentId);
department.setUserCount(count);
departmentMapper.updateById(department);
// 記錄統計日志
StatLog statLog = new StatLog();
statLog.setDepartmentId(departmentId);
statLog.setCount(count);
statLog.setStatTime(LocalDateTime.now());
statLogMapper.insert(statLog);
}
高級應用與優化
自定義線程池配置
默認情況下,@Async使用SimpleAsyncTaskExecutor,這不是生產環境的最佳選擇。我們可以自定義線程池:
@Configuration
public class AsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
executor.setCorePoolSize(10);
executor.setMaxPoolSize(50);
executor.setQueueCapacity(100);
executor.setThreadNamePrefix("AsyncExecutor-");
executor.initialize();
return executor;
}
}
異常處理
異步方法的異常不會傳播到調用線程,需要特別處理:
@Async
public CompletableFuture> asyncFindUsersWithExceptionHandling(String name) {
try {
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper?>();
queryWrapper.like(User::getName, name);
List users = userMapper.selectList(queryWrapper);
return CompletableFuture.completedFuture(users);
} catch (Exception e) {
// 記錄日志
log.error("異步查詢用戶失敗", e);
// 返回空列表或拋出CompletionException
return CompletableFuture.completedFuture(Collections.emptyList());
}
}
事務處理
@Async方法的事務需要特別注意,默認情況下異步方法的事務不會傳播:
@Async
@Transactional(propagation = Propagation.REQUIRES_NEW)
public void asyncUpdateWithTransaction(User user) {
// 這個更新操作將在新事務中執行
userMapper.updateById(user);
}
實際應用場景
后臺報表生成
@Async public void asyncGenerateUserReport(LocalDate startDate, LocalDate endDate, String reportPath) { LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper?>(); queryWrapper.between(User::getCreateTime, startDate.atStartOfDay(), endDate.atTime(23, 59, 59)) .orderByAsc(User::getCreateTime); List users = userMapper.selectList(queryWrapper); // 生成報表文件 generateExcelReport(users, reportPath); // 發送通知 sendReportReadyNotification(reportPath); }
批量數據處理
@Async
public CompletableFuture asyncBatchProcessUsers(List userIds) {
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper?>();
queryWrapper.in(User::getId, userIds);
List users = userMapper.selectList(queryWrapper);
int processedCount = 0;
for (User user : users) {
if (processUser(user)) {
processedCount++;
}
}
return CompletableFuture.completedFuture(processedCount);
}
性能考量與最佳實踐
合理使用異步:不是所有數據庫操作都適合異步,簡單查詢同步執行可能更高效
控制并發量:避免過多并發數據庫連接導致系統資源耗盡
批量操作優化:考慮使用MyBatis-Plus的批量操作方法
結果處理:使用CompletableFuture可以方便地處理異步結果
監控:監控異步任務的執行情況和線程池狀態
總結
MyBatis-Plus的LambdaQueryWrapper與Spring Boot的@Async注解的結合,為Java后端開發提供了強大的工具組合。LambdaQueryWrapper提供了類型安全、優雅的查詢構建方式,而@Async則讓異步編程變得簡單。合理使用這兩者可以顯著提高應用程序的響應速度和處理能力,特別是在處理復雜查詢、批量操作和后臺任務時。
在實際項目中,開發者應根據具體場景選擇合適的技術組合,并注意線程池配置、異常處理和事務管理等關鍵點,以確保系統的穩定性和可靠性。
審核編輯 黃宇
-
JAVA
+關注
關注
20文章
3003瀏覽量
116651 -
代碼
+關注
關注
30文章
4973瀏覽量
74184
發布評論請先 登錄
當匯川PLC遇上施耐德變頻器,疆鴻智能EtherNet/IP轉Modbus TCP給它倆當翻譯
【「Linux 設備驅動開發(第 2 版)」閱讀體驗】充分發揮硬件潛力
當頂流Clawdbot遇上AIMO,個人AI Agent迎來“實體化”革命!
當EtherCAT遇上PROFINET:我們的“協議小翻譯”讓礦井安全手拉手
如何在香橙派5 Plus上移植deepin 25操作系統
ulog輸出異常-中斷與線程打印沖突怎么解決?
電磁遇上熱與應力-CST多物理場仿真解決復雜工程挑戰
當ASM焊線機遇上協議翻譯官:CC\\-Link IE轉Modbus RTU的節能數據之旅
當機器人遇上“語言障礙”:CCLINKIE轉Profinet的“破冰外掛”來啦\\!
CANoe產品體系19版本新功能(下)
跨異步時鐘域處理方法大全
LambdaQueryWrapper遇上@Async
評論