文章背景
最近在測(cè)試業(yè)務(wù)需求時(shí)通讀了研發(fā)指定需求的代碼,發(fā)現(xiàn)研發(fā)大佬們用到了如下的內(nèi)容,有些內(nèi)容我還不是十分的清楚,比如下述真實(shí)代碼;作為后端大佬肯定爐火純青,但是我剛剛看到這段代碼時(shí)確實(shí)有點(diǎn)懵;
快速理解的方式
直接借助joycoder解釋代碼的能力就可以快速理解
于是乎有了下述的探索
但是我為了理解的透徹點(diǎn)還是又去翻找了一些其它資料做一個(gè)記錄吧,后續(xù)萬(wàn)一在遺忘了也方便快速查找
MyBatis-Plus的LambdaQueryWrapper簡(jiǎn)介
LambdaQueryWrapper是MyBatis-Plus提供的一種類(lèi)型安全的查詢(xún)條件構(gòu)造器,它利用Java 8的Lambda表達(dá)式特性,避免了硬編碼字段名,提高了代碼的可讀性和可維護(hù)性。
基本用法示例
LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper?>(); queryWrapper.eq(User::getName, "張三") .ge(User::getAge, 18) .orderByDesc(User::getCreateTime); List userList = userMapper.selectList(queryWrapper);
LambdaQueryWrapper的優(yōu)勢(shì)
類(lèi)型安全:通過(guò)方法引用而非字符串指定字段,編譯器可檢查類(lèi)型
代碼可讀性高:鏈?zhǔn)秸{(diào)用,語(yǔ)義清晰
防止SQL注入:自動(dòng)處理參數(shù)綁定
智能提示:IDE可自動(dòng)補(bǔ)全字段名
Spring Boot的@Async異步處理
@Async是Spring框架提供的注解,用于標(biāo)記方法為異步執(zhí)行。被@Async注解的方法會(huì)在調(diào)用時(shí)立即返回,而實(shí)際執(zhí)行將發(fā)生在單獨(dú)的線程中。
基本配置
首先需要在Spring Boot啟動(dòng)類(lèi)或配置類(lèi)上添加@EnableAsync注解:
@SpringBootApplication @EnableAsync public class MyApplication { public static void main(String[] args) { SpringApplication.run(MyApplication.class, args); } }
簡(jiǎn)單使用示例
@Service public class AsyncService { @Async public void asyncMethod() { // 這個(gè)方法將在單獨(dú)的線程中執(zhí)行 System.out.println("執(zhí)行異步方法: " + Thread.currentThread().getName()); } }
LambdaQueryWrapper與@Async的結(jié)合實(shí)踐
將兩者結(jié)合使用可以實(shí)現(xiàn)高效的異步數(shù)據(jù)庫(kù)操作,特別適合那些不需要立即返回結(jié)果的復(fù)雜查詢(xún)或批量操作。
示例1:異步查詢(xún)用戶列表
@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:異步統(tǒng)計(jì)與保存
@Async public void asyncStatAndSave(Long departmentId) { // 統(tǒng)計(jì)部門(mén)人數(shù) LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper?>(); queryWrapper.eq(User::getDepartmentId, departmentId); long count = userMapper.selectCount(queryWrapper); // 更新統(tǒng)計(jì)結(jié)果 Department department = new Department(); department.setId(departmentId); department.setUserCount(count); departmentMapper.updateById(department); // 記錄統(tǒng)計(jì)日志 StatLog statLog = new StatLog(); statLog.setDepartmentId(departmentId); statLog.setCount(count); statLog.setStatTime(LocalDateTime.now()); statLogMapper.insert(statLog); }
高級(jí)應(yīng)用與優(yōu)化
自定義線程池配置
默認(rèn)情況下,@Async使用SimpleAsyncTaskExecutor,這不是生產(chǎn)環(huán)境的最佳選擇。我們可以自定義線程池:
@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; } }
異常處理
異步方法的異常不會(huì)傳播到調(diào)用線程,需要特別處理:
@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("異步查詢(xún)用戶失敗", e); // 返回空列表或拋出CompletionException return CompletableFuture.completedFuture(Collections.emptyList()); } }
事務(wù)處理
@Async方法的事務(wù)需要特別注意,默認(rèn)情況下異步方法的事務(wù)不會(huì)傳播:
@Async @Transactional(propagation = Propagation.REQUIRES_NEW) public void asyncUpdateWithTransaction(User user) { // 這個(gè)更新操作將在新事務(wù)中執(zhí)行 userMapper.updateById(user); }
實(shí)際應(yīng)用場(chǎng)景
后臺(tái)報(bào)表生成
@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); // 生成報(bào)表文件 generateExcelReport(users, reportPath); // 發(fā)送通知 sendReportReadyNotification(reportPath); }
批量數(shù)據(jù)處理
@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); }
性能考量與最佳實(shí)踐
合理使用異步:不是所有數(shù)據(jù)庫(kù)操作都適合異步,簡(jiǎn)單查詢(xún)同步執(zhí)行可能更高效
控制并發(fā)量:避免過(guò)多并發(fā)數(shù)據(jù)庫(kù)連接導(dǎo)致系統(tǒng)資源耗盡
批量操作優(yōu)化:考慮使用MyBatis-Plus的批量操作方法
結(jié)果處理:使用CompletableFuture可以方便地處理異步結(jié)果
監(jiān)控:監(jiān)控異步任務(wù)的執(zhí)行情況和線程池狀態(tài)
總結(jié)
MyBatis-Plus的LambdaQueryWrapper與Spring Boot的@Async注解的結(jié)合,為Java后端開(kāi)發(fā)提供了強(qiáng)大的工具組合。LambdaQueryWrapper提供了類(lèi)型安全、優(yōu)雅的查詢(xún)構(gòu)建方式,而@Async則讓異步編程變得簡(jiǎn)單。合理使用這兩者可以顯著提高應(yīng)用程序的響應(yīng)速度和處理能力,特別是在處理復(fù)雜查詢(xún)、批量操作和后臺(tái)任務(wù)時(shí)。
在實(shí)際項(xiàng)目中,開(kāi)發(fā)者應(yīng)根據(jù)具體場(chǎng)景選擇合適的技術(shù)組合,并注意線程池配置、異常處理和事務(wù)管理等關(guān)鍵點(diǎn),以確保系統(tǒng)的穩(wěn)定性和可靠性。
審核編輯 黃宇
-
JAVA
+關(guān)注
關(guān)注
20文章
2992瀏覽量
115041 -
代碼
+關(guān)注
關(guān)注
30文章
4923瀏覽量
72368
發(fā)布評(píng)論請(qǐng)先 登錄
當(dāng)EtherCAT遇上PROFINET:我們的“協(xié)議小翻譯”讓礦井安全手拉手

如何在香橙派5 Plus上移植deepin 25操作系統(tǒng)
ulog輸出異常-中斷與線程打印沖突怎么解決?
電磁遇上熱與應(yīng)力-CST多物理場(chǎng)仿真解決復(fù)雜工程挑戰(zhàn)

當(dāng)Modbus遇上Profinet:閥門(mén)通信的“破圈”神助攻
當(dāng)ASM焊線機(jī)遇上協(xié)議翻譯官:CC\\-Link IE轉(zhuǎn)Modbus RTU的節(jié)能數(shù)據(jù)之旅
當(dāng)機(jī)器人遇上“語(yǔ)言障礙”:CCLINKIE轉(zhuǎn)Profinet的“破冰外掛”來(lái)啦\\!
CANoe產(chǎn)品體系19版本新功能(下)

跨異步時(shí)鐘域處理方法大全


評(píng)論