一、什麼是Mybatis Cursor?
Mybatis Cursor是Mybatis提供的一個API,用於處理大量數據時佔用內存過高的問題。它是對JDBC ResultSet游標的封裝,將查詢結果逐個讀取,而不是一次性讀取全部數據,從而避免了OOM問題。
Cursor可以看做是一種惰性載入的機制,只有在使用結果集中的數據時才會被讀取,並且可以自動關閉ResultSet和Statement。
二、Mybatis Cursor的分類及使用方式
1. FORWARD_ONLY Cursor (默認)
當使用FORWARD_ONLY Cursor時,只能沿游標方向向下移動,不能返回。這種Cursor只需要遍歷一次結果集,運行速度最快,但如果需要重複遍歷同一行,則必須重新執行查詢。
// 使用ForwardOnlyCursor try (SqlSession sqlSession = sqlSessionFactory.openSession()) { ResultHandler resultHandler = context -> { while (context.next()) { MyEntity entity = context.getResultObject(); // do something } }; sqlSession.select(SELECT_MY_ENTITY, null, new RowBounds(0, 10), resultHandler, ExecutorType.SIMPLE); }
2. SCROLL_SENSITIVE Cursor
SCROLL_SENSITIVE Cursor支持行級別的修改和動態游標,可以隨意移動游標,但是相對之前的遍歷速度會下降。
// 使用ScrollSensitiveCursor try (SqlSession sqlSession = sqlSessionFactory.openSession()) { ResultHandler resultHandler = context -> { while (context.next()) { MyEntity entity = context.getResultObject(); // do something context.updateRow(); // 可以動態修改行數據 } }; sqlSession.select(SELECT_MY_ENTITY, null, new RowBounds(0, 10), resultHandler, ExecutorType.SCROLL_SENSITIVE); }
3. SCROLL_INSENSITIVE Cursor
SCROLL_INSENSITIVE Cursor支持還原游標位置,因此可以多次遍歷相同的結果集。但是在移動游標時,可能會產生額外的性能開銷。
// 使用ScrollInsensitiveCursor try (SqlSession sqlSession = sqlSessionFactory.openSession()) { ResultHandler resultHandler = context -> { while (context.next()) { MyEntity entity = context.getResultObject(); // do something } }; sqlSession.select(SELECT_MY_ENTITY, null, new RowBounds(0, 10), resultHandler, ExecutorType.SCROLL_INSENSITIVE); }
三、注意事項
使用Cursor需要注意以下問題:
1. ResultSet的關閉
如果使用Cursor,在使用完Cursor後,必須手動調用ResultSet.close(),否則會內存泄漏。
2. 事務
Cursor在使用時需要開啟事務,否則無法正常關閉ResultSet和Statement
3. 內存佔用
雖然Cursor可以減小內存佔用,但是對於大數據量查詢,仍會引起內存佔用過高的問題。需要在程序中進一步優化。
四、總結
Mybatis Cursor是一個非常實用的API,可以有效減小內存佔用問題,處理大量數據時非常實用。使用時需要注意ResultSet的關閉、事務的開啟以及內存佔用問題。
原創文章,作者:LQPX,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/142369.html