2017/2/22 基于SpringMVC和Mybatis的分页实现(1)

来源:互联网 发布:人工智能假肢多少钱 编辑:程序博客网 时间:2024/06/15 12:58
工具类:
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
原创粉丝点击