目錄
Mybatis-Plus實現分頁查詢
技術概述
- 分頁查詢是一項常用的數據庫查詢方法,而使用Mybatis-Plus的分頁插件,可以為你省去更多的時間去編寫復雜的數據庫語句,當然,前提是你還是要懂得一些數據庫查詢語句以及Mybatis-Plus的常用方法。
- 之所以學習該技術,也是因為在軟工實踐中有分頁查詢的需求,為了能夠加快開發效率,所以選擇了使用分頁插件。
- 難點:需要注意Mybatis-Plus不同版本的要求不同;對Mybatis-Plus的相關方法還是需要進行學習。
技術詳述
配置分頁插件
1、spring和mybatis-plus整合
<!-- spring xml 方式 -->
<property name="plugins">
<array>
<bean class="com.baomidou.mybatisplus.extension.plugins.PaginationInterceptor">
<property name="sqlParser" ref="自定義解析類、可以沒有"/>
<property name="dialectClazz" value="自定義方言類、可以沒有"/>
<!-- COUNT SQL 解析.可以沒有 -->
<property name="countSqlParser" ref="countSqlParser"/>
</bean>
</array>
</property>
<bean id="countSqlParser" class="com.baomidou.mybatisplus.extension.plugins.pagination.optimize.JsqlParserCountOptimize">
<!-- 設置為 true 可以優化部分 left join 的sql -->
<property name="optimizeJoin" value="true"/>
</bean>
2、spring boot和mybatis-plus整合
//Spring boot方式
@Configuration
@MapperScan("mapper包名")
public class MybatisPlusConfig {
// 舊版
@Bean
public PaginationInterceptor paginationInterceptor() {
PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
// 設置請求的頁面大於最大頁后操作, true調回到首頁,false 繼續請求 默認false
// paginationInterceptor.setOverflow(false);
// 設置最大單頁限制數量,默認 500 條,-1 不受限制
// paginationInterceptor.setLimit(500);
// 開啟 count 的 join 優化,只針對部分 left join
paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
return paginationInterceptor;
}
// 最新版
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
}
自定義分頁
1、如果你的mapper沒有繼承BaseMapper
UserMapper.java 方法內容
public interface UserMapper {//可以繼承或者不繼承BaseMapper
/**
* <p>
* 查詢 : 根據state狀態查詢用戶列表,分頁顯示
* </p>
*
* @param page 分頁對象,xml中可以從里面進行取值,傳遞參數 Page 即自動分頁,必須放在第一位(你可以繼承Page實現自己的分頁對象)
* @param state 狀態
* @return 分頁對象
*/
IPage<User> selectPageVo(Page<?> page, Integer state);
}
UserMapper.xml 等同於編寫一個普通 list 查詢,mybatis-plus 自動替你分頁
<!-- 下面給出一個簡單的查詢例子<select>標簽就是表示查詢,id屬性是唯一標識符,注意要與你的mapper類的方法名一一對應,resultType就是獲取的數據將被封裝成的類型,關於mybatis的mapper.xml的語法、屬性有很多種,這里就不一一贅述了 -->
<select id="selectPageVo" resultType="com.baomidou.cloud.entity.UserVo">
SELECT id,name FROM user WHERE state=#{state}
</select>
UserServiceImpl.java 調用分頁方法
public IPage<User> selectUserPage(Page<User> page, Integer state) {
// 不進行 count sql 優化,解決 MP 無法自動優化 SQL 問題,這時候你需要自己查詢 count 部分
// page.setOptimizeCountSql(false);
// 當 total 為小於 0 或者設置 setSearchCount(false) 分頁插件不會進行 count 查詢
// 要點!! 分頁返回的對象與傳入的對象是同一個
return userMapper.selectPageVo(page, state);
}
需要注意的是:
如果返回類型是 IPage 則入參的 IPage 不能為null,因為 返回的IPage == 入參的IPage
如果返回類型是 List 則入參的 IPage 可以為 null(為 null 則不分頁),但需要你手動入參的IPage.setRecords(返回的 List);
如果 xml 需要從 page 里取值,需要 page.屬性
獲取。
流程圖:
2、如果你的mapper繼承了BaseMapper
除了上述做法,那你可以使用BaseMapper里聲明了的很強大的CRUD方法,可以看下面的例子。
/**
* 查詢未審核帖子(分頁)
* @param tag 搜索項目
* @param page 頁碼
* @return post 帖子列表
*/
public BackPage<Post> findBackPostList(String tag, int page){
BackPage<Post> postBackPage = new BackPage<>();
// 設置條件構造器
QueryWrapper<Post> wrapper = new QueryWrapper<>();
wrapper.like("post_title", tag);
wrapper.eq("is_check", NOT_CHECKED);
// 構造分頁信息,其中的Page<>(page, PAGE_RECORDS_NUM)的第一個參數是頁數,而第二個參數是每頁的記錄數
Page<Post> postPage = new Page<>(page, PAGE_RECORDS_NUM);
// page(postPage, wrapper)這里的第一個參數就是上面定義了的Page對象,第二個參數就是上面定義的條件構造器對象,通過調用這個方法就可以根據你的分頁信息以及查詢信息獲取分頁數據
IPage<Post> postIPage = page(postPage, wrapper);
// 封裝數據,其中getRecords()是獲取記錄數,getCurrent()獲取當前頁數,getPages()獲取總頁數,getTotal()獲取記錄總數,還要其他更多的方法,大家可以自行查看,在這里就不過多贅述了
postBackPage.setContentList(postIPage.getRecords());
postBackPage.setCurrentPage(postIPage.getCurrent());
postBackPage.setTotalPage(postIPage.getPages());
postBackPage.setTotalNum(postIPage.getTotal());
return postBackPage;
}
其中的BackPage<Post>
以及Post是我為了封裝查詢數據寫的實體類,大家根據自己的需求來選擇就好了。
public class BackPage<T> {
private static final long serialVersionUID=1L;
/**
* 總頁數
*/
private long totalPage;
/**
* 當前頁數
*/
private long currentPage;
/**
* 總數
*/
private long totalNum;
/**
* 內容
*/
private List<T> contentList;
}
流程圖:
技術使用中遇到的問題和解決過程
- 關於mybatis-plus版本的問題,3.x版本要使用分頁,必須配置插件,否則會沒有效果,不像2.x沒配插件就是內存分頁(在分頁的時候,是把所有的數據都查詢出來,然后通過RowBounds進行在內存分頁)。
/**
* <p>
* 根據 entity 條件,查詢全部記錄(並翻頁)
* </p>
*
* @param rowBounds 分頁查詢條件(可以為 RowBounds.DEFAULT)
* @param wrapper 實體對象封裝操作類(可以為 null)
* @return List<T>
*/
List<T> selectPage(RowBounds rowBounds, Wrapper<T> wrapper);
- 以及上述提到的IPage傳參與返回參數的關系。上去看看
解決過程就是通過網上查詢(博客園、csdn等)獲取相關解決方案。
總結
如果你使用了Mybatis-Plus,並且有需要用到分頁的功能,可以考慮Mybatis-Plus的分頁插件,只需要簡單的配置就可以使用,是個不錯的選擇。