##分页处理

分页
1、前台分页
2、数据库(后台)分页
3、存储过程

Orade (Rownum) Mysql(limit) sqlservier(Top N)

第一步 :
要在mybatis 核心xml中引入 拦截器插件


<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration><plugins><plugin interceptor="com.foreknow.dao.interceptor.PageInterceptor"></plugin></plugins>
</configuration>

第二步:
创建com.foreknow.util 包 下

Page.java 总记录数 当前页数 总页数 每页要显示的额记录数

package com.foreknow.util;public class Page {// 总记录数private int totalNumber;// 当前页数private int currentPage;// 总页数private int totalPage;// 每页要显示的记录数private int pageNumber;public Page() {this.currentPage = 1;this.pageNumber = 5;}public int getTotalNumber() {return totalNumber;}/*** 计算总页数*/public void count() {this.totalPage = this.totalNumber / this.pageNumber;if (this.totalNumber % this.pageNumber > 0) {this.totalPage++;}if (this.totalPage <= 0) {this.totalPage = 1;}if (this.currentPage > this.totalPage) {this.currentPage = this.totalPage;}if (this.currentPage <= 0) {this.currentPage = 1;}}public void setTotalNumber(int totalNumber) {this.totalNumber = totalNumber;count();}public int getCurrentPage() {return currentPage;}public void setCurrentPage(int currentPage) {this.currentPage = currentPage;}public int getTotalPage() {return totalPage;}public void setTotalPage(int totalPage) {this.totalPage = totalPage;}public int getPageNumber() {return pageNumber;}public void setPageNumber(int pageNumber) {this.pageNumber = pageNumber;}}

MD5Util.java 加密

package com.foreknow.util;import java.io.File;
import java.io.FileInputStream;
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.security.MessageDigest;/*** MD5加密工具类*/
public class MD5Util {private static final char DIGITS[] = { '0', '1', '2', '3', '4', '5', '6','7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' };/*** 获取文件的MD5码* * @param absPath*            文件路径* @return 文件的MD5码*/public final static String getFileMD5(String absPath) {try {File file = new File(absPath);MessageDigest mdTemp = MessageDigest.getInstance("MD5");FileInputStream fis = new FileInputStream(file);FileChannel filechannel = fis.getChannel();MappedByteBuffer mbb = filechannel.map(FileChannel.MapMode.READ_ONLY, 0, file.length());mdTemp.update(mbb);byte[] md = mdTemp.digest();int j = md.length;char str[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];str[k++] = DIGITS[byte0 >>> 4 & 0xf];str[k++] = DIGITS[byte0 & 0xf];}fis.close();return new String(str);} catch (Exception e) {return "";}}/*** 获取指定字符串的MD5码* * @param s*            字符串* @return 字符串的MD5码*/public final static String getMD5(String s) {char hexDigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9','a', 'b', 'c', 'd', 'e', 'f' };try {byte[] strTemp = s.getBytes();MessageDigest mdTemp = MessageDigest.getInstance("MD5");mdTemp.update(strTemp);byte[] md = mdTemp.digest();int j = md.length;char str[] = new char[j * 2];int k = 0;for (int i = 0; i < j; i++) {byte byte0 = md[i];str[k++] = hexDigits[byte0 >>> 4 & 0xf];str[k++] = hexDigits[byte0 & 0xf];}return new String(str);} catch (Exception e) {return null;}}public static void main(String[] args) {System.out.println(getMD5("admin"));}
}

FileUtil.java 对文件的处理 获取 删除 文件的保存 上传

package com.foreknow.util;import org.springframework.web.multipart.MultipartFile;import java.io.File;
import java.io.IOException;public class FileUtil {/*** 将MultipartFile保存到指定的路径下* * @param file*            Spring的MultipartFile对象* @param savePath*            保存路径* @return 保存的文件名,当返回NULL时为保存失败。* @throws IOException* @throws IllegalStateException*/public static String save(MultipartFile file, String savePath) throws IllegalStateException, IOException {if (file != null && file.getSize() > 0) {File fileFolder = new File(savePath);if (!fileFolder.exists()) {fileFolder.mkdirs();}File saveFile = getFile(savePath, file.getOriginalFilename());file.transferTo(saveFile);return saveFile.getName();}return null;}/*** 删除文件* * @param filePath*            文件路径* @return 是否删除成功:true-删除成功,false-删除失败*/public static boolean delete(String filePath) {File file = new File(filePath);if (file.isFile()) {file.delete();return true;}return false;}private static File getFile(String savePath, String originalFilename) {String fileName = System.currentTimeMillis() + "_" + originalFilename;File file = new File(savePath + fileName);if (file.exists()) {return getFile(savePath, originalFilename);}return file;}
}

CommonUtil.java

package com.foreknow.util;import java.util.UUID;/*** 共通工具类.*/
public class CommonUtil {/*** 方法描述:判断一个字符串是否为null或空字符串(被trim后为空字符串的也算)。* * @param str*            需要判断的字符串* @return false:不是空字符串,true:是空字符串*/public static boolean isEmpty(String str) {if (str == null || "".equals(str.trim())) {return true;}return false;}/*** 生成指定位数的随机整数* * @param number*            位数* @return 随机整数*/public static int random(int number) {return (int) ((Math.random() * 9 + 1) * Math.pow(10, number - 1));}/*** 获取UUID* * @return UUID*/public static String getUUID() {return UUID.randomUUID().toString().replace("-", "");}//    /**
//   * 判断session中存放的动作dto列表中是否包含指定的url
//   * @param session
//   * @param url
//   * @param method http动作
//   * @return true:包含,false:不包含
//   */
//  public static boolean contains(HttpSession session,String url,String method) {//      Object obj = session.getAttribute(SessionKeyConst.ACTION_INFO);
//      if(obj != null) {//          @SuppressWarnings("unchecked")
//          List<ActionDto> dtoList = (List<ActionDto>)obj;
//          for(ActionDto actionDto : dtoList) {//              if(!isEmpty(actionDto.getMethod()) && !actionDto.getMethod().equals(method)) {//                  continue;
//              }
//              if(!url.matches(actionDto.getUrl())) {//                  continue;
//              }
//              return true;
//          }
//      }
//      return false;
//  }
}

然后在bean包下 创建BaseBean.java 专门给分页使用 让Ad也继承这个类 因为只要是查询就涉及分页 就是查询需要分页 别的不需要分页 所以创建一个

##让其每一个bean 都继承BaseBean.java

package com.foreknow.bean;import com.foreknow.util.Page;/*** 分页的基础bean* @author ttc**/
public class BaseBean {//引入工具类 Page的接口private Page page;public BaseBean() {this.page = new Page();}public Page getPage() {return page;}public void setPage(Page page) {this.page = page;}
}

然后 实现 我们的自定义拦截器 mybatis

com.foreknow.dao.interceptor包下 PageInterceptor.java

package com.foreknow.dao.interceptor;import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Properties;import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.reflection.DefaultReflectorFactory;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;import com.foreknow.bean.BaseBean;
import com.foreknow.util.Page;/*** 自定义拦截器* 获取的Mybatis的Statement是在StatementHandler这个对象中进行的  所以我们 * type=StatementHandler.class* method="prepare"    实现接口的 prepare 方法* @Intercepts:标识当前的类是一个拦截器* @Signature(type=StatementHandler.class,method="prepare",args={Connection.class})* 它标记了当前的拦截器只会拦截StatementHandler接口中的prepare方法,因为这个方法的的参数是Connection类型的,* 所以获取到这个方法    传参数需要使用args={Connection.class}指定参数的类型* @author ttc**/@Intercepts({@Signature(type=StatementHandler.class,method="prepare",args={Connection.class})})
public class PageInterceptor implements Interceptor {public Object intercept(Invocation invocation) throws Throwable {// 获取目标对象StatementHandler statementHandler = (StatementHandler) invocation.getTarget();// 获取到元数据对象,从这个对象中可以通过其中的方法获取到我们要处理(拦截)的操作MetaObject metaObject = MetaObject.forObject(statementHandler, SystemMetaObject.DEFAULT_OBJECT_FACTORY,SystemMetaObject.DEFAULT_OBJECT_WRAPPER_FACTORY, new DefaultReflectorFactory());// 根据KEY获取到映射对象MappedStatement---------------AdDao.xmlMappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");// 获取到要AdDao.xml里的ID拦截操作的IDString id = mappedStatement.getId();
//一般uerdao.xml中  分页都是后面带ByPage的  所以下面判断一下if (id.endsWith("ByPage")) {BoundSql boundSql = statementHandler.getBoundSql();// 获取到Mapper.xml中的SQLString sql = boundSql.getSql();// 计算总的记录数    t是别名String countSql = "select count(*) from(" + sql + ")t";// 获取到Statement prepare(Connection connection)Connection conn = (Connection) invocation.getArgs()[0];PreparedStatement statement = conn.prepareStatement(countSql);// 通过代理获取到ParameterHandler对象,目的是要将?替换为具体值ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");parameterHandler.setParameters(statement);// JDBC的执行查询ResultSet rs = statement.executeQuery();BaseBean bean = (BaseBean) boundSql.getParameterObject();Page page = bean.getPage();if (rs.next()) {page.setTotalNumber(rs.getInt(1));}// 通过上面的分析分页的格式:// select * from table limit (start-1)*limit,limit;// 其中start是页码,limit是每页显示的条数。String pageSql = sql + " limit "+(page.getCurrentPage()-1)*page.getPageNumber()+","+page.getPageNumber();//重写分页的SQL  因为以前的  adDAO.xml里的sql不带分页  所以要重写  delegate.boundSql.sql  就这么写  写死的metaObject.setValue("delegate.boundSql.sql", pageSql);}//将执行权交给下一个拦截器return invocation.proceed();}public Object plugin(Object target) {// TODO Auto-generated method stubreturn Plugin.wrap(target, this);}public void setProperties(Properties properties) {// TODO Auto-generated method stub}}

##分页的步骤:
首先自己定义的拦截器

  • 列表第一项1.通过MappedStatement 里的方法 获取adDao.xml 依赖注入里的id
  • 列表第一项2.因为id有多个 判断一下 page结尾的id
  • 列表第一项3.获取到sql 后 记录总记录数
  • 列表第一项4.对JDBC的操作 设置connection 参数后 执行查询
  • 列表第一项5. 拼SQL
  • 列表第一项6.重写SQL
  • 列表第一项7.如果有下个拦截器 交给下一个 如果没有 就交给conntroller处理

然后在JSP中建一个自定义标签文件 tags

对应依赖的库 tag 复制到pom.xml中

#####定义一个自定义标签tag 在WEB-INF 下

<%@ tag language="java" pageEncoding="utf-8"%><!-- 获取页面的一些信息    引用一下
Page" name="page" 页数  和总记录数
获取属性 用attribute    --><%@ attribute type="com.foreknow.util.Page" name="page" required="true"%>
<%@ attribute type="java.lang.String" name="jsMethodName" required="true"%>
<script type="text/javascript">/* 传一个当前的页码 参数 */function transCurrenPage(currentPage) {var rule = /^[0-9]*[1-9][0-9]*$/if(!rule.test(currentPage)) {currentPage = 1;}eval("${jsMethodName}(currentPage)");}
</script>
<div class="page fix"><a href="javascript:transCurrenPage('1')" class="first">首页</a><a href="javascript:transCurrenPage('${page.currentPage-1}')" class="pre">上一页</a>当前第<span>${page.currentPage}/${page.totalPage}</span>页<a href="javascript:transCurrenPage('${page.currentPage+1}')" class="next">下一页</a><a href="javascript:transCurrenPage('${page.totalPage}')" class="last">末页</a>跳转&nbsp;<input type="text" id="currentPageText" value="1" class="allInput w28">&nbsp;页 &nbsp;<a href="javascript:transCurrenPage($('#currentPageText').val())" class="go">GO</a>
</div>

如果不想鼠标放上去 就显示url 为了网页的安全 可以写js

#####问题1:

引用的<%@ attribute type=“java.lang.String” name=“jsMethodName” required=“true”%> 什么意思?

解答:我们引用的是这个自定义的标签 那么 我们就应该把自定义标签定义一个名字
ame=“jsMethodName
#####问题2:
function transCurrenPage(currentPage) {
var rule = /1[1-9][0-9]/if(!rule.test(currentPage))currentPage=1;eval(&quot;/ if(!rule.test(currentPage)) { currentPage = 1; } eval(&quot;/if(!rule.test(currentPage))currentPage=1;eval("{jsMethodName}(currentPage)”);
}

解答: 这里我们运用的是一个正则表达式 判断一下 如果不符合这个规则 那么当前
当前页显示的是第一页

eval("${jsMethodName}(currentPage)");

意思说通过方法eval 把实际点击的这个当前页数传到自定义标签上 来解析这个jsMethodName 对应的JS 方法 search

adList.js

//显示信息
$(function(){common.showMessage($("#message").val())
})
//这个方法什么时候调用?
function search(currentPage){$("#currentPage").val(currentPage);$("#mainForm").submit();
}

这个#currentPage 定义的在JSP页面中的ID 对应的隐藏域 value 对应的是1页 也就说 默认是从第一页开始的 , 让后id=mainForm 是action里的 表单提交

adList.jsp

<%@ page language="java" contentType="text/html; charset=utf-8" pageEncoding="utf-8" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@ taglib prefix="pager" tagdir="/WEB-INF/tags/" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"/><meta http-equiv="X-UA-Compatible" content="IE=9; IE=8; IE=7; IE=EDGE"/><title></title><link rel="stylesheet" type="text/css" href="${basePath}/css/all.css"/><link rel="stylesheet" type="text/css" href="${basePath}/css/pop.css"/><link rel="stylesheet" type="text/css" href="${basePath}/css/main.css"/><script type="text/javascript" src="${basePath}/js/common/jquery-1.8.3.js"></script><script type="text/javascript" src="${basePath}/js/common/common.js"></script><script type="text/javascript" src="${basePath}/js/content/adList.js"></script>
</head><body style="background: #e1e9eb;">
<form action="${basePath}/ad/search" id="mainForm" method="post"><input type="hidden" id="id" name="id"/><input type="hidden" id="message" value="${pageCode.msg}"/><input type="hidden" id="basePath" value="${basePath}"/><input type="hidden" name="page.currentPage" id="currentPage" value="1"/><div class="right"><div class="current">当前位置:<a href="#">内容管理</a> &gt; 广告管理</div><div class="rightCont"><p class="g_title fix">广告列表</p><table class="tab1"><tbody><tr><td align="right" width="80">标题:</td><td><input name="title" id="title" value="" class="allInput" type="text"/></td><td style="text-align: right;" width="150"><input class="tabSub" value="查询" onclick="search('1');" type="button"/>&nbsp;&nbsp;&nbsp;&nbsp;<%--<t:auth url="/ad/addInit">--%><input class="tabSub" value="添加" onclick="location.href='${basePath}/ad/addInit'" type="button"/><%--</t:auth>--%></td></tr></tbody></table><div class="zixun fix"><table class="tab2" width="100%"><tbody><tr><th>序号</th><th>标题</th><th>链接地址</th><th>操作</th></tr><c:forEach items="${list}" var="item" varStatus="s"><tr><td>${s.index+1}</td><td>${item.title}</td><td>${item.link}</td><td><%--<t:auth url="/ad/modifyInit">--%><a href="javascript:void(0);" onclick="">修改</a>&nbsp;&nbsp;&nbsp;&nbsp;<%--</t:auth>--%><%--<t:auth url="/ad/remove">--%><a href="javascript:void(0);" onclick="">删除</a><%--</t:auth>--%></td></tr></c:forEach></tbody></table><pager:page jsMethodName="search" page="${searchParam.page}"></pager:page></div></div></div>
</form>
</body>
</html>

其中
引用一下这个page
<%@ taglib prefix=“pager” tagdir="/WEB-INF/tags/" %>

就是引用的分页
<pager:page jsMethodName=“search” page="${searchParam.page}"></pager:page>

问题3
jsMethodName=“search” page="${searchParam.page} 是什么意思?
解答:因为在自定义标签中 有两个参数

所以 在jsMethodName=“search” 让他调用JS 函数提交
第二: searchParam是控制器的addAttribute Map集合里的Key

adAdd.js

adList.js

所以 这就实现了分页的功能


  1. 0-9 ↩︎

SSM框架-实现Mybatis分页功能-foreknow_cms相关推荐

  1. Mybatis分页功能 pagehelper插件

    Mybatis分页功能 pagehelper插件 创建数据数据 use ssm; create table student (id int auto_incrementprimary key,name ...

  2. JavaWeb学习之路——SSM框架之Mybatis(三)

    数据库配置和相关类创建看上篇:JavaWeb学习之路--SSM框架之Mybatis(二) https://blog.csdn.net/kuishao1314aa/article/details/832 ...

  3. SSM框架——使用MyBatis Generator自动创建代码

    SSM框架--使用MyBatis Generator自动创建代码 这是通过命令行, 不用ide插件. 若在IDEA中通过插件generator, 还可以参考另一篇: IDEA搭建Spring+Spri ...

  4. php tp框架分页源代码,ThinkPHP3.2框架自带分页功能实现方法示例

    本文实例讲述了ThinkPHP3.2框架自带分页功能实现方法.分享给大家供大家参考,具体如下: 1.前端-分页代码: {$page} 2.创建分页样式:如page.css 并将以下代码复制到该文件中 ...

  5. SpringBoot 集成FluentMyBatis 框架之集成分页功能

    本文基于上一篇:SpringBoot 集成FluentMyBatis 框架之完善 SpringBoot 集成FluentMyBatis 框架之集成分页功能 FluentMyBatis 官方分页 官方提 ...

  6. 转:mybatis - 分页功能

    本文转自http://www.cnblogs.com/jcli/archive/2011/08/09/2132222.html mybatis高级应用系列一:分页功能 Mybatis3.0出来已有段时 ...

  7. SSM框架实现登录注册功能

    刚刚写出来的SSM登录注册案例,网上随便翻一下都有 ,本篇直接上手,使用Maven工程搭建一个简单的SSM框架实现简单的登录注册,验证重名功能. 目录 项目结构图 持久层相关配置文件 applicat ...

  8. ssm框架解读oracle,分页查询显示action的笔记SSM框架分页oracle数据库

    SSM框架简单分页 分页类代码分页的例1 package http://www.doczj.com/doc/db3d98ab69eae009591bec1b.htmlmon.dto; public c ...

  9. SSM框架-使用MyBatis Generator自动创建代码

    参考:http://blog.csdn.net/zhshulin/article/details/23912615 SSM搭建的时候用到MyBatis的代码自动生成的功能,由于MyBatis属于一种半 ...

最新文章

  1. vivado----fpga硬件调试 (五) ----找不到ila核问题及解决
  2. win7配置Eclipse+Cocos2dx+android开发环境
  3. 数据结构-栈详解(类C语言版)
  4. 只需5分钟即可启动并运行分层架构:: Spring Boot第1部分
  5. 前端网页广告无线翻滚_从小白到web前端工程师进阶之路 从0到1到更深
  6. mysql mac版本_mysql的安装、启动和基础配置 —— mac版本
  7. 【特别版】考证与学习,结构与功能,之间的因果关系
  8. 计算机专业学生,大三了找技术岗,怎么写一份好简历?内附269份简历模板
  9. 高通平台fastboot下载
  10. 维生素D与肠道菌群的互作
  11. java实现dde服务端,快速开启dde服务端
  12. win10安装PHP环境
  13. 吕 思 伟 ---- 潘 爱 民 :: ATL 介 绍( 二 )
  14. Sieve of Eratosthenes(埃拉托色尼筛选法)——C++实现
  15. 如何降低计算机版本,如何在win7系统电脑中将IE浏览器的版本降低
  16. 段永平抄底腾讯:高手不是最完美的,而是最淡定的
  17. python 作业3
  18. phpnow切换php,PHPNOW如何升级PHP
  19. 从浏览器跳转到前端框架的路由实现
  20. opencv在vs2015中 找不到opencv_world400d.dll的问题

热门文章

  1. Star-shaped polygon
  2. 大数据分析平台搭建方式有哪些
  3. 解析mysqlbinlog日志_关于mysql-binlog日志解析框架
  4. hikari如何切换数据源_spring boot+mybatis 多数据源切换(实例讲解)
  5. win7录屏_学用系列|清晰、体积小,这些录屏工具适合正在为录屏苦恼的你
  6. 三门问题的MonteCarlo仿真方法
  7. c语言代码re通常什么错误,求帮助 C语言realloc和free触发断点的问题
  8. html圆如何找到垂直中心线,一种用于找中心线及圆心的装置的制作方法
  9. c语言取字节高四位低四位,C语言取一个数的最高位
  10. 大数据面试官别再问闭包了