2017/2/22 基于SpringMVC和Mybatis的分页实现(1)
来源:互联网 发布:人工智能假肢多少钱 编辑:程序博客网 时间:2024/06/15 12:58
工具类:
分页专用类:
配置mybatis-config.xml
import java.io.*;import java.text.ParseException;import java.text.SimpleDateFormat;import java.util.Date;import java.util.Random;import java.util.regex.Matcher;import java.util.regex.Pattern;public class Tools {/** * 检测字符串是否不为空(null,"","null") * @param s * @return 不为空则返回true,否则返回false */public static boolean notEmpty(String s){return s!=null && !"".equals(s) && !"null".equals(s);}/** * 检测字符串是否为空(null,"","null") * @param s * @return 为空则返回true,不否则返回false */public static boolean isEmpty(String s){return s==null || "".equals(s) || "null".equals(s);}}反射工具:
import java.lang.reflect.Field;/** *反射工具 */public class ReflectHelper {/** * 获取obj对象fieldName的Field * @param obj * @param fieldName * @return */public static Field getFieldByFieldName(Object obj, String fieldName) {for (Class<?> superClass = obj.getClass(); superClass != Object.class; superClass = superClass.getSuperclass()) {try {return superClass.getDeclaredField(fieldName);} catch (NoSuchFieldException e) {}}return null;}/** * 获取obj对象fieldName的属性值 * @param obj * @param fieldName * @return * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException */public static Object getValueByFieldName(Object obj, String fieldName)throws SecurityException, NoSuchFieldException,IllegalArgumentException, IllegalAccessException {Field field = getFieldByFieldName(obj, fieldName);Object value = null;if(field!=null){if (field.isAccessible()) {value = field.get(obj);} else {field.setAccessible(true);value = field.get(obj);field.setAccessible(false);}}return value;}/** * 设置obj对象fieldName的属性值 * @param obj * @param fieldName * @param value * @throws SecurityException * @throws NoSuchFieldException * @throws IllegalArgumentException * @throws IllegalAccessException */public static void setValueByFieldName(Object obj, String fieldName,Object value) throws SecurityException, NoSuchFieldException,IllegalArgumentException, IllegalAccessException {Field field = obj.getClass().getDeclaredField(fieldName);if (field.isAccessible()) {field.set(obj, value);} else {field.setAccessible(true);field.set(obj, value);field.setAccessible(false);}}}
分页拦截器:
import org.apache.ibatis.executor.ErrorContext;import org.apache.ibatis.executor.ExecutorException;import org.apache.ibatis.executor.statement.BaseStatementHandler;import org.apache.ibatis.executor.statement.RoutingStatementHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.mapping.ParameterMapping;import org.apache.ibatis.mapping.ParameterMode;import org.apache.ibatis.plugin.*;import org.apache.ibatis.reflection.MetaObject;import org.apache.ibatis.reflection.property.PropertyTokenizer;import org.apache.ibatis.scripting.xmltags.ForEachSqlNode;import org.apache.ibatis.session.Configuration;import org.apache.ibatis.type.TypeHandler;import org.apache.ibatis.type.TypeHandlerRegistry;import javax.xml.bind.PropertyException;import java.lang.reflect.Field;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.List;import java.util.Properties;/** * Created by Spring on 2017/2/22. * qq:457540867 * 对应Mybatis3.4.0之后的版本(包括3.4.0) * 3.4.0之前的版本修改intercepts为@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class})}) */@Intercepts({@Signature(type = StatementHandler.class, method = "prepare", args = {Connection.class, Integer.class})})public class PagePlugin implements Interceptor { private static String dialect = ""; //数据库方言 private static String pageSqlId = ""; //mapper.xml中需要拦截的ID(正则匹配) public Object intercept(Invocation ivk) throws Throwable { // TODO Auto-generated method stub if (ivk.getTarget() instanceof RoutingStatementHandler) { RoutingStatementHandler statementHandler = (RoutingStatementHandler) ivk.getTarget(); BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler, "delegate"); MappedStatement mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate, "mappedStatement"); if (mappedStatement.getId().matches(pageSqlId)) { //拦截需要分页的SQL BoundSql boundSql = delegate.getBoundSql(); Object parameterObject = boundSql.getParameterObject();//分页SQL<select>中parameterType属性对应的实体参数,即Mapper接口中执行分页方法的参数,该参数不得为空 if (parameterObject == null) { throw new NullPointerException("parameterObject尚未实例化!"); } else { Connection connection = (Connection) ivk.getArgs()[0]; String sql = boundSql.getSql(); //String countSql = "select count(0) from (" + sql+ ") as tmp_count"; //记录统计 String countSql = "select count(0) from (" + sql + ") tmp_count"; //记录统计 == oracle 加 as 报错(SQL command not properly ended) PreparedStatement countStmt = connection.prepareStatement(countSql); BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), parameterObject); setParameters(countStmt, mappedStatement, countBS, parameterObject); ResultSet rs = countStmt.executeQuery(); int count = 0; if (rs.next()) { count = rs.getInt(1); } rs.close(); countStmt.close(); //System.out.println(count); Page page = null; if (parameterObject instanceof Page) { //参数就是Page实体 page = (Page) parameterObject; page.setEntityOrField(true); page.setTotalResult(count); } else { //参数为某个实体,该实体拥有Page属性 Field pageField = ReflectHelper.getFieldByFieldName(parameterObject, "page"); if (pageField != null) { page = (Page) ReflectHelper.getValueByFieldName(parameterObject, "page"); if (page == null) page = new Page(); page.setEntityOrField(false); page.setTotalResult(count); ReflectHelper.setValueByFieldName(parameterObject, "page", page); //通过反射,对实体对象设置分页对象 } else { throw new NoSuchFieldException(parameterObject.getClass().getName() + "不存在 page 属性!"); } } String pageSql = generatePageSql(sql, page); ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql); //将分页sql语句反射回BoundSql. } } } return ivk.proceed(); } /** * 对SQL参数(?)设值,参考org.apache.ibatis.executor.parameter.DefaultParameterHandler * * @param ps * @param mappedStatement * @param boundSql * @param parameterObject * @throws SQLException */ private void setParameters(PreparedStatement ps, MappedStatement mappedStatement, BoundSql boundSql, Object parameterObject) throws SQLException { ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId()); List<ParameterMapping> parameterMappings = boundSql.getParameterMappings(); if (parameterMappings != null) { Configuration configuration = mappedStatement.getConfiguration(); TypeHandlerRegistry typeHandlerRegistry = configuration.getTypeHandlerRegistry(); MetaObject metaObject = parameterObject == null ? null : configuration.newMetaObject(parameterObject); for (int i = 0; i < parameterMappings.size(); i++) { ParameterMapping parameterMapping = parameterMappings.get(i); if (parameterMapping.getMode() != ParameterMode.OUT) { Object value; String propertyName = parameterMapping.getProperty(); PropertyTokenizer prop = new PropertyTokenizer(propertyName); if (parameterObject == null) { value = null; } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) { value = parameterObject; } else if (boundSql.hasAdditionalParameter(propertyName)) { value = boundSql.getAdditionalParameter(propertyName); } else if (propertyName.startsWith(ForEachSqlNode.ITEM_PREFIX) && boundSql.hasAdditionalParameter(prop.getName())) { value = boundSql.getAdditionalParameter(prop.getName()); if (value != null) { value = configuration.newMetaObject(value).getValue(propertyName.substring(prop.getName().length())); } } else { value = metaObject == null ? null : metaObject.getValue(propertyName); } TypeHandler typeHandler = parameterMapping.getTypeHandler(); if (typeHandler == null) { throw new ExecutorException("There was no TypeHandler found for parameter " + propertyName + " of statement " + mappedStatement.getId()); } typeHandler.setParameter(ps, i + 1, value, parameterMapping.getJdbcType()); } } } } /** * 根据数据库方言,生成特定的分页sql * * @param sql * @param page * @return */ private String generatePageSql(String sql, Page page) { if (page != null && Tools.notEmpty(dialect)) { StringBuffer pageSql = new StringBuffer(); if ("mysql".equals(dialect)) { pageSql.append(sql); pageSql.append(" limit " + page.getCurrentResult() + "," + page.getShowCount()); } else if ("oracle".equals(dialect)) { pageSql.append("select * from (select tmp_tb.*,ROWNUM row_id from ("); pageSql.append(sql); //pageSql.append(") as tmp_tb where ROWNUM<="); pageSql.append(") tmp_tb where ROWNUM<="); pageSql.append(page.getCurrentResult() + page.getShowCount()); pageSql.append(") where row_id>"); pageSql.append(page.getCurrentResult()); } return pageSql.toString(); } else { return sql; } } public Object plugin(Object arg0) { // TODO Auto-generated method stub return Plugin.wrap(arg0, this); } public void setProperties(Properties p) { dialect = p.getProperty("dialect"); if (Tools.isEmpty(dialect)) { try { throw new PropertyException("dialect property is not found!"); } catch (PropertyException e) { // TODO Auto-generated catch block e.printStackTrace(); } } pageSqlId = p.getProperty("pageSqlId"); if (Tools.isEmpty(pageSqlId)) { try { throw new PropertyException("pageSqlId property is not found!"); } catch (PropertyException e) { // TODO Auto-generated catch block e.printStackTrace(); } } }}
分页专用类:
public class Page {private int showCount; //每页显示记录数private int totalPage;//总页数private int totalResult;//总记录数private int currentPage;//当前页private int currentResult;//当前记录起始索引private boolean entityOrField;//true:需要分页的地方,传入的参数就是Page实体;false:需要分页的地方,传入的参数所代表的实体拥有Page属性private String pageStr;//最终页面显示的底部翻页导航,详细见:getPageStr();private PageData pd = new PageData();public Page(){try {this.showCount = Const.PAGE;} catch (Exception e) {this.showCount = 10;}}public int getTotalPage() {if(totalResult!=0){if(totalResult%showCount==0)totalPage = totalResult/showCount;elsetotalPage = totalResult/showCount+1;}else{totalPage=1;}return totalPage;}public void setTotalPage(int totalPage) {this.totalPage = totalPage;}public int getTotalResult() {return totalResult;}public void setTotalResult(int totalResult) {this.totalResult = totalResult;}public int getCurrentPage() {//if(currentPage<=0)//currentPage = 1;//if(currentPage>getTotalPage())//currentPage = getTotalPage();return currentPage;}public void setCurrentPage(int currentPage) {this.currentPage = currentPage;}public void setPageStr(String pageStr) { this.pageStr=pageStr;}public int getShowCount() {return showCount;}public void setShowCount(int showCount) {this.showCount = showCount;}public int getCurrentResult() {currentResult = (getCurrentPage()-1)*getShowCount();if(currentResult<0)currentResult = 0;return currentResult;}public void setCurrentResult(int currentResult) {this.currentResult = currentResult;}public boolean isEntityOrField() {return entityOrField;}public void setEntityOrField(boolean entityOrField) {this.entityOrField = entityOrField;}public PageData getPd() {return pd;}public void setPd(PageData pd) {this.pd = pd;}@Overridepublic int hashCode() {final int prime = 31;int result = 1;result = prime * result + currentPage;result = prime * result + currentResult;result = prime * result + (entityOrField ? 1231 : 1237);result = prime * result + ((pageStr == null) ? 0 : pageStr.hashCode());result = prime * result + ((pd == null) ? 0 : pd.hashCode());result = prime * result + showCount;result = prime * result + totalPage;result = prime * result + totalResult;return result;}@Overridepublic boolean equals(Object obj) {if (this == obj)return true;if (obj == null)return false;if (getClass() != obj.getClass())return false;Page other = (Page) obj;if (currentPage != other.currentPage)return false;if (currentResult != other.currentResult)return false;if (entityOrField != other.entityOrField)return false;if (pageStr == null) {if (other.pageStr != null)return false;} else if (!pageStr.equals(other.pageStr))return false;if (pd == null) {if (other.pd != null)return false;} else if (!pd.equals(other.pd))return false;if (showCount != other.showCount)return false;if (totalPage != other.totalPage)return false;if (totalResult != other.totalResult)return false;return true;}@Overridepublic String toString() {return "Page [showCount=" + showCount + ", totalPage=" + totalPage + ", totalResult=" + totalResult+ ", currentPage=" + currentPage + ", currentResult=" + currentResult + ", entityOrField="+ entityOrField + ", pageStr=" + pageStr + ", pd=" + pd + "]";}public String getPageStr(){return this.pageStr;}public static void PageStr(Page p){int lastPage =p.getTotalPage();int currentPage=p.getCurrentPage();if(lastPage==0){lastPage=1;//totalPage=1;currentPage=1;} StringBuilder sb=new StringBuilder("<ul class='pagination pagination-lg'>"); String s1=""; String s2=""; if(currentPage==1){ s1="disabled";//禁用上一页 } if(currentPage==lastPage||lastPage==0){ s2="disabled";//禁用下一页 } if(s1.equals("disabled")){ sb.append("<li class='"+s1+"'><a>«</a></li>"); }else{ sb.append("<li class='"+s1+"'><a onclick=\"toPage("+(currentPage-1)+")\" >«</a></li>"); } if(currentPage-1>=4){//前面至少4页 sb.append("<li><a onclick=\"toPage(1)\">1</a></li>");//第一页 sb.append("<li class=\""+"disabled"+"\"><span>...</span></li>");//省略号 if(currentPage==lastPage){//如果是最后一页 sb.append("<li><a onclick=\"toPage("+(currentPage-3)+")\" >"+(currentPage-3)+"</a></li>");//前三页 } sb.append("<li><a onclick=\"toPage("+(currentPage-2)+")\" >"+(currentPage-2)+"</a></li>");//前二页 sb.append("<li><a onclick=\"toPage("+(currentPage-1)+")\" >"+(currentPage-1)+"</a></li>");//前一页 }else { for(int i=1;i<currentPage;i++){ sb.append("<li><a onclick=\"toPage("+i+")\" >"+i+"</a></li>");//前面不超过4页把前面的都显示出来 } } sb.append("<li class=\"active\"><a onclick=\"toPage("+currentPage+")\" >"+currentPage+"</a></li>");//加上当前页码 if(lastPage-currentPage>=4){//后面至少4页 sb.append("<li><a onclick=\"toPage("+(currentPage+1)+")\">"+(currentPage+1)+"</a></li>");//后一页 sb.append("<li><a onclick=\"toPage("+(currentPage+2)+")\">"+(currentPage+2)+"</a></li>");//后二页 if(currentPage==1){//如果是第一页 sb.append("<li><a onclick=\"toPage("+(currentPage+3)+")\" >"+(currentPage+3)+"</a></li>");//第三页 } sb.append("<li class=\""+"disabled"+"\"><span>...</span></li>");//省略号 sb.append("<li><a onclick=\"toPage("+lastPage+")\" >"+lastPage+"</a></li>");//最后页 }else{ for(int i=currentPage+1;i<=lastPage;i++){ sb.append("<li><a onclick=\"toPage("+i+")\" >"+i+"</a></li>");//后面不超过4页把后面的都显示出来 } } if(s2.equals("disabled")){ sb.append("<li class='"+s2+"'><a>»</a></li>"); }else{ sb.append("<li class=\""+s2+"\"><a onclick=\"toPage("+(currentPage+1)+")\" >»</a></li>"); } sb.append("</ul>"); p.setPageStr(sb.toString());}}
public class Const {public static final Integer PAGE = 10;//分页条数配置路径}
配置mybatis-config.xml
<typeAliases><typeAlias type="com.chinook5.util.PageData" alias="pd" /><!-- 分页 --><typeAlias type="com.chinook5.util.Page" alias="page" /></typeAliases><plugins><plugin interceptor="com.chinook5.util.PagePlugin"><property name="dialect" value="mysql" /><property name="pageSqlId" value=".*ListPage.*" /></plugin></plugins>
pagedate.java:
import java.util.Collection;import java.util.Date;import java.util.HashMap;import java.util.Iterator;import java.util.Map;import java.util.Set;import javax.servlet.http.HttpServletRequest;public class PageData extends HashMap implements Map{private static final long serialVersionUID = 1L;Map map = null;HttpServletRequest request;public PageData(HttpServletRequest request){this.request = request;Map properties = request.getParameterMap();Map returnMap = new HashMap(); Iterator entries = properties.entrySet().iterator(); Entry entry;String name = ""; String value = ""; while (entries.hasNext()) {entry = (Entry) entries.next();name = (String) entry.getKey(); Object valueObj = entry.getValue(); if(null == valueObj){ value = ""; }else if(valueObj instanceof String[]){ String[] values = (String[])valueObj;for(int i=0;i<values.length;i++){ value = values[i] + ",";}value = value.substring(0, value.length()-1); }else{value = valueObj.toString(); }returnMap.put(name, value); }map = returnMap;}public PageData() {map = new HashMap();}@Overridepublic Object get(Object key) {Object obj = null;if(map.get(key) instanceof Object[]) {Object[] arr = (Object[])map.get(key);obj = request == null ? arr:(request.getParameter((String)key) == null ? arr:arr[0]);} else {obj = map.get(key);}return obj;}public Date getStringDate(String date){if(DateUtil.isValidDate(date)){return DateUtil.fomatDate(date);}else{return null;}}public Integer getInteger(Object key){return (Integer)key;}public String getString(Object key) {return (String)get(key);}@SuppressWarnings("unchecked")@Overridepublic Object put(Object key, Object value) {return map.put(key, value);}@Overridepublic Object remove(Object key) {return map.remove(key);}public void clear() {map.clear();}public boolean containsKey(Object key) {// TODO Auto-generated method stubreturn map.containsKey(key);}public boolean containsValue(Object value) {// TODO Auto-generated method stubreturn map.containsValue(value);}public Set entrySet() {// TODO Auto-generated method stubreturn map.entrySet();}public boolean isEmpty() {// TODO Auto-generated method stubreturn map.isEmpty();}public Set keySet() {// TODO Auto-generated method stubreturn map.keySet();}@SuppressWarnings("unchecked")public void putAll(Map t) {// TODO Auto-generated method stubmap.putAll(t);}public int size() {// TODO Auto-generated method stubreturn map.size();}public Collection values() {// TODO Auto-generated method stubreturn map.values();}}
0 0
- 2017/2/22 基于SpringMVC和Mybatis的分页实现(1)
- 2017/2/22 基于SpringMVC和Mybatis的分页实现(2)
- springmvc+Mybatis 分页查询的简单实现
- SpringMVC的mybatis分页
- 基于mybatis 自定义标签分页的实现
- 基于mybatis ajax 分页的实现
- SpringMVC+MyBatis+MySQL实现分页
- 基于maven,springmvc+mybatis+pagehepler分页配置
- Spring+SpringMVC+Mybatis+PageHelper+laypage+Ajax实现的分页
- 基于SpringMVC 和MyBatis的实现省份城市之间的动态切换
- springmvc+mybatis+mysql的分页的查询和显示
- springMVC、myBatis的物理分页和高级查询
- springMVC、myBatis的物理分页和高级查询
- MyBatis+springMVC+easyUI (dataGirl)实现分页
- SpringMVC+MyBatis分页插件简单实现
- SpringMVC+Mybatis+Oracle实现web分页
- Maven+Mybatis+Spring+SpringMVC实现分页
- spring+SpringMVC+Maven+Mybatis+Mysql分页实现
- 【Android】安卓开发之使用Gson和POST请求和服务器通信
- ViewPager+GridView实现商品分类.滑动点击效果(团购,商城都会用到)--binbinyang
- HTTPS配置入门:Nginx、Node.js配置HTTPS服务器
- Java线程中yield与join方法的区别
- 移动App该如何保存用户密码
- 2017/2/22 基于SpringMVC和Mybatis的分页实现(1)
- svn客户端的详细使用
- 微信小程序(事件处理)
- 初学JavaWeb需要知道的目录结构与配置
- HDU 1342 Lotto(DFS)
- 时间转换
- 树莓派FTP文件传输小记
- mybaits 多个参数传入用#{0,1,....}或者@Param注释
- Disruptor框架入门