mybatis 分页插件
来源:互联网 发布:java api接口签名验证 编辑:程序博客网 时间:2024/06/05 07:25
package org.gjl.interceptor;import org.apache.ibatis.executor.parameter.ParameterHandler;import org.apache.ibatis.executor.statement.StatementHandler;import org.apache.ibatis.io.Resources;import org.apache.ibatis.mapping.BoundSql;import org.apache.ibatis.mapping.MappedStatement;import org.apache.ibatis.plugin.*;import org.apache.ibatis.reflection.MetaObject;import org.apache.ibatis.reflection.SystemMetaObject;import org.apache.ibatis.scripting.defaults.DefaultParameterHandler;import org.apache.ibatis.session.Configuration;import org.gjl.vo.Parameters;import java.beans.IntrospectionException;import java.beans.PropertyDescriptor;import java.lang.reflect.Field;import java.lang.reflect.InvocationTargetException;import java.lang.reflect.Method;import java.sql.Connection;import java.sql.PreparedStatement;import java.sql.ResultSet;import java.sql.SQLException;import java.util.Iterator;import java.util.Map;import java.util.Properties;import java.util.Set;/** * @Author GJL * @Desription * @Date 2017/12/6 * @Modified By: **/@Intercepts({@Signature(type = StatementHandler.class,method = "prepare",args = {Connection.class,Integer.class})})public class MyInterceptor implements Interceptor{ private Integer defaultPage; private Integer defaultPageSize; private Boolean defaultUseFlag; private Boolean defaultCheckFlag; private Boolean defaultCleanOyderBy; public Object intercept(Invocation invocation) throws Throwable { StatementHandler stmtHandler = (StatementHandler)getUnproxyObject(invocation.getTarget()); MetaObject metaStatementHandler = SystemMetaObject.forObject(stmtHandler); String sql = (String)metaStatementHandler.getValue("delegate.boundSql.sql"); //mappedStatement 保存了一个映射器节点的内容 包含 我们配置的sql id 缓存信息 jdbcType javaType ResultType // ParameterType等重要内容 还有SqlSource 接口 该接口有多中实现 ,getBoundSql(ParameterObject)是他的方法。 MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement"); if(!checkSeleck(sql)){ invocation.proceed(); } BoundSql boundSql = (BoundSql) metaStatementHandler.getValue("delegate.boundSql"); Object parameterObject = boundSql.getParameterObject(); //获取到参数 Parameters pageParams = getPageParamsFromParamObj(parameterObject); if(pageParams == null){ return invocation.proceed(); } //若不使用插件 则直接返回 Boolean useFlag = pageParams.getUseFlag() == null?this.defaultUseFlag:pageParams.getUseFlag(); if(!useFlag){ return invocation.proceed(); } //获取相关配置的参数 Integer currentPage = pageParams.getCurrentPage() == null?this.defaultPage:pageParams.getCurrentPage(); Integer pageSize = pageParams.getPageSize() == null ?this.defaultPageSize:pageParams.getPageSize(); Boolean cleanOrderBy = pageParams.getCleanOrderBy() == null ?this.defaultCleanOyderBy:pageParams.getCleanOrderBy(); Boolean checkFlag = pageParams.getCheckFlag() == null ?this.defaultCheckFlag:pageParams.getCheckFlag(); //计算总条数 int total = getTotal(invocation,metaStatementHandler,boundSql,cleanOrderBy); //回填总条数到页面参数 pageParams.setTotal(total); //计算总页数 int totalPage = total%pageSize == 0 ? total/pageSize : total/pageSize+1; //回填总页数到分页参数 pageParams.setTotalPage(totalPage); //检查当前页码的有效性 checkPage(checkFlag,currentPage,totalPage); //修改sql return prepareSQl(invocation,metaStatementHandler,boundSql,currentPage,pageSize); } private Object prepareSQl(Invocation invocation, MetaObject metaStatementHandler, BoundSql boundSql, Integer currentPage, Integer pageSize) throws InvocationTargetException, IllegalAccessException, SQLException { String sql = boundSql.getSql(); String newSql = "select * from ("+sql+") $_paging_table limit ?,?"; metaStatementHandler.setValue("delegate.boundSql.sql",newSql); Object statementObj = invocation.proceed(); this.preparePageDataParams((PreparedStatement)statementObj,currentPage,pageSize); return statementObj; } private void preparePageDataParams(PreparedStatement preparedStatement, Integer currentPage, Integer pageSize) throws SQLException { int idx = preparedStatement.getParameterMetaData().getParameterCount(); preparedStatement.setInt(idx-1,(currentPage-1)*pageSize); preparedStatement.setInt(idx,pageSize); } private void checkPage(Boolean checkFlag, Integer currentPage, int totalPage) throws Exception { if(checkFlag){ if(currentPage>totalPage){ throw new Exception("查询失败【"+currentPage+"】大于总页数"+"【"+totalPage+"】!!"); } } } private int getTotal(Invocation ivt, MetaObject metaStatementHandler, BoundSql boundSql, Boolean cleanOrderBy) { //获取当前的MappedStatement MappedStatement mappedStatement = (MappedStatement) metaStatementHandler.getValue("delegate.mappedStatement"); //配置对象 Configuration cfg = mappedStatement.getConfiguration(); //当前需要执行的sql String sql = (String)metaStatementHandler.getValue("delegate.boundSql.sql"); //去掉最后的clearOrderBy sql = cleanOrderByForSql(sql); //改写为统计总数的sql语句 String countSql = "select count(*) as total from ("+sql+") $_paging"; Connection connection = (Connection) ivt.getArgs()[0]; PreparedStatement ps = null; int total =0; try { ps = connection.prepareStatement(countSql); BoundSql countBoundSql = new BoundSql(cfg,countSql,boundSql.getParameterMappings(),boundSql.getParameterObject()); ParameterHandler handler = new DefaultParameterHandler(mappedStatement,boundSql.getParameterObject(),countBoundSql); handler.setParameters(ps); ResultSet rs = ps.executeQuery(); while(rs.next()){ total = rs.getInt("total"); } } catch (SQLException e) { e.printStackTrace(); }finally { if(ps !=null){ try { ps.close(); } catch (SQLException e) { e.printStackTrace(); } } } return total; } private String cleanOrderByForSql(String sql) { StringBuilder sb = new StringBuilder(sql); String newSql = sql.toLowerCase(); int index = newSql.lastIndexOf("order"); if(index == -1){ return sql; } return sb.substring(0,index); } private Parameters getPageParamsFromParamObj(Object parameterObject) { Parameters parameters = null; if(parameterObject == null){ return null; } if(parameterObject instanceof Map){ Map<String,Object> paramMap = (Map<String,Object>) parameterObject; Set<String> keySet = paramMap.keySet(); Iterator<String> iterator = keySet.iterator(); while(iterator.hasNext()){ String key = iterator.next(); Object value = paramMap.get(key); if(value instanceof Parameters){ return (Parameters) value; } } }else if(parameterObject instanceof Parameters){ return (Parameters)parameterObject; }else{ Field[] fields = parameterObject.getClass().getDeclaredFields(); for(Field field :fields){ if(field.getType() == Parameters.class){ try { PropertyDescriptor pd = new PropertyDescriptor(field.getName(),parameterObject.getClass()); Method method = pd.getReadMethod(); return (Parameters) method.invoke(parameterObject); } catch (IntrospectionException e) { e.printStackTrace(); } catch (IllegalAccessException e) { e.printStackTrace(); } catch (InvocationTargetException e) { e.printStackTrace(); } } } } return parameters; } private boolean checkSeleck(String sql) { String trimSql = sql.trim(); int index = trimSql.indexOf("select"); return index == 0; } private Object getUnproxyObject(Object target) { MetaObject metaObject = SystemMetaObject.forObject(target); Object object = null; while(metaObject.hasGetter("h")){ object = metaObject.getValue("h"); metaObject = SystemMetaObject.forObject(object); } if(object == null){ return target; } return object; } public Object plugin(Object target) { return Plugin.wrap(target,this); } //设置插件配置参数 public void setProperties(Properties properties) { String strDefaultPage = properties.getProperty("default.page","1"); String strDefaultPageSize = properties.getProperty("default.pageSize","50"); String strDefaultUseFlag = properties.getProperty("default.useFlag","false"); String strDefaultCheckFlag = properties.getProperty("default.checkFlag","false"); String strDefaultCleanOrderBy = properties.getProperty("default.cleanOrderBy","false"); this.defaultPage = Integer.parseInt(strDefaultPage); this.defaultPageSize = Integer.parseInt(strDefaultPageSize); this.defaultCheckFlag = Boolean.parseBoolean(strDefaultCheckFlag); this.defaultUseFlag = Boolean.parseBoolean(strDefaultUseFlag); this.defaultCleanOyderBy = Boolean.parseBoolean(strDefaultCleanOrderBy); }}
阅读全文
0 0
- mybatis分页/分页插件
- mybatis分页插件(物理分页)
- mybatis分页插件实现分页
- Mybatis分页插件
- Mybatis分页插件 - 示例
- Mybatis分页插件更新
- mybatis generator 分页插件
- Mybatis分页插件更新
- Mybatis分页插件 - 示例
- MyBatis分页插件
- Mybatis分页插件更新
- Mybatis一个分页插件
- mybatis 分页插件
- mybatis分页插件
- [Mybatis]分页(基于插件)
- 自定义mybatis分页插件
- mybatis分页插件
- mybatis分页插件
- 第十五周 项目3-归并排序算法的改进
- js普通文本转富文本
- appium在Javaweb项目的搭建
- 草根seo站长增加收入的实用方法
- Pickle:UnicodeDecodeError: 'utf-8' codec can't decode byte 0x80 in position 0: invalid start byte
- mybatis 分页插件
- 团体程序设计天梯赛-练习集 L1-046. 整除光棍
- 开发一个基于React Native的简易demo--读取网络数据并展示
- DSP开发的一点概念
- Servlet中不用sping注入原因和解释
- Samba案例
- 单向队列和优先级队列
- 关于dedecms后台控制常用操作错位解决办法
- 用共享内存读写数据