SSM项目下的分页

在进行分页时,我们要明白前端页面需要给后端传递的数据有哪些,后端又要传递给前端页面什么数据。

前端给后台:当前页是第几页,每一页的大小

后台给前端:当前页的数据,总条数

1、创建实体类(包含总条数和当前页的数据)

@Data
public class PageBean {
    /**
     *  总条数
     */
    private long total;
    /**
     * 当前页数的数据
     */
    private List data;


    public static PageBean setPageAndData(long total,List data){
        PageBean pageBean = new PageBean();
        pageBean.setTotal(total);
        pageBean.setData(data);
        return pageBean;
    }
}

 

2、pageHelper分页插件

使用方法

1. 引入分页插件

引入分页插件有下面2种方式,推荐使用 Maven 方式。

1). 引入 Jar 包

你可以从下面的地址中下载最新版本的 jar 包

由于使用了sql 解析工具,你还需要下载 jsqlparser.jar(需要和PageHelper 依赖的版本一致) :

2). 使用 Maven

在 pom.xml 中添加如下依赖:

<dependency>
    <groupId>com.github.pagehelper</groupId>
    <artifactId>pagehelper</artifactId>
    <version>最新版本</version>
</dependency>

最新版本号可以从首页查看。

2. 配置拦截器插件

特别注意,新版拦截器是 com.github.pagehelper.PageInterceptor。 com.github.pagehelper.PageHelper 现在是一个特殊的 dialect 实现类,是分页插件的默认实现类,提供了和以前相同的用法。

2.1. 在 MyBatis 配置 xml 中配置拦截器插件

<!-- 
    plugins在配置文件中的位置必须符合要求,否则会报错,顺序如下:
    properties?, settings?, 
    typeAliases?, typeHandlers?, 
    objectFactory?,objectWrapperFactory?, 
    plugins?, 
    environments?, databaseIdProvider?, mappers?
-->
<plugins>
    <!-- com.github.pagehelper为PageHelper类所在包名 -->
    <plugin interceptor="com.github.pagehelper.PageInterceptor">
        <!-- 使用下面的方式配置参数,后面会有所有的参数介绍 -->
        <property name="param1" value="value1"/>
    </plugin>
</plugins>

 

 

2.2. 在 Spring 配置文件中配置拦截器插件

使用 spring 的属性配置方式,可以使用 plugins 属性像下面这样配置:

<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
  <!-- 注意其他配置 -->
  <property name="plugins">
    <array>
      <bean class="com.github.pagehelper.PageInterceptor">
        <property name="properties">
          <!--使用下面的方式配置参数,一行配置一个 -->
          <value>
            params=value1
          </value>
        </property>
      </bean>
    </array>
  </property>
</bean>

 

3. 如何在代码中使用

分页插件支持以下几种调用方式:

//第一种,RowBounds方式的调用
List<User> list = sqlSession.selectList("x.y.selectIf", null, new RowBounds(0, 10));

//第二种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.startPage(1, 10);
List<User> list = userMapper.selectIf(1);

//第三种,Mapper接口方式的调用,推荐这种使用方式。
PageHelper.offsetPage(1, 10);
List<User> list = userMapper.selectIf(1);

//第四种,参数方法调用
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
    List<User> selectByPageNumSize(
            @Param("user") User user,
            @Param("pageNum") int pageNum, 
            @Param("pageSize") int pageSize);
}
//配置supportMethodsArguments=true
//在代码中直接调用:
List<User> list = userMapper.selectByPageNumSize(user, 1, 10);

//第五种,参数对象
//如果 pageNum 和 pageSize 存在于 User 对象中,只要参数有值,也会被分页
//有如下 User 对象
public class User {
    //其他fields
    //下面两个参数名和 params 配置的名字一致
    private Integer pageNum;
    private Integer pageSize;
}
//存在以下 Mapper 接口方法,你不需要在 xml 处理后两个参数
public interface CountryMapper {
    List<User> selectByPageNumSize(User user);
}
//当 user 中的 pageNum!= null && pageSize!= null 时,会自动分页
List<User> list = userMapper.selectByPageNumSize(user);

