mybatis plus很好,但是我被它坑了!
來源:waynblog
作者今天在開發一個後臺傳送訊息的功能時,由於需要給多個使用者傳送訊息,於是使用了 mybatis plus
提供的 saveBatch()
方法,在測試環境測試透過上預釋出後,測試反應傳送訊息介面很慢得等 5、6 秒,於是我就登入線上環境檢視執行日誌,發現是 mybatis plus
提供的 saveBatch()
方法執行很慢導致,於是也就有了本篇文章。
mybatis plus 是一個流行的 ORM 框架,它基於 mybatis,提供了很多便利的功能,比如程式碼生成器、通用 CRUD、分頁外掛、樂觀鎖外掛等。它可以讓我們更方便地運算元據庫,減少重複的程式碼,提高開發效率。
案發現場還原
/**
* 先儲存通知訊息,在批次儲存使用者通知記錄
*/
@Transactional(rollbackFor = Exception.class)
@Override
public boolean saveNotice(Notify notify, String receiveUserIds) {
long begin = System.currentTimeMillis();
notify.setCreateTime(new Date());
notify.setCreateBy(ShiroUtil.getSessionUid());
if (notify.getPublishTime() == null) {
notify.setPublishTime(new Date());
}
boolean insert = save(notify);
List<NotifyRecord> collect = new ArrayList<>();
List<String> receiveUserList = fillNotifyRecordList(notify, receiveUserIds, collect);
notifyRecordService.saveBatch(collect);
long end = System.currentTimeMillis();
System.out.println(end - begin);
...
return insert;
}
/**
* 根據使用者id,組裝使用者通知記錄集合,返回200條記錄
*/
public List<String> fillNotifyRecordList(Notify notify, String receiveUserIds, List<NotifyRecord> collect) {
List<String> noticeRecordList = new ArrayList<>(200);
...
// 組將兩百條使用者通知記錄
return noticeRecordList;
}
如上程式碼,我有一個 saveNotice()
方法用於儲存通知訊息以及使用者通知記錄。執行邏輯如下,
儲存通知訊息 根據使用者 id,組裝使用者通知記錄集合,返回 200 條使用者通知記錄 批次儲存使用者通知記錄集合
前兩步驟耗時都很少,我們直接看第三步操作耗時,結合 sql 執行日誌,如下,
-- slow sql 5542 millis. INSERT INTO oa_notify_record ( notifyId, receiveUserId, receiveUserName, isRead, createTime ) VALUES ( ?, ?, ?, ?, ? )[225,"fcd90fe3990e505d07c90a238f75e9c1","niuwawa",false,"2023-10-30 23:54:04"]
5681
再結合 mybatis free log
外掛列印完整 sql 如下圖,
可以看出,我們批次儲存使用者通知記錄是一條記錄一條進行儲存得,已經可以猜測就是批次插入方法導致得耗時較高。
這裡使用得是 mybatis log free 外掛,它可以自動幫我們在控制檯列印完整得 mybatis sql 語句。有需要可以在 idea 外掛中心搜尋 mybatis log free 下載安裝。
結合 saveBatch()
底層原始碼也能夠看出,mybatis plus
對於批次操作是透過 for
迴圈執行儲存操作得,原始碼如下圖,
到這裡我們也就知道了在測試環境執行較快得原因,因為在測試環境需要批次儲存得使用者通知記錄比較少,只有幾條記錄,所以很快。但是上預釋出後,由於預釋出中需要批次儲存得使用者通知記錄比較多達到了數百條,所以執行較慢,耗時達到了 5、6 秒之久。
解決方法
到這裡,也就是本文得重點所在了,那怎麼解決這個問題嘞?如何既利用 mybatis plus
提供得便攜性,也能夠解決批次操作耗時較高得問題。
其實解決方法很簡單,只需要在 jdbcurl
上新增 rewriteBatchedStatements=true
引數即可解決這個問題。
MySQL 的 JDBC 連線的 url 中要加 rewriteBatchedStatements 引數,並保證 5.1.13 以上版本的驅動,才能實現高效能的批次插入。
MySQL JDBC 驅動在預設情況下會無視 executeBatch()語句,把我們期望批次執行的一組 sql 語句拆散,一條一條地發給 MySQL 資料庫,批次插入實際上是單條插入,直接造成較低的效能。只有把 rewriteBatchedStatements 引數置為 true, 驅動才會幫你批次執行 SQL。另外這個選項對 INSERT/UPDATE/DELETE 都有效。
rewriteBatchedStatements=true 的意思是,當你在 Java 程式中使用批次插入/修改/刪除(batching)時,MySQL JDBC 驅動程式將嘗試重新編寫(rewrite)你的 SQL 語句,以便更有效地執行這些批次插入操作。
OK,在我們給 jdbcurl
上新增了引數後,看看效果,如下圖,
可以看到 jdbcurl
新增了 rewriteBatchedStatements=true
引數後,批次操作的執行耗時已經只有 200 毫秒,自此也就解決了 mybatis plus
提供的 saveBatch()
方法執行耗時較高得問題。
總結
mybatis plus
給開發人員帶來了很多便利,但是其中也有一些坑點,比如上文所提到得批次操作耗時問題,如果不注意的話,就有可能調入坑裡,各位開發同學可以檢查自己或者公司專案中 jdbcurl
是否缺失 rewriteBatchedStatements=true
引數,加以改正,避免重複掉入這個坑裡。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70027826/viewspace-2991983/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- 被mybatis一級快取坑了MyBatis快取
- mybatis plus +springboot +jsp整合踩坑指南MyBatisSpring BootJS
- 小心,別被eureka坑了
- mybatis-plus批次插入你用對了嗎MyBatis
- MyBatis-PlusMyBatis
- 被 Pandas read_csv 坑了
- js到底需不需要寫分號(;), 我被坑了,該長記性了JS
- SpringBoot中使用Mybatis-plus整合PageHelper分頁外掛踩坑Spring BootMyBatis
- Windows,你好呀?我很好,我想你!Windows
- 我被刪庫了
- Spring整合Mybatis plusSpringMyBatis
- MyBatis-Plus 3.0.7.1MyBatis
- MyBatis-Plus 整理MyBatis
- mybatis plus 啟用 mybatis外掛MyBatis
- ThreadLocal原理記錄,別被坑了!!thread
- Windows 95 被做成了一款 app,我們在 MacBook 上體驗了它WindowsAPPMac
- Mybatis的<if>標籤的坑,0會被過濾掉?MyBatis
- MyBatis-Plus學習MyBatis
- mybatis-plus分表MyBatis
- SpringBoot整合Mybatis-PlusSpring BootMyBatis
- fastjson很好,但不適合我ASTJSON
- 快取把我坑慘了..快取
- Centos7,你好嗎?我很好?我想你!CentOS
- 被vector動態擴容給坑了!
- mybatis-plus批量插入saveBatch太慢?我願意稱rewriteBatchedStatements為神MyBatis
- Spring Boot —— 整合 MyBatis-PlusSpring BootMyBatis
- mybatis-plus程式碼生成MyBatis
- Spring Boot 教程 - MyBatis-PlusSpring BootMyBatis
- Mybatis-Plus中的MetaObjectHandlerMyBatisObject
- Mybatis-plus外掛功能MyBatis
- Mybatis-plus的Service介面MyBatis
- SpringBoot | 3.3 整合MyBatis-PlusSpring BootMyBatis
- MyBatis-Plus——實踐篇MyBatis
- Mybatis-Plus增強包MyBatis
- mybatis-plus 使用In查詢MyBatis
- mybatis-plus 使用心得MyBatis
- MyBatis 進階,MyBatis-Plus!(基於 Springboot 演示)MyBatisSpring Boot
- 因為我最近忙、所以我寫了它