(1) 创建StudentMapper.xml文件,编写查询的sql语句:
<select id="queryStudents" resultMap="studentMapper">
select * from student
select>
(2) 定义 IStuService 接口,并且定义分页方法:
List<Student> queryStudents(int currentPage, int pageSize);
(3) 实现类 StuServiceIml 对获取到的数组通过 currPage 和 pageSize 进行分页:
public List<Student> queryStudents(int currentPage, int pageSize) {
List<Student> studentList = studentMapper.queryStudents;
int firstIndex = (currentPage - 1) * pageSize;
int endIndex = currentPage * pageSize;
return studentList.subList(firstIndex, endIndex);
}
(1) 创建StudentMapper.xml文件,编写查询的sql语句:
<select id="queryStudentsBySql" parameterType="map" resultMap="studentMapper">
select * from student limit #{currentIndex},#{pageSize}
select>
(2) 定义 IStuService 接口,并且定义分页方法:
List<Student> queryStudentsBySql(int currentPage, int pageSize);
(3) 实现类 StuServiceIml 对获取到的数组通过 currPage 和 pageSize 进行分页:
public List<Student> queryStudentsBySql(int currentPage, int pageSize) {
Map<String, Object> data = new HashMap();
data.put("currentIndex", (currentPage - 1) * pageSize);
data.put("pageSize", pageSize);
return studentMapper.queryStudentsBySql(data);
}
推荐阅读:springboot+mybatis自定义拦截器实现分页查询
@Data
public class PageBean<T> {
private int currentPage = 1; //当前页
private int pageSize = 10; //每页条数
private int pageCount; //总页数
private int totalCount; //总条数
private List<T> data;
public void setTotalCount(int totalCount) {
this.totalCount = totalCount;
this.calPageCount();
}
public void calPageCount() {
this.pageCount = (int) Math.ceil((this.totalCount * 1.0) / this.pageSize);
}
}
<plugins>
<plugin interceptor="com.xxx.PageInterceptor">plugin>
plugins>
@Component
@Intercepts({
@Signature(type = StatementHandler.class, method = "prepare", args = {
Connection.class, Integer.class})})
public class PageInterceptor implements Interceptor {
@Override
public Object intercept(Invocation invocation) throws Throwable {
StatementHandler statementHandler = (StatementHandler) invocation.getTarget(); // 获取拦截的对象
BoundSql boundSql = statementHandler.getBoundSql(); // 待执行的sql对象
// 判断是否查询语句
if (!"".equals(boundSql.getSql()) && boundSql.getSql().toUpperCase().trim().startsWith("SELECT")) {
Object params = boundSql.getParameterObject(); // 获取参数
// 如果查询方法中传入的参数是 PageBean 的一个实例,则为分页查询
if (params instanceof PageBean) {
PageBean pageBean = (PageBean) params;
Connection connection = (Connection) invocation.getArgs()[0];
MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
// 查询总条数
int count = count(connection, (ParameterHandler) metaObject.getValue("delegate.parameterHandler"), boundSql);
pageBean.setTotalCount(count);
// 拼接分页语句
String pageSql = boundSql.getSql() + " limit " +
((pageBean.getCurrentPage() - 1) * pageBean.getPageSize()) +
", " + pageBean.getPageSize();
metaObject.setValue("delegate.boundSql.sql", pageSql);
return invocation.proceed();
}
}
return invocation.proceed();
}
@Override
public Object plugin(Object o) {
// 注意:此处判断使用的是RoutingStatementHandler,而不是StatementHandler
if (o instanceof RoutingStatementHandler) {
return Plugin.wrap(o, this);
} else {
return o;
}
}
public int count(Connection connection, ParameterHandler parameterHandler, BoundSql boundSql) {
String countSql = "select count(0) from (" + boundSql.getSql() + ") as total";
PreparedStatement countStmt = null;
ResultSet rs = null;
try {
countStmt = connection.prepareStatement(countSql);
parameterHandler.setParameters(countStmt);
rs = countStmt.executeQuery();
if (rs.next()) {
return rs.getInt(1);
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
try {
if (null != countStmt) {
countStmt.close();
}
if (null != rs) {
rs.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
return 0;
}
}
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>5.1.41version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>1.3.1version>
dependency>
<dependency>
<groupId>tk.mybatisgroupId>
<artifactId>mapper-spring-boot-starterartifactId>
<version>1.2.4version>
dependency>
<dependency>
<groupId>com.github.pagehelpergroupId>
<artifactId>pagehelper-spring-boot-starterartifactId>
<version>1.2.3version>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-configuration-processorartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druid-spring-boot-starterartifactId>
<version>1.1.0version>
dependency>
<dependency>
<groupId>com.alibabagroupId>
<artifactId>druidartifactId>
<version>${druid.version}version>
dependency>
# 数据源基础配置
spring.datasource.type=com.alibaba.druid.pool.DruidDataSource
#数据库
spring.datasource.url=jdbc:mysql://localhost:3306/test?characterEncoding=utf8
spring.datasource.username=root
spring.datasource.password=root
spring.datasource.driver-class-name=com.mysql.jdbc.Driver
# mybatis 配置
mybatis.type-aliases-package=com.mos.quote.model
mybatis.mapper-locations=classpath:mapper/*.xml
# 通用 Mapper 配置(多个时逗号隔开)
mapper.mappers=com.mos.quote.common.MyMapper
#insert、update是否判断字符串类型!='' 即 test="str != null"表达式内是否追加 and str != ''
mapper.not-empty=false
#主键生成策略
mapper.identity=MYSQL
# 分页插件配置
#指定数据库分页类型
pagehelper.helperDialect=mysql
#页码<=0 查询第一页,页码>=总页数查询最后一页
pagehelper.reasonable=true
#支持通过 Mapper 接口参数来传递分页参数
pagehelper.supportMethodsArguments=true
pagehelper.params=count=countSql
import tk.mybatis.mapper.common.Mapper;
import tk.mybatis.mapper.common.MySqlMapper;
public interface MyMapper<T> extends Mapper<T>, MySqlMapper<T> {
}
tk.mapper 使用案例:
public void selectByExampleTest() {
Example example = new Example(Category.class);
Example.Criteria criteria = example.createCriteria();
criteria.andEqualTo("categoryID", 1);
criteria.orEqualTo("categoryID", 2);
categoryDao.selectByExample(example);
}
@Service
public class AreaServiceImpl implements IAreaService {
@Autowired
private AreaMapper areaMapper;
@Override
public PageInfo<Area> queryPage(Integer pageNo, Integer pageSize, String parentId) {
PageHelper.startPage(pageNo,pageSize); //分页参数配置
List<Area> list = this.queryAllByPID(parentId); //查询
return new PageInfo<>(list); //分页
}
}
执行 PageHelper.startPage(1, 10)
后紧跟着执行 Executor,即 countryMapper.selectIf(param1)
,避免这两行之间出现错误
大数据量建议不要使用 PageHelper 插件实现分页
# 结果 4.73s
select * from user where age = 10 limit 100000,10;
替换为
# 结果 0.53s
SELECT a.* FROM USER a
INNER JOIN
(SELECT id FROM USER WHERE age = 10 LIMIT 100000,10) b
ON a.id = b.id;
注:PageHelper 使用拦截器重构 sql 的方式实现分页查询
解决:MySql 的 order by 和 limit 不要一起使用
PageHelper 替代框架:sqlhelper