//第六种,ISelect 接口方式
//jdk6,7用法,创建接口
Page<User> page = PageHelper.startPage(1, 10).doSelectPage(new ISelect() {
    @Override
    public void doSelect() {
        userMapper.selectGroupBy();
    }
});
//jdk8 lambda用法
Page<User> page = PageHelper.startPage(1, 10).doSelectPage(()-> userMapper.selectGroupBy());

//也可以直接返回PageInfo,注意doSelectPageInfo方法和doSelectPage
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(new ISelect() {
    @Override
    public void doSelect() {
        userMapper.selectGroupBy();
    }
});
//对应的lambda用法
pageInfo = PageHelper.startPage(1, 10).doSelectPageInfo(() -> userMapper.selectGroupBy());

//count查询,返回一个查询语句的count数
long total = PageHelper.count(new ISelect() {
    @Override
    public void doSelect() {
        userMapper.selectLike(user);
    }
});
//lambda
total = PageHelper.count(()->userMapper.selectLike(user));
使用PageInfo的用法(常用):
//获取第1页,10条内容,默认查询总数count
PageHelper.startPage(1, 10);
List<User> list = userMapper.selectAll();
//用PageInfo对结果进行包装
PageInfo page = new PageInfo(list);
//测试PageInfo全部属性
//PageInfo包含了非常全面的分页属性
assertEquals(1, page.getPageNum());
assertEquals(10, page.getPageSize());
assertEquals(1, page.getStartRow());
assertEquals(10, page.getEndRow());
assertEquals(183, page.getTotal());
assertEquals(19, page.getPages());
assertEquals(1, page.getFirstPage());
assertEquals(8, page.getLastPage());
assertEquals(true, page.isFirstPage());
assertEquals(false, page.isLastPage());
assertEquals(false, page.isHasPreviousPage());
assertEquals(true, page.isHasNextPage());

案例

mapper层是逆向工程自动生成的,所以只能用拼接的方式来写SQL语句

Service层实现类代码

  @Override
    public List<Book> searchPage(BookCriteria bookCriteria) {
        BookExample bookExample = new BookExample();
        BookExample.Criteria criteria1 = bookExample.createCriteria();
        BookExample.Criteria criteria2 = bookExample.createCriteria();
        BookExample.Criteria criteria3 = bookExample.createCriteria();

        if (bookCriteria.getFirstType() != -1 && bookCriteria.getFirstType() != 0) {
            criteria1.andFirstTypeIdEqualTo(bookCriteria.getFirstType());
        }
        if (bookCriteria.getSecondType() != -1 && bookCriteria.getSecondType() != 0) {
            criteria1.andSecondTypeIdEqualTo(bookCriteria.getSecondType());
        }
        if (!StringUtils.isEmpty(bookCriteria.getSearchStr())) {
            criteria1.andBookNameLike("%" + bookCriteria.getSearchStr() + "%");
        }


        if (bookCriteria.getFirstType() != -1 && bookCriteria.getFirstType() != 0) {
            criteria2.andFirstTypeIdEqualTo(bookCriteria.getFirstType());
        }
        if (bookCriteria.getSecondType() != -1 && bookCriteria.getSecondType() != 0) {
            criteria2.andSecondTypeIdEqualTo(bookCriteria.getSecondType());
        }
        if (!StringUtils.isEmpty(bookCriteria.getSearchStr())) {
            criteria2.andAuthorNameLike("%" + bookCriteria.getSearchStr() + "%");
        }


        if (bookCriteria.getFirstType() != -1 && bookCriteria.getFirstType() != 0) {
            criteria3.andFirstTypeIdEqualTo(bookCriteria.getFirstType());
        }
        if (bookCriteria.getSecondType() != -1 && bookCriteria.getSecondType() != 0) {
            criteria3.andSecondTypeIdEqualTo(bookCriteria.getSecondType());
        }
        if (!StringUtils.isEmpty(bookCriteria.getSearchStr())) {
            criteria3.andDescriptionLike("%" + bookCriteria.getSearchStr() + "%");
        }

        bookExample.or(criteria2);
        bookExample.or(criteria3);
        bookExample.setOrderByClause("book_id desc");

        List<Book> books = bookMapper.selectByExample(bookExample);

        books.forEach(book -> {
            Integer firstTypeId = book.getFirstTypeId();
            Booktype booktype = booktypeMapper.selectByPrimaryKey(firstTypeId);
            book.setFirstTypeName(booktype == null? "未知分类" : booktype.getTypeName());
            Integer secondTypeId = book.getSecondTypeId();
            Booktype booktype1 = booktypeMapper.selectByPrimaryKey(secondTypeId);
            book.setSecondTypeName(booktype1 == null? "未知分类" : booktype1.getTypeName());
        });
        return books;
    }

 

