Mybatis學習筆記(九)

常見問題與解決方案

簡要描述:總結MyBatis-Plus開發過程中常見的問題、錯誤及其解決方案,幫助開發者快速定位和解決問題。

核心概念

  • 常見錯誤:開發中經常遇到的錯誤類型
  • 性能問題:性能相關問題的排查和解決
  • 配置問題:配置相關的常見問題
  • 最佳實踐:推薦的開發實踐和規范

常見錯誤及解決

簡要描述:MyBatis-Plus開發中常見的錯誤類型及其解決方法。

核心概念

  • SQL錯誤:SQL語法和執行錯誤
  • 映射錯誤:實體類和數據庫字段映射錯誤
  • 配置錯誤:配置文件相關錯誤
  • 注解錯誤:注解使用不當導致的錯誤

SQL相關錯誤

// 1. 字段不存在錯誤
// 錯誤示例:
QueryWrapper<User> wrapper = new QueryWrapper<>();
wrapper.eq("user_name", "張三"); // 數據庫字段是username,不是user_name// 解決方案:
@TableField("username") // 明確指定數據庫字段名
private String userName;// 或者在QueryWrapper中使用正確的字段名
wrapper.eq("username", "張三");// 2. 表名不存在錯誤
// 錯誤示例:
@TableName("sys_user") // 數據庫表名是user,不是sys_user
public class User {// ...
}// 解決方案:
@TableName("user") // 使用正確的表名
public class User {// ...
}// 3. 主鍵策略錯誤
// 錯誤示例:
@TableId(type = IdType.AUTO) // 數據庫主鍵不是自增的
private Long id;// 解決方案:
@TableId(type = IdType.ASSIGN_ID) // 使用雪花算法生成ID
private Long id;// 4. 邏輯刪除字段錯誤
// 錯誤示例:
@TableLogic
private Integer deleted; // 數據庫字段類型是TINYINT,但使用了Integer// 解決方案:
@TableLogic(value = "0", delval = "1")
private Boolean deleted; // 使用Boolean類型

分頁查詢錯誤

// 1. 分頁插件未配置
// 錯誤現象:分頁查詢返回全部數據
// 解決方案:正確配置分頁插件
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}// 2. 分頁參數錯誤
// 錯誤示例:
Page<User> page = new Page<>(0, 10); // 頁碼從0開始// 解決方案:
Page<User> page = new Page<>(1, 10); // 頁碼從1開始// 3. 分頁查詢count錯誤
// 錯誤示例:
Page<User> page = new Page<>(1, 10);
page.setSearchCount(false); // 禁用count查詢但又需要總數// 解決方案:
Page<User> page = new Page<>(1, 10);
page.setSearchCount(true); // 啟用count查詢

事務相關錯誤

