前言:
在java web我的项目中常常会用到分页这个性能,而以罕用的的长久层框架mybatis为例,并没有提供原生的物理分页性能相干接口,不过mybaits 提供了相应的插件性能能够不便咱们做一些相应的扩大 ,这里咱们数据库选为mysql ,个别状况下会间接应用第三放的插件 如 mybatis-helper , mybatis-plus ,他们都提供了分页这个性能,知其然知其所以然,如果不应用这些类库咱们要如何做呢?
实现:
首先在mysql讲到分页咱们会想到limit 关键字;而后呢前台用到分页 还须要有一个总页数 ,总页数的背地是总条数和每页多少条;关键点:通过插件实现 分页+总条数
这是一个简略的demo
import lombok.AllArgsConstructor;import lombok.Data;import lombok.RequiredArgsConstructor;import lombok.experimental.Delegate;import org.apache.ibatis.binding.MapperMethod;import org.apache.ibatis.cache.CacheKey;import org.apache.ibatis.executor.Executor;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.mapping.ParameterMapping;import org.apache.ibatis.plugin.Interceptor;import org.apache.ibatis.plugin.Intercepts;import org.apache.ibatis.plugin.Invocation;import org.apache.ibatis.plugin.Signature;import org.apache.ibatis.session.ResultHandler;import org.apache.ibatis.session.RowBounds;import org.springframework.jdbc.core.JdbcTemplate;import org.springframework.stereotype.Component;import java.lang.reflect.Field;import java.util.ArrayList;import java.util.List;import java.util.stream.Collectors;/** * @author yangrd * @date 2021/12/7 */@RequiredArgsConstructor@Component@Intercepts({@Signature( type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class})})public class MyTestInterceptor implements Interceptor { private final JdbcTemplate jdbcTemplate; @Override public Object intercept(Invocation invocation) throws Throwable { BoundSql boundSql = (BoundSql) invocation.getArgs()[5]; String tempSql = boundSql.getSql(); MapperMethod.ParamMap<Object> parameterObject = (MapperMethod.ParamMap<Object>) boundSql.getParameterObject(); List<String> argNames = boundSql.getParameterMappings().stream().map(ParameterMapping::getProperty).collect(Collectors.toList()); Object[] args = argNames.stream().map(parameterObject::get).toArray(); Long count = count(tempSql, args); Field field = BoundSql.class.getDeclaredField("sql"); field.setAccessible(true); field.set(boundSql, String.format("%s limit 1, 10", tempSql)); return Page.of(count, (ArrayList<?>) invocation.proceed()); } @Data @AllArgsConstructor(staticName = "of") public static class Page<T> implements List<T> { private Long total; @Delegate private List<T> list; } private Long count(String tempSql, Object[] args) { String countSql = String.format("select count(*) from (%s) t", tempSql); return jdbcTemplate.queryForObject(countSql, Long.class, args); }}
总结:
这是一个极其简略的demo 权当抛砖引玉 ,如判断是否须要分页、第几页、 每页多条数这些中央还须要欠缺,但它向咱们展现了 mybatis中如何分页的外围原理,我想咱们在这里完结了这个示例,但在这个示例之外如果能给你带来一些思考天然是极好的。