mybatis是非常优秀的半orm框架,比hibernate更容易控制,性能也很好,但mybatis官方并没提供分页功能,需要自己实现,下面提供一种物理分页的实现思路:
(基于sping、spring mvc、mybatis的整合,将PO)
1. 编写一个Pagination.java的实体类,含有页面显示数、总页数、当前页、开始行、结束行等属性
2. sql里加上分页参数
3. PO对象里加上这个分页对象
4. 在Service里,执行查询前,将分页实例的总记录数set进去,当前页由页面传入,这样就有了三个必备参数:总记录数、每页显示数(可以设一个默认值)、当前页,就可以获取sql查询时开始行、结束行,就实现分页了。
优点:
不改动mybatis框架代码,对service的实现类改动很小,只需加入一行代码,对controller改个只需model里add两个attribute,尽量做到低侵入低耦合。分页导航自动生成,可重新设置每页显示数,从不分页改为分页尽可能减少代码的增加工作。
缺点:
暂时只适用于持久化对象和表单视图对象共用,即持久化对象既用于数据库交互,也用于表单数据绑定。
下面为实例说明:
1. 在对象里加入一个属性:
- ...
- /** 用于分页 */
- private Pagination pagination = new Pagination();
- public Pagination getPagination() {
- return pagination;
- }
- public void setPagination(Pagination pagination) {
- this.pagination = pagination;
- }
此处初始化了,是为了不用判断是否为null,相当于给一个初始值。
2. 在mapper.xml文件中加入分页语句本例以mysql(limit #{offSet}, #{pageSize})为例
- <select id="getUserInfoList" parameterType="com.jayung.pagination.domain.UserInfo"
- resultType="com.jayung.pagination.domain.UserInfo">
- select user_id userId, user_name userName, password password,
- age age
- from user_info
- <trim prefix="where" suffixOverrides="and">
- <if test="userId!=null and userId!=''">user_id = #{userId} and </if>
- <if test="userName!=null and userName!=''">user_name = #{userName} and </if>
- <if test="password!=null and password!=''">password = #{password} and </if>
- <if test="age!=null and age!=''">age = #{age} and </if>
- </trim>
- <span style="background-color: #ffff00;">limit #{pagination.startRow}, #{pagination.pageSize}</span>
- </select>
其中limit #{pagination.startRow}, #{pagination.pageSize}是分页的两个参数;
3. 定义取总记录数的SQL
- <select id="getUserInfoListCount" parameterType="com.jayung.pagination.domain.UserInfo"
- resultType="java.lang.Integer">
- select count(1)
- from user_info
- <trim prefix="where" suffixOverrides="and">
- <if test="userId!=null and userId!=''">user_id = #{userId} and </if>
- <if test="userName!=null and userName!=''">user_name = #{userName} and </if>
- <if test="password!=null and password!=''">password = #{password} and </if>
- <if test="age!=null and age!=''">age = #{age} and </if>
- </trim>
- </select>
与上面SQL的差别是将查询结果集换成了count记录集的总数;
3. serviceimpl
- public List<UserInfo> getUserInfoList(UserInfo userInfo) {
- userInfo.getPagination().setTotalRow(userInfoMapper.getUserInfoListCount(userInfo));
- return userInfoMapper.getUserInfoList(userInfo);
- }
4. controller
- @RequestMapping(value = "/demo/userInfo/search")
- public String search(Model model, UserInfo userInfo, HttpServletRequest request) {
- // userInfo里含有pagination属性。
- model.addAttribute("userInfoList", userInfoService.getUserInfoList(userInfo));
- // pagination是分页对象
- model.addAttribute("pagination", userInfo.getPagination());
- // paginationForm是为了不丢失从查询页面传过来的查询参数,并保存当前页、每页显示数的信息
- model.addAttribute("paginationForm", PaginationUtil.getPaginationForm(request));
- return "/demo/userInfo/userInfoList";
- }
5. paginationUtil用于保存来自源页面的参数,防止翻到第二页时丢失。
- public static String getPaginationForm(HttpServletRequest request) {
- StringBuffer form = new StringBuffer();
- form.append("<form name=\"_paginationForm\" id=\"_paginationForm\" method=\"post\" aciton=\""
- + new UrlPathHelper().getOriginatingRequestUri(request) + "\">\n");
- Enumeration paramNames = request.getParameterNames();
- while (paramNames.hasMoreElements()) {
- String paramName = (String) paramNames.nextElement();
- String paramValue = request.getParameter(paramName);
- if (!"pagination.pageSize".equals(paramName) && !"pagination.currentPage".equals(paramName)) {
- form.append(" <input type=\"hidden\" name=\"" + paramName + "\" value=\"" + paramValue + "\" />\n");
- }
- }
- String pageSize = (request.getParameter("pagination.pageSize") == null) ? Constant.PAGE_SIZE_DEFAULT.toString()
- : request.getParameter("pagination.pageSize");
- String currentPage = (request.getParameter("pagination.currentPage") == null) ? "1" : request
- .getParameter("pagination.currentPage");
- form.append(" <input type=\"hidden\" id=\"_pagination.pageSize\" name=\"pagination.pageSize\" value=\"" + pageSize + "\" />\n");
- form.append(" <input type=\"hidden\" id=\"_pagination.currentPage\" name=\"pagination.currentPage\" value=\"" + currentPage + "\" />\n");
- form.append("</form>");
- return form.toString();
- }
6. 分页页面
- <table class="tableList" id="userInfoList">
- <tr>
- <th>userId</th>
- <th>userName</th>
- <th>password</th>
- <th>age</th>
- <th>操作</th>
- <tr>
- <c:forEach items="${userInfoList}" var="userInfo" varStatus="status">
- <tr id="${status.index}">
- <td>${userInfo.userId}</td>
- <td>${userInfo.userName}</td>
- <td>${userInfo.password}</td>
- <td>${userInfo.age}</td>
- <td><a href="${userInfo.userId}">查看</a>
- <a href="${userInfo.userId}/edit">编辑</a>
- <a href="javascript:void();" οnclick="deleteRow('${userInfo.userId}','${status.index}');">删除</a></td>
- </tr>
- </c:forEach>
- </table>
- <div><span style="background-color: #ffff00;">${pagination.navigator}</span></div>
- span style="background-color: #ffff00;">${paginationForm}</span>
${pagination.navigator}是分页导航
${paginationForm}是分页表单
最后上传完整工程附件,含初始化sql脚本
欢迎大家讨论优化。
下载链接请转至iteye博客地址: