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 Cloud-Feign服務調用的問題及處理方法
Feign 是一個聲明式的 REST 客戶端,它用了基于接口的注解方式,很方便實現客戶端配置。接下來通過本文給大家介紹Spring Cloud-Feign服務調用,需要的朋友可以參考下2021-10-10教你使用IDEA搭建spring源碼閱讀環(huán)境的詳細步驟
這篇文章主要介紹了使用IDEA搭建spring源碼閱讀環(huán)境的詳細步驟,本文分兩步通過實例圖文相結合給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友參考下吧2021-08-08