一、官方介紹
支援的資料庫
- mysql,oracle,db2,h2,hsql,sqlite,postgresql,sqlserver,Phoenix,Gauss ,clickhouse,Sybase,OceanBase,Firebird,cubrid,goldilocks,csiidb,informix,TDengine,redshift
- 達夢資料庫,虛谷資料庫,人大金倉資料庫,南大通用(華庫)資料庫,南大通用資料庫,神通資料庫,瀚高資料庫,優炫資料庫
屬性介紹
屬性名 | 類型 | 預設值 | 描述 |
overflow | boolean | false | 溢出總頁數後是否進行處理(預設不處理,參見 插件#continuePage 方法) |
maxLimit | Long | 單頁分頁條數限制(預設無限制,參見 插件#handlerLimit 方法) | |
dbType | DbType | 資料庫類型(根據類型擷取應使用的分頁方言,參見 插件#findIDialect 方法) | |
dialect | IDialect | 方言實作類(參見 插件#findIDialect 方法) |
建議單一資料庫類型的均設定 dbType
自定義的 mapper#method 使用分頁
IPage<UserVo> selectPageVo(IPage<?> page, Integer state);
// or (class MyPage extends Ipage<UserVo>{ private Integer state; })
MyPage selectPageVo(MyPage page);
// or
List<UserVo> selectPageVo(IPage<UserVo> page, Integer state);
<select id="selectPageVo" resultType="xxx.xxx.xxx.UserVo">
SELECT id,name FROM user WHERE state=#{state}
</select>
如果傳回類型是 IPage 則入參的 IPage 不能為null,因為 傳回的IPage == 入參的IPage; 如果想臨時不分頁,可以在初始化IPage時size參數傳 <0 的值;
如果傳回類型是 List 則入參的 IPage 可以為 null(為 null 則不分頁),但需要你手動 入參的IPage.setRecords(傳回的 List);
如果 xml 需要從 page 裡取值,需要 page.屬性 擷取
其他:
生成 countSql 會在 left join 的表不參與 where 條件的情況下,把 left join 優化掉
是以建議任何帶有 left join 的sql,都寫标準sql,即給于表一個别名,字段也要 别名.字段
注意!
- 多個插件使用的情況,請将分頁插件放到 插件執行鍊 最後面。如在租戶插件前面,會出現 COUNT 執行 SQL 不準确問題。
Page
該類繼承了 IPage 類,實作了 簡單分頁模型 如果你要實作自己的分頁模型可以繼承 Page 類或者實作 IPage 類
屬性名 | 類型 | 預設值 | 描述 |
records | List | emptyList | 查詢資料清單 |
total | Long | 查詢清單總記錄數 | |
size | Long | 10 | 每頁顯示條數,預設 10 |
current | Long | 1 | 目前頁 |
orders | List | emptyList | 排序字段資訊,允許前端傳入的時候,注意 SQL 注入問題,可以使用 SqlInjectionUtils.check(...) 檢查文本 |
optimizeCountSql | boolean | true | 自動優化 COUNT SQL 如果遇到 jSqlParser 無法解析情況,設定該參數為 false |
optimizeJoinOfCountSql | boolean | true | 自動優化 COUNT SQL 是否把 join 查詢部分移除 |
searchCount | boolean | true | 是否進行 count 查詢,如果指向查詢到清單不要查詢總記錄數,設定該參數為 false |
maxLimit | Long | 單頁分頁條數限制 | |
countId | String | xml 自定義 count 查詢的 statementId |
二、簡單使用
配置分頁插件
@Configuration
public class MybatisConfig {
@Bean
public PaginationInterceptor paginationInterceptor() {
return new PaginationInterceptor();
}
}
在高版本的SpringBoot中, 會提示這種寫法已過時, 是以采用另一種寫法 MybatisPlusInterceptor , 如下:
@Bean
public MybatisPlusInterceptor mybatisPlusInterceptor() {
MybatisPlusInterceptor interceptor = new MybatisPlusInterceptor();
interceptor.addInnerInterceptor(new PaginationInnerInterceptor(DbType.H2));
return interceptor;
}
MybatisPlusInterceptor
目前MybatisPlusInterceptor作為核心插件,代理了 Executor#query 和 Executor#update 和 StatementHandler#prepare 方法
屬性
private List<InnerInterceptor> interceptors = new ArrayList<>();
InnerInterceptor
我們提供的插件都将基于此接口來實作功能 目前已有的功能: 自動分頁: PaginationInnerInterceptor 多租戶: TenantLineInnerInterceptor 動态表名: DynamicTableNameInnerInterceptor 樂觀鎖: OptimisticLockerInnerInterceptor sql性能規範: IllegalSQLInnerInterceptor 防止全表更新與删除: BlockAttackInnerInterceptor 注意: 使用多個功能需要注意順序關系,建議使用如下順序 多租戶 動态表名 分頁,樂觀鎖 sql性能規範,防止全表更新與删除 總結: 對sql進行單次改造的優先放入,不對sql進行改造的最後放入
編寫Mapper及其對應的mapper.xml檔案
@Mapper
public interface UserMapper extends BaseMapper<User> {
List<User> findPageUsers(Page<User> page);
}
<select id="findPageUsers" resultType="com.test.entity.User">
select * from `user`
</select>
編寫測試類
簡單的分頁查詢
@SpringBootTest
class MybatisPlusStudyApplicationTests {
@Resource
UserMapper userMapper;
@Test
void contextLoads() {
Page<User> page = new Page<>(1, 3);
List<User> pageUsers = userMapper.findPageUsers(page);
page.setRecords(pageUsers);
System.out.println(page);
}
}
運作結果:
JsqlParserCountOptimize sql=select * from `user`
==> Preparing: SELECT COUNT(1) FROM `user`
==> Parameters:
<== Columns: COUNT(1)
<== Row: 9
==> Preparing: select * from `user` LIMIT ?
==> Parameters: 3(Long)
<== Columns: id, name, age
<== Row: 41ee81ff-fc0c-8bfa-77d8-44c190cc7466, aaa, 12
<== Row: 3b25fb904548c28b7ac6882d86c7ae5f, bbb, 12
<== Row: 8b0397fcdfebe37d1d26175c17ed3725, ccc, 12
<== Total: 3
帶查詢條件的分頁查詢
此方法是使用PaginationInterceptor 作為分頁插件.
@Test
void contextLoads() {
Page<User> page = new Page<>(1, 2);
QueryWrapper<User> queryWrapper = new QueryWrapper<>();
queryWrapper.eq("name", "bbb");
Page<User> page1 = userMapper.selectPage(page, queryWrapper);
page.setRecords(page1.getRecords()).getRecords().forEach(System.out::println);
}
運作結果:
JsqlParserCountOptimize sql=SELECT id,name,age FROM user
WHERE (name = ?)
==> Preparing: SELECT COUNT(1) FROM user WHERE (name = ?)
==> Parameters: wdh(String)
<== Columns: COUNT(1)
<== Row: 5
==> Preparing: SELECT id,name,age FROM user WHERE (name = ?) LIMIT ?
==> Parameters: wdh(String), 2(Long)
<== Columns: id, name, age
<== Row: b78cbc0d-82f8-2f57-90c5-5f0a308ee4a5, bbb, 12
<== Row: 4febef0e-409d-a540-7b42-b3815c5a1956, ccc, 12
<== Total: 2
Closing non transactional SqlSession [org.apache.ibatis.session.defaults.DefaultSqlSession@6a0f2853]
User(id=3b25fb904548c28b7ac6882d86c7ae5f, name=bbb, age=12)
User(id=8b0397fcdfebe37d1d26175c17ed3725, name=ccc, age=12)
Page
簡單分頁模型, 有如下幾個主要屬性
/**
* 查詢資料清單
*/
protected List<T> records = Collections.emptyList();
/**
* 總數
*/
protected long total = 0;
/**
* 每頁顯示條數,預設 10
*/
protected long size = 10;
/**
* 目前頁
*/
protected long current = 1;
注意事項
在編寫mapper.xml中的SQL語句的時候, 語句末尾不能使用 ; 結尾, 原因是在做分頁的時候會在編寫的SQL語句後面拼接上limit語句, 導緻出現SQL文法錯誤(SQLSyntaxErrorException). 如下所示:
JsqlParserCountOptimize sql=select *
from `user`;
==> Preparing: SELECT COUNT(1) FROM `user`
==> Parameters:
<== Columns: COUNT(1)
<== Row: 9
==> Preparing: select * from `user`; LIMIT ?
==> Parameters: 3(Long)
org.springframework.jdbc.BadSqlGrammarException:
### Error querying database. Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 3' at line 1
### The error may exist in org/wxmx/mybatis_plus_study/mapper/UserMapper.xml
### The error may involve defaultParameterMap
### The error occurred while setting parameters
### SQL: select * from `user`; LIMIT ?
### Cause: java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LIMIT 3' at line 1
; bad SQL grammar []; nested exception is java.sql.SQLSyntaxErrorException: You have an error in your SQL syntax;