您好,登錄后才能下訂單哦!
這篇文章主要介紹“PageHelper引發的幽靈數據問題怎么解決”的相關知識,小編通過實際案例向大家展示操作過程,操作方法簡單快捷,實用性強,希望這篇“PageHelper引發的幽靈數據問題怎么解決”文章能幫助大家解決問題。
首先我們看了下這對代碼的業務邏輯,非常的簡單,總共沒有幾行代碼,也沒有分頁邏輯,代碼如下:
public List<SdSubscription> findAll() { return sdSubscriptionMapper.selectAll(); }
那么究竟是咋回事呢?講道理不可能出現這種情況的啊,不要慌,我們加點日志,將日志級別調整為DEBUG
,讓日志飛一段時間。
public List<SdSubscription> findAll() { log.info("find the sub start ....."); List<SdSubscription> subs = sdSubscriptionMapper.selectAll(); log.info("find the sub end ....."); return subs; }
果不其然,日志中出現了奇奇怪怪的分頁參數,如下圖所示:
果然是PageHelper
這個開源框架搞的鬼,我想大家都用過吧,分頁非常方便,那么究竟為什么別人都沒問題,單單就我會出現問題呢?
為了回答上面的疑問,我們先看看PageHelper
框架的工作原理吧。
PageHelper
是一個開源的 MyBatis
分頁插件,它可以幫助開發者在查詢數據時,快速的實現分頁功能。
PageHelper
的工作原理可以簡單概括為以下幾個步驟:
在需要進行分頁的查詢方法前,調用 PageHelper
的靜態方法 startPage()
,設置當前頁碼和每頁顯示的記錄數。它會將分頁信息放到線程的ThreadLocal
中,那么在線程的任何地方都可以訪問了。
當查詢方法執行時,PageHelper
會自動攔截查詢語句,如果發現線程的ThreadLocal
中有分頁信息,那么就會在其前后添加分頁語句,例如 MySQL
中的 LIMIT
語句。
查詢結果將被包裝在 Page
對象中返回,該對象包含分頁信息和查詢結果列表。
在查詢方法執行完畢后,會在finally
中清除線程ThreadLocal
中的分頁信息,避免分頁設置對其他查詢方法的影響。
PageHelper
的實現原理主要依賴于攔截器技術和反射機制,通過攔截查詢語句并動態生成分頁語句,實現了簡單、高效、通用的分頁功能。具體源碼在下圖的類中,非常容易看懂。
明白了PageHelper
的工作原理后,反復檢查代碼,都沒有調用過startPage
,debug
查看ThreadLocal
中也沒有分頁信息啊,懵逼中。那我看看別人寫的添加分頁參數的代碼吧,不看不知道,一看嚇一跳。
原來有位“可愛”的同事竟然在查詢后,加了一個分頁,就是把分頁信息放到線程的ThreadLocal
中。
那大家是不是有疑問,丁是丁,矛是矛,你的線程關我何事?這就要說到我們的tomcat了。
其實這就涉及到我們的tomcat
相關知識了,我們一個瀏覽器發一個接口請求,經過我們的tomcat
的,究竟是一個什么樣的流程呢?
客戶端發送HTTP
請求到Tomcat
服務器。
Tomcat
的HTTP
連接器(Connector
)接收到請求,將連接請求交給線程池Executor
處理,解析它,然后將請求轉發給對應的Web應用程序。
Tomcat
的Web應用程序容器(Container
)接收到請求,根據請求的URL找到對應的Servlet
。
關于tomcat中使用線程池提交瀏覽器的連接請求的源碼如下:
從而得知,你的連接請求是從線程池從拿的,而拿到的這個線程恰好是一個“臟線程”,在ThreadLocal
中放了分頁信息,導致你這邊出現問題。
關于“PageHelper引發的幽靈數據問題怎么解決”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識,可以關注億速云行業資訊頻道,小編每天都會為大家更新不同的知識點。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。