美文网首页
Mybatis 分页插件源码

Mybatis 分页插件源码

作者: 往后余生9375 | 来源:发表于2020-02-27 10:12 被阅读0次
    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.Map;
    import java.util.Properties;
    import javax.xml.bind.PropertyException;
    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.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.MetaObject;
    import org.apache.ibatis.reflection.property.PropertyTokenizer;
    import org.apache.ibatis.session.Configuration;
    import org.apache.ibatis.type.TypeHandler;
    import org.apache.ibatis.type.TypeHandlerRegistry;
    
    @Intercepts({@Signature(
        type = StatementHandler.class,
        method = "prepare",
        args = {Connection.class}
    )})
    public class PagePlugin implements Interceptor {
        private static String dialect = "";
        private static String pageSqlId = ".*?Page*?";
    
        public PagePlugin() {
        }
    
        public Object intercept(Invocation ivk) throws Throwable {
            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)) {
                    BoundSql boundSql = delegate.getBoundSql();
                    Object parameterObject = boundSql.getParameterObject();
                    if (parameterObject == null) {
                        throw new NullPointerException("parameterObject error");
                    }
    
                    Connection connection = (Connection)ivk.getArgs()[0];
                    String sql = boundSql.getSql();
                    String countSql = "select count(0) from (" + sql + ") myCount";
                    PreparedStatement countStmt = connection.prepareStatement(countSql);
                    BoundSql countBS = new BoundSql(mappedStatement.getConfiguration(), countSql, boundSql.getParameterMappings(), parameterObject);
                    this.setParameters(countStmt, mappedStatement, countBS, parameterObject);
                    ResultSet rs = countStmt.executeQuery();
                    int count = 0;
                    if (rs.next()) {
                        count = rs.getInt(1);
                    }
    
                    rs.close();
                    countStmt.close();
                    Page page = null;
                    if (parameterObject instanceof Page) {
                        page = (Page)parameterObject;
                        page.setRecordsTotal(count);
                    } else if (parameterObject instanceof Map) {
                        Map<String, Object> map = (Map)parameterObject;
                        page = (Page)map.get("page");
                        if (page == null) {
                            page = new Page();
                        }
    
                        page.setRecordsTotal(count);
                        page.setRecordsFiltered(count);
                    } else {
                        Field pageField = ReflectHelper.getFieldByFieldName(parameterObject, "page");
                        if (pageField == null) {
                            throw new NoSuchFieldException(parameterObject.getClass().getName());
                        }
    
                        page = (Page)ReflectHelper.getValueByFieldName(parameterObject, "page");
                        if (page == null) {
                            page = new Page();
                        }
    
                        page.setRecordsTotal(count);
                        page.setRecordsFiltered(count);
                        ReflectHelper.setValueByFieldName(parameterObject, "page", page);
                    }
    
                    String pageSql = this.generatePageSql(sql, page);
                    ReflectHelper.setValueByFieldName(boundSql, "sql", pageSql);
                }
            }
    
            return ivk.proceed();
        }
    
        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 = (ParameterMapping)parameterMappings.get(i);
                    if (parameterMapping.getMode() != ParameterMode.OUT) {
                        String propertyName = parameterMapping.getProperty();
                        PropertyTokenizer prop = new PropertyTokenizer(propertyName);
                        Object value;
                        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("__frch_") && 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());
                    }
                }
            }
    
        }
    
        private String generatePageSql(String sql, Page page) {
            if (page != null && (dialect != null || !dialect.equals(""))) {
                StringBuffer pageSql = new StringBuffer();
                if ("mysql".equals(dialect)) {
                    pageSql.append(sql);
                    pageSql.append(" limit " + page.getStart() + "," + page.getLength());
                } else if ("oracle".equals(dialect)) {
                    pageSql.append("select * from (select tmp_tb.*,ROWNUM row_id from (");
                    pageSql.append(sql);
                    pageSql.append(")  tmp_tb where ROWNUM<=");
                    pageSql.append(page.getStart() + page.getLength());
                    pageSql.append(") where row_id>");
                    pageSql.append(page.getStart());
                }
    
                return pageSql.toString();
            } else {
                return sql;
            }
        }
    
        public Object plugin(Object arg0) {
            return Plugin.wrap(arg0, this);
        }
    
        public void setProperties(Properties p) {
            dialect = p.getProperty("dialect");
            if (dialect == null || dialect.equals("")) {
                try {
                    throw new PropertyException("dialect property is not found!");
                } catch (PropertyException var4) {
                    var4.printStackTrace();
                }
            }
    
            pageSqlId = p.getProperty("pageSqlId");
            if (dialect == null || dialect.equals("")) {
                try {
                    throw new PropertyException("pageSqlId property is not found!");
                } catch (PropertyException var3) {
                    var3.printStackTrace();
                }
            }
    
        }
    }
    
    

    工具类

    //
    // Source code recreated from a .class file by IntelliJ IDEA
    // (powered by Fernflower decompiler)
    //
    
    package com.sunnysoft.pageutil;
    
    import java.lang.reflect.Field;
    
    public class ReflectHelper {
        public ReflectHelper() {
        }
    
        public static Field getFieldByFieldName(Object obj, String fieldName) {
            Class superClass = obj.getClass();
    
            while(superClass != Object.class) {
                try {
                    return superClass.getDeclaredField(fieldName);
                } catch (NoSuchFieldException var4) {
                    superClass = superClass.getSuperclass();
                }
            }
    
            return null;
        }
    
        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;
        }
    
        public static void setValueByFieldName(Object obj, String fieldName, Object value) throws SecurityException, NoSuchFieldException, IllegalArgumentException, IllegalAccessException {
            Field field = null;
    
            try {
                field = obj.getClass().getDeclaredField(fieldName);
            } catch (Exception var5) {
                return;
            }
    
            if (field.isAccessible()) {
                field.set(obj, value);
            } else {
                field.setAccessible(true);
                field.set(obj, value);
                field.setAccessible(false);
            }
    
        }
    }
    
    

    Page对象

    @Data
    public class Page<E> implements Serializable {
        private int start;
        private int length;
        private int recordsFiltered;
        private int recordsTotal;
        private List<E> data = Collections.emptyList();
    }
    

    Vo (查询实体)

    @Data
    public class QueryVo extends Page<StudentDto>{
      private Integer studentId;
    }
    

    Dto(数据传输对象)

    public class StudentDto{
      private Integer studentId;
      private String name;
    private String address;
    private Integer classId;
    }
    

    Service 接口

    public interface IStudentService{
      Page<StudentDto> queryDataByPage(QueryVo queryVo);
    }
    

    ServiceImpl

     Page<StudentDto> queryDataByPage(QueryVo queryVo){
       List<StudentDto> list = xxx.queryList(queryVo);
      queryVo.getPage().setData(list);
     return queryVo.getPage();
    }
    

    相关文章

      网友评论

          本文标题:Mybatis 分页插件源码

          本文链接:https://www.haomeiwen.com/subject/rqqthhtx.html