Java使用MyBatis框架分頁的5種方式
本文為大家分享了Java使用MyBatis框架分頁的五種方式,供大家參考,具體內容如下
初始準備
1.創(chuàng)建分頁對象類,方便模塊間傳值
//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中定義結果集合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代碼:查詢所有數據
<select id="selectAll" resultMap="BaseResult"> select * from tb_user </select>
2.業(yè)務層代碼:利用List的subList()方法對數據進行切片
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("未查找到用戶");
}
return ResultGenerator.genSuccessResult(users);
}
二、LIMIT關鍵字
1.mapper代碼:利用limit關鍵字實現分頁
<select id="selectByPageInfo" resultMap="BaseResult">
select * from tb_user limit #{pageNo}, #{pageSize}
</select>
2.業(yè)務層直接調用
public List<User> findByPageInfo(PageInfo info) {
return userMapper.selectByPageInfo(info);
}
3.控制層直接調用
三、RowBounds實現分頁
1.在DAO層定義好所要傳輸的分頁信息,類型為RowBounds
2.mapper層:查詢所有數據
3.業(yè)務層:將PageInfo信息封裝成RowBounds,調用DAO層方法
public List<User> findByRowBounds(PageInfo info) {
return userMapper.selectByRowBounds(new RowBounds(info.getPageNo(), info.getPageSize()));
}
4.控制層直接調用
四、MyBatis的Interceptor實現:實現復雜,需要明白MyBatis的實現
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攔截器進行分頁
*
* @Intercepts 說明是一個攔截器
* @Signature 攔截器的簽名
* type 攔截的類型 四大對象之一( Executor,ResultSetHandler,ParameterHandler,StatementHandler)
* method 攔截的方法
* args 參數,高版本需要加個Integer.class參數,不然會報錯
*
*/
@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,默認的是RoutingStatementHandler
StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
//獲取StatementHandler的包裝類
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
//分隔代理對象
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);
}
//獲取查看接口映射的相關信息
MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
String mapId = mappedStatement.getId();
//攔截以ByInterceptor結尾的請求,統(tǒng)一實現分頁
if (mapId.matches(".+ByInterceptor$")) {
System.out.println("LOG:已觸發(fā)分頁攔截器");
//獲取進行數據庫操作時管理參數的Handler
ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
//獲取請求時的參數
PageInfo info = (PageInfo) parameterHandler.getParameterObject();
//獲取原始SQL語句
String originalSql = (String) metaObject.getValue("delegate.boundSql.sql");
//構建分頁功能的SQL語句
String sql = originalSql.trim() + " limit " + info.getPageNo() + ", " + info.getPageSize();
metaObject.setValue("delegate.boundSql.sql", sql);
}
//調用原對象方法,進入責任鏈下一級
return invocation.proceed();
}
@Override
public Object plugin(Object target) {
//生成Object對象的動態(tài)代理對象
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
//如果分頁每頁數量是統(tǒng)一的,可以在這里進行統(tǒng)一配置,也就無需再傳入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,完成分頁操作
DefinedPageInterceptor definedPageInterceptor = new DefinedPageInterceptor();
sqlSession.setPlugins(new Interceptor[]{definedPageInterceptor});
return sqlSession;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
3.DAO層接口方法名需要和代碼中自定義的".+ByInterceptor$"正則表達式相匹配,mapper的書寫依然是查詢所有數據
<select id="selectByInterceptor" resultMap="BaseResult"> select * from tb_user </select>
4.業(yè)務層直接調用
5.控制層直接調用
五、開源項目PageHelper實現:本質還是自己封裝了個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();
//設置數據庫類型
properties.setProperty("helperDialect", "mysql");
//該參數默認為false
//設置為true時,會將RowBounds第一個參數offset當成pageNum頁碼使用
//和startPage中的pageNum效果一樣
properties.setProperty("offsetAsPageNum", "true");
//該參數默認為false
//設置為true時,使用RowBounds分頁會進行count查詢
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,完成分頁操作
PageInterceptor pageInterceptor = this.initPageInterceptor();
//配置自定義的Interceptro作為MyBatis的Interceptor,完成分頁操作
DefinedPageInterceptor definedPageInterceptor = new DefinedPageInterceptor();
sqlSession.setPlugins(new Interceptor[]{pageInterceptor, definedPageInterceptor});
return sqlSession;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
3.mapper依然是查詢所有數據
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());
//寫到要使用到的類名和方法名
List<User> users = session.selectList("cn.edu.yau.mapper.UserMapper.selectAll");
return users;
}
}
6.業(yè)務層直接調用Handler
7.控制層直接調用
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
Spring Boot集成SpringFox 3.0與Pageable參數處理方法
這篇文章主要介紹了Spring Boot集成SpringFox 3.0與Pageable參數處理,本文給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2023-10-10

