在使用Mybetis分頁插件時測試拋出了此異常,出現此異常的原因大體有兩點:
-
因爲配置出現的原因
- 步驟一、配置maven
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.1.6</version>
</dependency>
- 步驟二、在mybatis-config.xml配置插件
<plugin interceptor="com.github.pagehelper.PageHelper">
<property name="dialect" value="sqlserver2012" />
<!-- 該參數默認爲false -->
<!-- 設置爲true時,會將RowBounds第一個參數offset當成pageNum頁碼使用 -->
<!-- 和startPage中的pageNum效果一樣 -->
<property name="offsetAsPageNum" value="true"/>
<!-- 該參數默認爲false -->
<!-- 設置爲true時,使用RowBounds分頁會進行count查詢 -->
<property name="rowBoundsWithCount" value="true" />
<!-- 設置爲true時,如果pageSize=0或者RowBounds.limit = 0就會查詢出全部的結果 -->
<!-- (相當於沒有執行分頁查詢,但是返回結果仍然是Page類型) -->
<property name="pageSizeZero" value="true" />
<!-- 3.3.0版本可用 - 分頁參數合理化,默認false禁用 -->
<!-- 啓用合理化時,如果pageNum<1會查詢第一頁,如果pageNum>pages會查詢最後一頁 -->
<!-- 禁用合理化時,如果pageNum<1或pageNum>pages會返回空數據 -->
<property name="reasonable" value="false" />
</plugin>
- 步驟三、update project (maven)
- 步驟四、代碼編寫
然而我檢查了一遍我的代碼發現不是這個原因於是我又檢查了一遍代碼發現了第二個原因
-
在開啓分頁後查詢前插入了別的查詢語句
先看一開始錯誤的代碼
//開啓分頁
PageHelper.startPage(pageNum, pageSize);
TbTypeTemplateExample example=new TbTypeTemplateExample();
//執行存入緩存方法,其中有查詢數據庫的語句
saveToRedis();
Page<TbTypeTemplate> page= (Page<TbTypeTemplate>)typeTemplateMapper.selectByExample(example);
結果在最後一行代碼出現了強轉類型失敗的異常,將查詢語句放到查詢分頁之後就可以正常的執行成功了。
究其原因就在於pageHelper是通過mybatis的pulgin實現了Interceptor接口。
pageHelper會使用ThreadLocal獲取到同一線程中的變量信息,各個線程之間的Threadlocal不會相互干擾,也就是Thread1中的ThreadLocal1之後獲取到Tread1中的變量的信息,不會獲取到Thread2中的信息
所以在多線程環境下,各個Threadlocal之間相互隔離,可以實現,不同thread使用不同的數據源或不同的Thread中執行不同的SQL語句
所以,PageHelper利用這一點通過攔截器獲取到同一線程中的預編譯好的SQL語句之後將SQL語句包裝成具有分頁功能的SQL語句,並將其再次賦值給下一步操作,所以實際執行的SQL語句就是有了分頁功能的SQL語句。