更新時(shí)間:2021-03-03 15:12:35 來(lái)源:動(dòng)力節(jié)點(diǎn) 瀏覽2459次
MyBatis 是一款優(yōu)秀的持久層框架,它支持定制化 SQL、存儲(chǔ)過(guò)程以及高級(jí)映射。MyBatis 避免了幾乎所有的 JDBC 代碼和手動(dòng)設(shè)置參數(shù)以及獲取結(jié)果集。MyBatis 可以使用簡(jiǎn)單的 XML 或注解來(lái)配置和映射原生信息,將接口和 Java 的 POJOs(Plain Old Java Objects,普通的 Java對(duì)象)映射成數(shù)據(jù)庫(kù)中的記錄。
今天我們就來(lái)學(xué)學(xué)mybatis框架分頁(yè)實(shí)現(xiàn),有幾種方式,最簡(jiǎn)單的就是利用原生的sql關(guān)鍵字limit來(lái)實(shí)現(xiàn),還有一種就是利用interceptor來(lái)拼接sql,實(shí)現(xiàn)和limit一樣的功能,再一個(gè)就是利用PageHelper來(lái)實(shí)現(xiàn)。這里講解這三種常見(jiàn)的實(shí)現(xiàn)方式:

無(wú)論哪種實(shí)現(xiàn)方式,我們返回的結(jié)果,不能再使用List了,需要一個(gè)自定義對(duì)象Pager。
package com.xxx.mybatis.bean;
import java.util.List;
public class Pager<T> {
private int page;//分頁(yè)起始頁(yè)
private int size;//每頁(yè)記錄數(shù)
private List<T> rows;//返回的記錄集合
private long total;//總記錄條數(shù)
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getSize() {
return size;
}
public void setSize(int size) {
this.size = size;
}
public List<T> getRows() {
return rows;
}
public void setRows(List<T> rows) {
this.rows = rows;
}
public long getTotal() {
return total;
}
public void setTotal(long total) {
this.total = total;
}
}
limit關(guān)鍵字實(shí)現(xiàn):
UserDao.java增加兩個(gè)方法
public List<User> findByPager(Map<String, Object> params);
public long count();
UserMapper.xml中增加兩個(gè)查詢(xún)
<select id="findByPager" resultType="com.xxx.mybatis.domain.User">
select * from xx_user limit #{page},#{size}
</select>
<select id="count" resultType="long">
select count(1) from xx_user
</select>
UserService.java中增加分頁(yè)方法
public Pager<User> findByPager(int page,int size){
Map<String, Object> params = new HashMap<String, Object>();
params.put("page", (page-1)*size);
params.put("size", size);
Pager<User> pager = new Pager<User>();
List<User> list = userDao.findByPager(params);
pager.setRows(list);
pager.setTotal(userDao.count());
return pager;
}
這是最直觀的實(shí)現(xiàn)方式,也是最簡(jiǎn)單的,不用任何插件或者工具就能夠很方便的實(shí)現(xiàn)的方法。
interceptor plugin實(shí)現(xiàn):
需要定義一個(gè)類(lèi)實(shí)現(xiàn)Interceptor接口
MyPageInterceptor.java
package com.xxx.mybatis.bean;
import java.sql.Connection;
import java.util.Map;
import java.util.Properties;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class,Integer.class})})
public class MyPageInterceptor implements Interceptor {
private int page;
private int size;
@SuppressWarnings("unused")
private String dbType;
@SuppressWarnings("unchecked")
@Override
public Object intercept(Invocation invocation) throws Throwable {
System.out.println("plugin is running...");
StatementHandler statementHandler = (StatementHandler)invocation.getTarget();
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
while(metaObject.hasGetter("h")){
Object object = metaObject.getValue("h");
metaObject = SystemMetaObject.forObject(object);
}
while(metaObject.hasGetter("target")){
Object object = metaObject.getValue("target");
metaObject = SystemMetaObject.forObject(object);
}
MappedStatement mappedStatement = (MappedStatement)metaObject.getValue("delegate.mappedStatement");
String mapId = mappedStatement.getId();
if(mapId.matches(".+ByPager$")){
ParameterHandler parameterHandler = (ParameterHandler)metaObject.getValue("delegate.parameterHandler");
Map<String, Object> params = (Map<String, Object>)parameterHandler.getParameterObject();
page = (int)params.get("page");
size = (int)params.get("size");
String sql = (String) metaObject.getValue("delegate.boundSql.sql");
sql += " limit "+(page-1)*size +","+size;
metaObject.setValue("delegate.boundSql.sql", sql);
}
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
String limit = properties.getProperty("limit","10");
this.page = Integer.parseInt(limit);
this.dbType = properties.getProperty("dbType", "mysql");
}
}
我們之前在service的findByPager方法里面,為了給limit傳入兩個(gè)參數(shù),其中page做了計(jì)算,這里使用攔截器的方式就無(wú)需計(jì)算了:

public Pager<User> findByPager(int page,int size){
Map<String, Object> params = new HashMap<String, Object>();
params.put("page", page);
params.put("size", size);
Pager<User> pager = new Pager<User>();
List<User> list = userDao.findByPager(params);
pager.setRows(list);
pager.setTotal(userDao.count());
return pager;
}
spring配置中,增加plugin設(shè)置:

到這里,你也許也猜到了MyPageInterceptor實(shí)際上是以一種攔截器的方式在程序執(zhí)行findByPager方法的時(shí)候,對(duì)語(yǔ)句會(huì)增加limit page,size的拼接,還是和第一種原生實(shí)現(xiàn)思路一樣,所以這里需要對(duì)UserMapper.xml配置文件中的findByPager這個(gè)查詢(xún)對(duì)應(yīng)的語(yǔ)句中的limit#{page},#{size}這部分去掉,變?yōu)槿缦碌臉幼樱?/p>

至此,通過(guò)攔截器插件的方式也實(shí)現(xiàn)了分頁(yè)功能了。
PageHelper實(shí)現(xiàn):
這種方式實(shí)現(xiàn)需要我們引入maven依賴(lài)。
<dependency>
<groupId>com.github.pagehelper</groupId>
<artifactId>pagehelper</artifactId>
<version>4.2.1</version>
</dependency>
spring.xml配置文件做一下修改:
<bean id="pageInterceptor" class="com.github.pagehelper.PageHelper">
<property name="properties">
<props>
<prop key="helperDialect">mysql</prop>
<prop key="reasonable">true</prop>
<prop key="supportMethodsArguments">true</prop>
<prop key="params">count=countSql</prop>
</props>
</property>
</bean>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="mapperLocations" value="classpath:com/xxx/mybatis/dao/*Mapper.xml"/>
<property name="plugins" ref="pageInterceptor"></property>
</bean>
service層的方法,做一些修改:
public Pager<User> findByPager(int page,int size){
Pager<User> pager = new Pager<User>();
Page<User> res = PageHelper.startPage(page,size);
userDao.findAll();
pager.setRows(res.getResult());
pager.setTotal(res.getTotal());
return pager;
}
至此,PageHelper工具方法實(shí)現(xiàn)分頁(yè)也實(shí)現(xiàn)了。其實(shí)PageHelper方法也是第二種使用Interceptor攔截器方式的一種三方實(shí)現(xiàn),它內(nèi)部幫助我們實(shí)現(xiàn)了Interceptor的功能。所以我們不用自定義MyPageInterceptor這個(gè)類(lèi)了。實(shí)際上也是在運(yùn)行查詢(xún)方法的時(shí)候,進(jìn)行攔截,然后設(shè)置分頁(yè)參數(shù)。所以PageHelper.startPage(page,size)這一句需要顯示調(diào)用,然后再執(zhí)行userDao.findAll(),在查詢(xún)所有用戶(hù)信息的時(shí)候,會(huì)進(jìn)行一個(gè)分頁(yè)參數(shù)設(shè)置,讓放回的結(jié)果只是分頁(yè)的結(jié)果,而不是全部集合。
零基礎(chǔ)學(xué)習(xí)Mybatis,推薦動(dòng)力節(jié)點(diǎn)Mybatis菜鳥(niǎo)教程,通過(guò)本課程的學(xué)習(xí),可以在最短的時(shí)間內(nèi)學(xué)會(huì)使用持久層框架MyBatis,在該視頻中沒(méi)有廢話,都是干貨,該視頻的講解不是學(xué)術(shù)性研究,項(xiàng)目中用什么,這里就講什么,如果您現(xiàn)在項(xiàng)目中馬上要使用MyBatis框架,那么您只需要學(xué)習(xí)完此教程,就可以順利的使用MyBatis開(kāi)發(fā)了。
以上就是動(dòng)力節(jié)點(diǎn)Java培訓(xùn)機(jī)構(gòu)的小編針對(duì)“Mybatis分頁(yè)視頻教程,超強(qiáng)實(shí)戰(zhàn)”的內(nèi)容進(jìn)行的回答,希望對(duì)大家有所幫助,如有疑問(wèn),請(qǐng)?jiān)诰€咨詢(xún),有專(zhuān)業(yè)老師隨時(shí)為你服務(wù)。
相關(guān)閱讀
Java實(shí)驗(yàn)班
0基礎(chǔ) 0學(xué)費(fèi) 15天面授
Java就業(yè)班
有基礎(chǔ) 直達(dá)就業(yè)
Java夜校直播班
業(yè)余時(shí)間 高薪轉(zhuǎn)行
Java在職加薪班
工作1~3年,加薪神器
Java架構(gòu)師班
工作3~5年,晉升架構(gòu)
提交申請(qǐng)后,顧問(wèn)老師會(huì)電話與您溝通安排學(xué)習(xí)