// 1. 事務不生效
// 錯誤示例:
@Service
public class UserService {@Transactionalprivate void updateUser(User user) { // private方法,事務不生效// ...}
}// 解決方案:
@Service
public class UserService {@Transactionalpublic void updateUser(User user) { // public方法// ...}
}// 2. 異常被捕獲導致事務不回滾
// 錯誤示例:
@Transactional
public void updateUser(User user) {try {userMapper.updateById(user);int i = 1 / 0; // 拋出異常} catch (Exception e) {log.error("更新用戶失敗", e); // 異常被捕獲,事務不回滾}
}// 解決方案:
@Transactional(rollbackFor = Exception.class)
public void updateUser(User user) {try {userMapper.updateById(user);int i = 1 / 0;} catch (Exception e) {log.error("更新用戶失敗", e);throw e; // 重新拋出異常,觸發事務回滾}
}

性能問題排查

簡要描述:識別和解決MyBatis-Plus應用中的性能問題。

核心概念

  • 慢查詢識別:識別執行緩慢的SQL
  • 內存泄漏:排查內存泄漏問題
  • 連接池問題:數據庫連接池相關問題
  • 緩存問題:緩存使用不當導致的性能問題

慢查詢排查

// 1. 開啟SQL日志
// application.yml
logging:level:com.example.mapper: debugorg.springframework.jdbc: debug// 2. 使用性能分析插件
@Configuration
public class PerformanceConfig {@Bean@Profile("dev")public PerformanceInterceptor performanceInterceptor() {PerformanceInterceptor interceptor = new PerformanceInterceptor();interceptor.setMaxTime(1000); // 超過1秒的SQL會被記錄interceptor.setFormat(true);return interceptor;}
}// 3. 自定義慢查詢監控
@Component
public class SlowQueryMonitor {private static final Logger logger = LoggerFactory.getLogger(SlowQueryMonitor.class);@EventListenerpublic void handleSlowQuery(SlowQueryEvent event) {if (event.getExecutionTime() > 1000) {logger.warn("慢查詢檢測: SQL={}, 執行時間={}ms, 參數={}", event.getSql(), event.getExecutionTime(), event.getParameters());// 可以發送告警通知sendSlowQueryAlert(event);}}private void sendSlowQueryAlert(SlowQueryEvent event) {// 發送告警邏輯}
}

內存泄漏排查

// 1. SqlSession未關閉導致內存泄漏
// 錯誤示例:
public List<User> findUsers() {SqlSession sqlSession = sqlSessionFactory.openSession();List<User> users = sqlSession.selectList("findUsers");// 未關閉SqlSession,導致內存泄漏return users;
}// 解決方案:
public List<User> findUsers() {try (SqlSession sqlSession = sqlSessionFactory.openSession()) {return sqlSession.selectList("findUsers");} // 自動關閉SqlSession
}// 2. 大結果集查詢導致內存溢出
// 錯誤示例:
public List<User> findAllUsers() {return userMapper.selectList(null); // 查詢所有數據,可能導致內存溢出
}// 解決方案:使用分頁查詢
public List<User> findAllUsers() {List<User> allUsers = new ArrayList<>();int pageSize = 1000;int current = 1;while (true) {Page<User> page = new Page<>(current, pageSize);IPage<User> result = userMapper.selectPage(page, null);allUsers.addAll(result.getRecords());if (result.getRecords().size() < pageSize) {break;}current++;}return allUsers;
}

版本升級注意事項

簡要描述:MyBatis-Plus版本升級過程中需要注意的重要事項和兼容性問題。

核心概念

  • 版本兼容性:不同版本間的兼容性問題
  • API變更:API接口的變更和廢棄
  • 配置變更:配置方式的變化
  • 依賴升級:相關依賴的升級要求

3.x升級到4.x注意事項

# 1. 依賴變更
# 舊版本(3.x)
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.3</version>
</dependency># 新版本(4.x)
<dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>4.0.0</version>
</dependency># 2. 配置變更
# 舊配置方式
mybatis-plus:global-config:db-config:id-type: autologic-delete-value: 1logic-not-delete-value: 0# 新配置方式
mybatis-plus:global-config:db-config:id-type: autologic-delete-field: deletedlogic-delete-value: 1logic-not-delete-value: 0

API變更處理

// 1. 分頁插件配置變更
// 舊版本配置
@Configuration
public class MybatisPlusConfig {@Beanpublic PaginationInterceptor paginationInterceptor() {PaginationInterceptor paginationInterceptor = new PaginationInterceptor();paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));return paginationInterceptor;}
}// 新版本配置
@Configuration
public class MybatisPlusConfig {@Beanpublic MybatisPlusInterceptor mybatisPlusInterceptor() {MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.MYSQL));return interceptor;}
}// 2. 性能分析插件變更
// 舊版本
@Bean
public PerformanceInterceptor performanceInterceptor() {return new PerformanceInterceptor();
}// 新版本(已廢棄,建議使用第三方工具)
// 使用p6spy或其他性能監控工具

升級檢查清單

// 升級前檢查清單
public class UpgradeChecklist {/*** 1. 檢查依賴兼容性* - Spring Boot版本兼容性* - JDK版本要求* - 其他依賴庫版本*//*** 2. 檢查配置文件* - application.yml配置項變更* - 插件配置方式變更* - 全局配置項變更*//*** 3. 檢查代碼兼容性* - 廢棄API的替換* - 新增注解的使用* - 方法簽名變更*//*** 4. 測試驗證* - 單元測試通過* - 集成測試通過* - 性能測試對比*/
}

最佳實踐總結

簡要描述:MyBatis-Plus開發的最佳實踐和推薦規范總結。

核心概念

  • 代碼規范:代碼編寫規范
  • 性能優化:性能優化建議
  • 安全實踐:安全相關的最佳實踐
  • 維護性:提高代碼可維護性的建議

開發規范總結

// 1. 實體類設計規范
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("sys_user")
public class User implements Serializable {private static final long serialVersionUID = 1L;@TableId(value = "id", type = IdType.ASSIGN_ID)private Long id;@TableField("username")@NotBlank(message = "用戶名不能為空")private String username;@TableField(value = "create_time", fill = FieldFill.INSERT)private LocalDateTime createTime;@TableLogic(value = "0", delval = "1")private Boolean deleted;@Versionprivate Integer version;
}// 2. Mapper接口規范
@Mapper
public interface UserMapper extends BaseMapper<User> {/*** 自定義查詢方法要有明確的注釋*/List<User> selectByCustomCondition(@Param("condition") UserQueryCondition condition);
}// 3. Service層規范
@Service
@Transactional(rollbackFor = Exception.class)
public class UserServiceImpl extends ServiceImpl<UserMapper, User> implements UserService {@Overridepublic IPage<User> findUserPage(UserPageRequest request) {// 參數校驗validatePageRequest(request);// 構建查詢條件LambdaQueryWrapper<User> wrapper = buildQueryWrapper(request);// 執行分頁查詢Page<User> page = new Page<>(request.getCurrent(), request.getSize());return baseMapper.selectPage(page, wrapper);}private void validatePageRequest(UserPageRequest request) {if (request.getCurrent() < 1) {throw new IllegalArgumentException("頁碼不能小于1");}if (request.getSize() > 100) {throw new IllegalArgumentException("每頁大小不能超過100");}}
}

性能優化總結

// 1. 查詢優化
public class QueryOptimization {// 使用字段選擇,避免查詢不必要的字段public List<UserSimpleVO> findUserSimpleList() {LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.select(User::getId, User::getUsername, User::getEmail);return baseMapper.selectList(wrapper);}// 使用批量操作public boolean batchUpdateStatus(List<Long> userIds, Integer status) {if (CollectionUtils.isEmpty(userIds)) {return true;}List<User> users = userIds.stream().map(id -> {User user = new User();user.setId(id);user.setStatus(status);return user;}).collect(Collectors.toList());return updateBatchById(users);}// 使用緩存@Cacheable(value = "users", key = "#id")public User findById(Long id) {return baseMapper.selectById(id);}
}// 2. 連接池優化
spring:datasource:hikari:maximum-pool-size: 20minimum-idle: 5connection-timeout: 30000idle-timeout: 600000max-lifetime: 1800000

安全實踐總結

// 1. 防止SQL注入
public class SecurityPractice {// 正確:使用參數化查詢public List<User> findUsersByName(String username) {LambdaQueryWrapper<User> wrapper = new LambdaQueryWrapper<>();wrapper.eq(User::getUsername, username);return baseMapper.selectList(wrapper);}// 錯誤:直接拼接SQLpublic List<User> findUsersByNameBad(String username) {QueryWrapper<User> wrapper = new QueryWrapper<>();wrapper.apply("username = '" + username + "'"); // 危險!return baseMapper.selectList(wrapper);}// 2. 敏感信息處理public UserVO getUserInfo(Long userId) {User user = baseMapper.selectById(userId);if (user == null) {return null;}UserVO userVO = new UserVO();BeanUtils.copyProperties(user, userVO);userVO.setPassword(null); // 不返回密碼return userVO;}
}

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

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

相關文章

數據類型 list

一、介紹類似于數組&#xff0c;順序表&#xff0c;deque結構圖特點&#xff1a;元素有序&#xff0c;元素允許重復由于頭尾高效插入刪除&#xff0c;可以模擬棧&#xff0c;隊列二、常見 list 命令1、lpush key elem [elem ...]頭插元素&#xff0c;返回值列表長度2、lrange k…

pyqt5無法顯示opencv繪制文本和掩碼信息

背景&#xff1a;pyqt5無法顯示opencv繪制的標簽和mask&#xff1b;我們在使用YOLO做實例分割做推理時&#xff0c;會使用opencv做后處理結果繪制&#xff08;含標簽繪制和掩碼繪制&#xff09;&#xff1b;結果opencv繪制的解碼卻無法在pyqt的解碼上面顯示。pyqt轉換代碼如下&…

如何生成嚴格遞增的分布式id?

本文字數&#xff1a;2604字預計閱讀時間&#xff1a;15分鐘01引言在現有分布式系統中&#xff0c;面對增長迅速的業務數據&#xff0c;id生成一直是非常重要的一環。而分布式系統的id生成方案需要滿足幾個重要特性&#xff1a;容錯高可用、高性能高并發、全局唯一。02技術背景…

【LeetCode】二叉樹相關算法題

目錄1、二叉樹介紹【1】核心概念【2】關鍵特性2、算法題【1】二叉樹的前序遍歷【2】二叉樹的后序遍歷1、二叉樹介紹 【1】核心概念 結構含義節點結構二叉樹由節點組成&#xff0c; 每個節點包含一個數據元素和最多兩個子節點&#xff1a;左子節點和右子節點根節點樹的頂部節點…

Vulnhub Deathnote靶機復現攻略

一、靶機安裝 下載地址&#xff1a;https://download.vulnhub.com/deathnote/Deathnote.ova 下載好后使用VB打開&#xff0c;配置如下 二、主機發現 使用相同連接方式的kali進行后續操作(172.16.2.7)根據mac地址進行確認。 nmap -sn 172.16.2.1/24 三、端口掃描 端口開放了…

DevEco Studio 6.0.0 元服務頁面跳轉失敗

背景&#xff0c;我使用最新的編輯器DevEco Studio 6.0.0&#xff0c;編寫一個元服務&#xff0c;發現使用跳轉頁面的時候失敗了&#xff01;然后查看官方文檔&#xff0c;兩種方式都測試了&#xff0c;發現都不行。 方法1&#xff1a;Navigation路由跳轉無效&#xff0c;見官方…

docker重啟或系統重啟后harbor自動啟動

docker重啟或系統重啟后harbor自動啟動docker重啟或系統重啟后harbor自動啟動方法 1&#xff1a;在 docker-compose.yml 中配置重啟策略&#xff08;推薦&#xff09;方法 2&#xff1a;創建 Systemd 服務&#xff08;更可靠&#xff09;方法 3&#xff1a;使用 Docker 的 Rest…

OpenZeppelin Contracts 架構分層分析

OpenZeppelin Contracts 是一個面向以太坊&#xff08;及兼容 EVM 的區塊鏈&#xff09;生態系統的??模塊化、安全性優先、標準兼容的智能合約庫??。其內部代碼按照功能職責與抽象層級&#xff0c;可系統性地劃分為多個邏輯層次。理解這些層次及其依賴關系&#xff0c;對于…

Java-JVM的內存模型

一.JVM內存模型JVM內存模型可以從進程生命周期和線程生命周期1.線程生命周期每個線程都會有自己各自一份數據&#xff0c;不會存在線程安全問題1.程序計數器指示當前線程執行的字節碼指令的行號&#xff0c;以便線程執行時可以回到正確的位置2.虛擬機棧線程私有的&#xff0c;與…

Highcharts Dashboards | 打造企業級數據儀表板:從圖表到數據駕駛艙

企業日常決策、產品運營、業務監控&#xff0c;越來越依賴數據驅動。而儀表板&#xff08;Dashboard&#xff09;作為匯總展示多維度信息的“數據駕駛艙”&#xff0c;已成為企業可視化的核心場景之一。如果你正在尋找一款能夠快速、靈活、安全構建儀表板的前端圖表工具&#x…

基于Java的Markdown轉Word工具(標題、段落、表格、Echarts圖等)

項目源于我們開發的一款基于大模型的報告生成工具。由于需要將 Markdown 格式的內容導出為 Word 文檔&#xff0c;而市面上缺乏合適的現成工具&#xff0c;所以決定自己開發一個Markdown轉Word的工具。 &#x1fa77;源碼地址&#xff1a;daydayup-zyn/md2doc-plus &#x1f…

Unity:PlayerPrefs筆記

寫在前面&#xff1a;寫本系列(自用)的目的是回顧已經學過的知識、記錄新學習的知識或是記錄心得理解&#xff0c;方便自己以后快速復習&#xff0c;減少遺忘。一、PlayerPrefs的基本方法1、存儲相關PlayerPrefs的數據存儲類似于鍵值對存儲&#xff0c;一個鍵對應一個值。Unity…

SQL tutorials

SQL Literature SQL運行在資料庫管理系統&#xff08;Database Management System&#xff09;&#xff0c;如MySQL&#xff0c;Postgre SQL&#xff0c;Microsoft SQL Server&#xff0c; Oracle&#xff0c;etc。 SQL練習平臺&#xff1a;https://sqliteviz.com/ EXAMPLE SQL…

MySQL快速恢復數據的N種方案完全教程

目錄 1. 理解MySQL數據恢復的核心邏輯 1.1 數據丟失的常見場景 1.2 MySQL的“救命稻草”:關鍵文件和機制 2. 方案一:利用全量備份+binlog實現點對點恢復 2.1 準備工作 2.2 恢復步驟 2.3 實戰案例 3. 方案二:利用InnoDB的崩潰恢復機制 3.1 崩潰恢復的原理 3.2 恢復步…

雙屏加固筆記本電腦C156-2:堅固與高效的完美融合

在當今數字化時代&#xff0c;筆記本電腦已成為人們工作和生活中不可或缺的工具。然而&#xff0c;對于一些特殊行業和惡劣環境下的應用場景&#xff0c;普通筆記本電腦往往難以滿足需求。此時&#xff0c;具備堅固耐用、高性能等特點的加固筆記本電腦應運而生。魯成偉業的雙屏…

Jenkins 環境部署

下載相關軟件&#xff1a;Jenkins 的安裝和設置 相關工具&#xff1a; Git : Git - Downloads java 17: Java Archive Downloads - Java SE 17.0.12 and earlier python : Download Python | Python.org jenkins、jenkins.war : Jenkins 的安裝和設置 將所有軟件安裝后&am…

如何高效解決 Java 內存泄漏問題方法論

目錄 一、系統化的診斷與優化方法論 二、獲取內存快照:內存泄漏的第一步 (一)自動生成 Heap Dump (二)手動生成 Heap Dump 三、導入分析工具:MAT 和 JProfiler (一)MAT (Memory Analyzer Tool) (二)JProfiler (三)自身企業工具 四、深入分析:逐步排查內存…

HarmonyOS Camera Kit 全解析:從基礎拍攝到跨設備協同的實戰指南

在移動應用開發中&#xff0c;相機功能往往是提升用戶體驗的關鍵模塊&#xff0c;但傳統相機開發面臨權限管理復雜、設備兼容性差、功能實現繁瑣等痛點。HarmonyOS 作為面向全場景的分布式操作系統&#xff0c;其 Camera Kit&#xff08;相機服務&#xff09;通過統一的 API 接…

運用詞向量模型分辨評論

代碼實現&#xff1a;import jieba import pandas as pd hp pd.read_table(優質評價.txt,encodinggbk) cp pd.read_table(差評1.txt,encodinggbk) cp_segments [] contents cp.content.values.tolist() for content in contents:results jieba.lcut(content)if len(result…

基于Apache Flink的實時數據處理架構設計與高可用性實戰經驗分享

基于Apache Flink的實時數據處理架構設計與高可用性實戰經驗分享 一、業務場景描述 在現代電商平臺中&#xff0c;實時用戶行為數據&#xff08;點擊、瀏覽、購物車操作等&#xff09;對業務決策、個性化推薦和風控都至關重要。我們需要搭建一個高吞吐、低延遲且具備高可用性的…