Java使用MyBatis框架分頁(yè)的5種方式
本文為大家分享了Java使用MyBatis框架分頁(yè)的五種方式,供大家參考,具體內(nèi)容如下
初始準(zhǔn)備
1.創(chuàng)建分頁(yè)對(duì)象類(lèi),方便模塊間傳值
//PageInfo.java
import lombok.Data;
@Data
public class PageInfo {
private int pageNo;
private int pageSize;
}
2.定義DAO層接口
import org.apache.ibatis.session.RowBounds;
import org.springframework.stereotype.Repository;
import java.util.List;
@Repository
public interface UserMapper {
User selectByUser(User user);
List<User> selectAll();
List<User> selectByPageInfo(PageInfo info);
List<User> selectByInterceptor(PageInfo info);
List<User> selectByRowBounds(RowBounds rowBounds);
}
3.mapper中定義結(jié)果集合BaseResult
<resultMap id="BaseResult" type="cn.edu.yau.pojo.User"> <id property="id" column="id" jdbcType="INTEGER"></id> <result property="username" column="username" jdbcType="VARCHAR"></result> <result property="password" column="password" jdbcType="VARCHAR"></result> </resultMap>
一、原始切分:最原始方法,不建議使用
1.mapper代碼:查詢(xún)所有數(shù)據(jù)
<select id="selectAll" resultMap="BaseResult"> select * from tb_user </select>
2.業(yè)務(wù)層代碼:利用List的subList()方法對(duì)數(shù)據(jù)進(jìn)行切片
public List<User> findByAll(PageInfo info) {
List<User> users = userMapper.selectAll();
return users.subList(info.getPageNo(), info.getPageSize());
}
3.控制層代碼
@RequestMapping(value = "/userlist_1", method = RequestMethod.GET)
@ResponseBody
public Result findUserBySubList(PageInfo info) {
List<User> users = userService.findByAll(info);
if(users.size() == 0) {
return ResultGenerator.genFailResult("未查找到用戶(hù)");
}
return ResultGenerator.genSuccessResult(users);
}
二、LIMIT關(guān)鍵字
1.mapper代碼:利用limit關(guān)鍵字實(shí)現(xiàn)分頁(yè)
<select id="selectByPageInfo" resultMap="BaseResult">
select * from tb_user limit #{pageNo}, #{pageSize}
</select>
2.業(yè)務(wù)層直接調(diào)用
public List<User> findByPageInfo(PageInfo info) {
return userMapper.selectByPageInfo(info);
}
3.控制層直接調(diào)用
三、RowBounds實(shí)現(xiàn)分頁(yè)
1.在DAO層定義好所要傳輸?shù)姆猪?yè)信息,類(lèi)型為RowBounds
2.mapper層:查詢(xún)所有數(shù)據(jù)
3.業(yè)務(wù)層:將PageInfo信息封裝成RowBounds,調(diào)用DAO層方法
public List<User> findByRowBounds(PageInfo info) {
return userMapper.selectByRowBounds(new RowBounds(info.getPageNo(), info.getPageSize()));
}
4.控制層直接調(diào)用
四、MyBatis的Interceptor實(shí)現(xiàn):實(shí)現(xiàn)復(fù)雜,需要明白MyBatis的實(shí)現(xiàn)
1.創(chuàng)建Interceptor
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.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;
import java.sql.Connection;
import java.util.Properties;
/**
* 利用MyBatis攔截器進(jìn)行分頁(yè)
*
* @Intercepts 說(shuō)明是一個(gè)攔截器
* @Signature 攔截器的簽名
* type 攔截的類(lèi)型 四大對(duì)象之一( Executor,ResultSetHandler,ParameterHandler,StatementHandler)
* method 攔截的方法
* args 參數(shù),高版本需要加個(gè)Integer.class參數(shù),不然會(huì)報(bào)錯(cuò)
*
*/
@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})
public class DefinedPageInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
//獲取StatementHandler,默認(rèn)的是RoutingStatementHandler
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
//獲取StatementHandler的包裝類(lèi)
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
//分隔代理對(duì)象
while (metaObject.hasGetter("h")) {
Object obj = metaObject.getValue("h");
metaObject = SystemMetaObject.forObject(obj);
}
while (metaObject.hasGetter("target")) {
Object obj = metaObject.getValue("target");
metaObject = SystemMetaObject.forObject(obj);
}
//獲取查看接口映射的相關(guān)信息
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
String mapId = mappedStatement.getId();
//攔截以ByInterceptor結(jié)尾的請(qǐng)求,統(tǒng)一實(shí)現(xiàn)分頁(yè)
if (mapId.matches(".+ByInterceptor$")) {
System.out.println("LOG:已觸發(fā)分頁(yè)攔截器");
//獲取進(jìn)行數(shù)據(jù)庫(kù)操作時(shí)管理參數(shù)的Handler
ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
//獲取請(qǐng)求時(shí)的參數(shù)
PageInfo info = (PageInfo) parameterHandler.getParameterObject();
//獲取原始SQL語(yǔ)句
String originalSql = (String) metaObject.getValue("delegate.boundSql.sql");
//構(gòu)建分頁(yè)功能的SQL語(yǔ)句
String sql = originalSql.trim() + " limit " + info.getPageNo() + ", " + info.getPageSize();
metaObject.setValue("delegate.boundSql.sql", sql);
}
//調(diào)用原對(duì)象方法,進(jìn)入責(zé)任鏈下一級(jí)
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
//生成Object對(duì)象的動(dòng)態(tài)代理對(duì)象
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
//如果分頁(yè)每頁(yè)數(shù)量是統(tǒng)一的,可以在這里進(jìn)行統(tǒng)一配置,也就無(wú)需再傳入PageInfo信息了
}
}
2.將Interceptor添加至MyBatisConfig中,這里采用JavaConfig的方式
@Bean
public SqlSessionFactoryBean sqlSession() {
SqlSessionFactoryBean sqlSession = new SqlSessionFactoryBean();
sqlSession.setDataSource(dataSource());
try {
Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml");
sqlSession.setMapperLocations(resources);
//配置自定義的Interceptro作為MyBatis的Interceptor,完成分頁(yè)操作
DefinedPageInterceptor definedPageInterceptor = new DefinedPageInterceptor();
sqlSession.setPlugins(new Interceptor[]{definedPageInterceptor});
return sqlSession;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
3.DAO層接口方法名需要和代碼中自定義的".+ByInterceptor$"正則表達(dá)式相匹配,mapper的書(shū)寫(xiě)依然是查詢(xún)所有數(shù)據(jù)
<select id="selectByInterceptor" resultMap="BaseResult"> select * from tb_user </select>
4.業(yè)務(wù)層直接調(diào)用
5.控制層直接調(diào)用
五、開(kāi)源項(xiàng)目PageHelper實(shí)現(xiàn):本質(zhì)還是自己封裝了個(gè)Interceptor
1.引入PageHelper的jar包
<dependency> <groupId>com.github.pagehelper</groupId> <artifactId>pagehelper</artifactId> <version>5.1.10</version> </dependency>
2.配置PageInterceptor
public PageInterceptor initPageInterceptor(){
PageInterceptor pageInterceptor = new PageInterceptor();
Properties properties = new Properties();
//設(shè)置數(shù)據(jù)庫(kù)類(lèi)型
properties.setProperty("helperDialect", "mysql");
//該參數(shù)默認(rèn)為false
//設(shè)置為true時(shí),會(huì)將RowBounds第一個(gè)參數(shù)offset當(dāng)成pageNum頁(yè)碼使用
//和startPage中的pageNum效果一樣
properties.setProperty("offsetAsPageNum", "true");
//該參數(shù)默認(rèn)為false
//設(shè)置為true時(shí),使用RowBounds分頁(yè)會(huì)進(jìn)行count查詢(xún)
properties.setProperty("rowBoundsWithCount", "true");
pageInterceptor.setProperties(properties);
return pageInterceptor;
}
@Bean
public SqlSessionFactoryBean sqlSession() {
SqlSessionFactoryBean sqlSession = new SqlSessionFactoryBean();
sqlSession.setDataSource(dataSource());
try {
Resource[] resources = new PathMatchingResourcePatternResolver().getResources("classpath:mapper/*.xml");
sqlSession.setMapperLocations(resources);
//配置PageHelper作為MyBatis的Interceptor,完成分頁(yè)操作
PageInterceptor pageInterceptor = this.initPageInterceptor();
//配置自定義的Interceptro作為MyBatis的Interceptor,完成分頁(yè)操作
DefinedPageInterceptor definedPageInterceptor = new DefinedPageInterceptor();
sqlSession.setPlugins(new Interceptor[]{pageInterceptor, definedPageInterceptor});
return sqlSession;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
3.mapper依然是查詢(xún)所有數(shù)據(jù)
4.為DAO層再封裝一次方法
@Repository
public class PageHelperHandler {
@Autowired
private SqlSessionFactory sqlSessionFactory;
public List<User> findByPageHelper(PageInfo info) {
SqlSession session = sqlSessionFactory.openSession();
PageHelper.startPage(info.getPageNo(), info.getPageSize());
//寫(xiě)到要使用到的類(lèi)名和方法名
List<User> users = session.selectList("cn.edu.yau.mapper.UserMapper.selectAll");
return users;
}
}
6.業(yè)務(wù)層直接調(diào)用Handler
7.控制層直接調(diào)用
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
springmvc用于方法鑒權(quán)的注解攔截器的解決方案代碼
這篇文章主要介紹了springmvc用于方法鑒權(quán)的注解攔截器的解決方案代碼,具有一定借鑒價(jià)值,需要的朋友可以參考下。2017-12-12
mybatisplus實(shí)現(xiàn)自動(dòng)填充時(shí)間的項(xiàng)目實(shí)踐
在數(shù)據(jù)庫(kù)操作中,頻繁設(shè)置創(chuàng)建時(shí)間和更新時(shí)間字段非常繁瑣,通過(guò)使用MyBatis-Plus的自動(dòng)填充功能,可以簡(jiǎn)化操作,本文就來(lái)詳細(xì)的介紹一下,感興趣的可以了解一下2024-10-10
Java基礎(chǔ)之方法重寫(xiě)和多態(tài)示例
這篇文章主要介紹了Java基礎(chǔ)之方法重寫(xiě)和多態(tài),結(jié)合實(shí)例形式分析了java方法重寫(xiě)和多態(tài)的相關(guān)原理與使用技巧,需要的朋友可以參考下2019-08-08
使用AOP+反射實(shí)現(xiàn)自定義Mybatis多表關(guān)聯(lián)查詢(xún)
這篇文章主要介紹了使用AOP+反射實(shí)現(xiàn)自定義Mybatis多表關(guān)聯(lián),目前的需求是增強(qiáng)現(xiàn)有的查詢(xún),使用簡(jiǎn)單的注解即可實(shí)現(xiàn)多表關(guān)聯(lián),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下2022-05-05
Spring Boot集成SpringFox 3.0與Pageable參數(shù)處理方法
這篇文章主要介紹了Spring Boot集成SpringFox 3.0與Pageable參數(shù)處理,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2023-10-10
java實(shí)現(xiàn)dijkstra最短路徑尋路算法
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)dijkstra最短路徑尋路算法,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01
java正則表達(dá)式的應(yīng)用 java讀取文件并獲取電話(huà)號(hào)碼
這篇文章主要介紹了java正則表達(dá)式的應(yīng)用,應(yīng)用的內(nèi)容是java讀取文件并獲取電話(huà)號(hào)碼,感興趣的小伙伴們可以參考一下2015-11-11