Controller层代码

    /**
     * 分页查询进阶版
     * 分页条件查询
     * @param bookCriteria
     * @return
     */
    @GetMapping("searchPage")
    @ResponseBody
    public AjaxResult searchPage(BookCriteria bookCriteria) {
        //开启分页,这一行代码的下面一行代码将会被分页
        PageHelper.startPage(bookCriteria.getCurrentPage(), bookCriteria.getPageSize());
        List<Book> all = bookService.searchPage(bookCriteria);
        //当前页的内容
        PageInfo<Book> pageInfo = new PageInfo<>(all);
        //获取总条数
        long total = pageInfo.getTotal();
        return AjaxResult.success(PageBean.setPageAndData(total, all));
    }
前端JS代码
    var currentPage = 1;
    var pageSize = 5;

    /**
     * 分页查询所有
     */
    function searchPage() {
        //获取的值是key=value形式
        // console.log($("#searchForm").serialize())
        $.get("/book/searchPage?currentPage=" + currentPage + "&pageSize=" + pageSize + "&" + $("#searchForm").serialize(), function (response) {
            if (response.data) {
                var str = "";
                response.data.data.forEach(function (item) {
                    str += "<tr>\n" +
                        "                            <td><input type=\"checkbox\"></td>\n" +
                        "                            <td>" + item.bookId + "</td>\n" +
                        "                            <td>" + item.bookName + "</td>\n" +
                        "                            <td>" + item.authorName + "</td>\n" +
                        "                            <td>" + item.firstTypeName + "</td>\n" +
                        "                            <td>" + item.secondTypeName + "</td>\n" +
                        "                            <td><img src=\"" + item.imgUrl + "\" style=\"vertical-align: middle\" width=\"35px\"\n" +
                        "                                     height=\"35px\" alt=\"\"></td>\n" +
                        "                            <td>\n" +
                        "                                <button  itemid=\"" + item.bookId + "\" type=\"button\" class=\"btn btn-success updateBtn\" data-toggle=\"modal\" data-target=\"#createDialog\">编辑</button>\n" +
                        "                                <button itemid=\"" + item.bookId + "\" type=\"button\" class=\"btn btn-danger deletedBtn\">删除</button>\n" +
                        "                            </td>\n" +
                        "                        </tr>";
                });
                $("tbody").html(str);
                initPage(response.data.total);
            }

            delBtn();
            addBtn();
            alterBtn();
        })
    }
    //调用分页函数
    searchPage();

    /**
     * 初始化分页插件
     *
     */
    function initPage(total) {
        $("#pagination").pagination(total,    //分布总数量,必须参数
            {
                callback: pageChangeHandler,  //PageCallback() 为翻页调用次函数。
                prev_text: "« 上一页",
                next_text: "下一页 »",
                items_per_page: pageSize,
                num_edge_entries: 2,       //两侧首尾分页条目数
                num_display_entries: 4,    //连续分页主体部分分页条目数
                current_page: currentPage - 1,   //当前页索引
                load_first_page: false
            });
    };

    /**
     * 下一页
     * @param index
     */
    function pageChangeHandler(index) {
        currentPage = index + 1;
        searchPage();
    }

 




posted @ 2021-06-13 20:31  mini9264  阅读(192)  评论(0编辑  收藏  举报