(十二)从零搭建后端框架——如此简洁的分页查询

2,617 阅读3分钟

前言

【如此简洁的数据库操作】这一篇文章中, 通过使用MyBatis-Plus极大的简化了数据库的操作,实现了简单的CURD。

本篇文章就通过MyBatis-Plus来简洁的实现分页查询。

实现方式有两种:

  • 原生分页查询
  • 自定义分页查询

注:该文章是后续,如若没看过前面的,建议先查看

具体实现

分页插件

首先需要创建配置类来配置分页插件,如下:

@Configuration
public class MybatisPlusConfig {

    @Bean
    public PaginationInterceptor paginationInterceptor() {
        PaginationInterceptor paginationInterceptor = new PaginationInterceptor();
        // 设置请求的页面大于最大页后操作, true调回到首页,false 继续请求  默认false
        // paginationInterceptor.setOverflow(false);
        // 设置最大单页限制数量,默认 500 条,-1 不受限制
        // paginationInterceptor.setLimit(500);
        // 开启 count 的 join 优化,只针对部分 left join
        paginationInterceptor.setCountSqlParser(new JsqlParserCountOptimize(true));
        return paginationInterceptor;
    }
}

原生分页查询

若使用MyBatis-Plus原生的分页查询方式,则不需要其它实现(在上一篇的基础上),直接可以使用。如下:

@RestController
@RequestMapping("/user")
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @GetMapping("/page")
    public ApiResult selectUserPage(@RequestParam String nickname,
                                    @RequestParam long pageNum,
                                    @RequestParam long pageSize) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like("nickname", nickname);

        Page<User> page = new Page<>(pageNum, pageSize);

        IPage<User> userPage = userService.page(page, wrapper);
        return ApiResult.success(new QueryResult<>(userPage));
    }
}
  • Page 用于指定分页条件

  • Wrapper 条件构造器,用于指定查询条件

    条件函数有很多,具体可以查看官网:mp.baomidou.com/guide/wrapp…

上面代码有用到QueryResult类,如下:

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
public class QueryResult<T> {

    /**
     * 总条数
     */
    private Long total;

    /**
     * 返回结果集
     */
    private List<T> items;

    public QueryResult(IPage<T> page) {
        this.total = page.getTotal();
        this.items = page.getRecords();
    }
}

简单的分页查询使用上面的方式即可,不需要编写SQL。

但分页查询难免可能出先多表连接查询,或者是一些复杂的sql语句,这时候原生分页查询就不支持,需要自定义。

自定义分页查询

自定义即自己实现SQL语句。因为有了分页插件,自定义的SQL语句也不需要编写分页相关的SQL。如下:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.zhuqc.framework.dao.UserDao">

    <select id="selectUserPage" resultType="com.zhuqc.framework.entity.User">
        SELECT * FROM sys_user ${ew.customSqlSegment}
    </select>

</mapper>

如果需要自定义SQL,又想使用Wrapper条件构造器,就需要在SQL添加${ew.customSqlSegment}。并且在Mapper接口中添加参数。如下:

@Mapper
public interface UserDao extends BaseMapper<User> {

    IPage<User> selectUserPage(IPage<User> page, @Param(Constants.WRAPPER) Wrapper<User> queryWrapper);
}
@Service
@Transactional
public class UserServiceImpl extends ServiceImpl<UserDao, User> implements UserService {

    @Autowired
    private UserDao userDao;

    @Override
    public IPage<User> selectUserPage(IPage<User> page, Wrapper<User> queryWrapper) {
        return userDao.selectUserPage(page, queryWrapper);
    }
}

在配置文件中,指定Mapper文件的位置:

mybatis-plus:
  mapper-locations: classpath*:/sql-mappers/**/*.xml
  configuration:
    map-underscore-to-camel-case: true

编写完成后,就可以在控制层使用:

@RestController
@RequestMapping("/user")
public class UserController extends BaseController {

    @Autowired
    private UserService userService;

    @GetMapping("/page2")
    public ApiResult selectUserPage2(@RequestParam String nickname,
                                     @RequestParam long pageNum,
                                     @RequestParam long pageSize) {
        QueryWrapper<User> wrapper = new QueryWrapper<>();
        wrapper.like("nickname", nickname);

        Page<User> page = new Page<>(pageNum, pageSize);

        IPage<User> userPage = userService.selectUserPage(page, wrapper);
        return ApiResult.success(new QueryResult<>(userPage));
    }
}

总结

在不使用分页插件的情况下,若想使用分页查询,需要先查询总数,再查询当前页的数据,这样就需要编写两条SQL。

而现在使用了分页插件,简单的分页查询不需要编写SQL,直接使用。复杂的查询也只需要编写查询当前页数据的SQL,查询总数的SQL分页插件会自动生成。

通过使用MyBatis-Plus实现分页查询,可以感觉到极大的简化了开发。

以上,感谢阅读,如果感觉有帮助的话,不妨随手点个赞!

源码

github.com/zhuqianchan…

往期回顾