MyBatis-plusページングプラグイン------筆者はページングプラグインの使用をお勧めしません

15773 ワード

MyBatis-plusページングプラグイン
  • 1、ページングオブジェクト
  • 2、ページングカード(実はブロック)
  • 3、反射工具
  • 4、配置(主にpluginsを参照)
  • 1、ページングオブジェクト
    package com.dsanjun.common.autopage;
    
    import java.io.Serializable;
    import java.util.List;
    
    /**
     *       
     * 
     * @author dyw
     * @date 2019 9 20 
     * @param 
     */
    public class AutoPage implements Serializable {
    	private static final long serialVersionUID = 2862962633786434439L;
    	/**
    	 *      ,  10 
    	 */
    	private int pageSize = 10; //        
    	/**
    	 *    ,     
    	 */
    	private int currentPage = 1; //    
    	/**
    	 *             ,      
    	 */
    	private int currentDBIndex;
    	/**
    	 *    
    	 */
    	private int totalPage;
    	/**
    	 *     
    	 */
    	private int totalCount;
    
    	/**
    	 *         
    	 */
    	private List records;
    
    	public List getRecords() {
    		return records;
    	}
    
    	public void setRecords(List records) {
    		this.records = records;
    	}
    
    	public int getTotalPage() {
    		if (totalCount % pageSize == 0) {
    			totalPage = totalCount / pageSize;
    		} else {
    			totalPage = totalCount / pageSize + 1;
    		}
    		return totalPage;
    	}
    
    	public int getCurrentPage() {
    		if (currentPage <= 0) {
    			currentPage = 1;
    		}
    		if (currentPage > getTotalPage()) {
    			currentPage = getTotalPage();
    		}
    		return currentPage;
    	}
    
    	public void setCurrentPage(int currentPage) {
    		this.currentPage = currentPage;
    	}
    
    	public int getPageSize() {
    		return pageSize;
    	}
    
    	public void setPageSize(int pageSize) {
    		this.pageSize = pageSize;
    	}
    
    	public int getCurrentDBIndex() {
    		currentDBIndex = (getCurrentPage() - 1) * getCurrentPage();
    		return currentDBIndex;
    	}
    
    	public int getTotalCount() {
    		return totalCount;
    	}
    
    	public void setTotalCount(int totalCount) {
    		this.totalCount = totalCount;
    	}
    }
    

    2、ページングカード(実はブロック)
    package com.dsanjun.common.autopage;
    
    import java.sql.Connection;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.util.List;
    import java.util.Properties;
    import javax.xml.bind.PropertyException;
    import org.apache.ibatis.binding.MapperMethod.ParamMap;
    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.scripting.xmltags.ForEachSqlNode;
    import org.apache.ibatis.session.Configuration;
    import org.apache.ibatis.type.TypeHandler;
    import org.apache.ibatis.type.TypeHandlerRegistry;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import com.baomidou.mybatisplus.core.toolkit.PluginUtils;
    
    /**
     *      ,               ,          。
     * 
     * 
    
      *         Mybatis     :
     * 1、   JDBC                  Statement  。
     * 2、Mybatis   Sql           Sql   Statement  ,     Sql    Statement     。
     * 3、 Mybatis Statement     RoutingStatementHandler   prepare     。
     * 4、  StatementHandler   prepare  ,          Sql           Sql  ,     StatementHandler   prepare  (   invocation.proceed())。
     * 5、                                   ,           Sql   ,              Mybatis               Sql          ,           Sql           。
     * 
    *
    * @author dyw
    *@date 2019 9 20
    * @param
    */
    @Intercepts({
    @Signature(type = StatementHandler.class, method = "prepare", args = { Connection.class, Integer.class }) })
    @SuppressWarnings("unchecked")
    public class AutoPageInterceptor implements Interceptor {
    private Logger log = LoggerFactory.getLogger(AutoPageInterceptor.class);
    /**
    *データベース・タイプ
    */
    private String databaseType;
    /**
    *ページングSql ID(Mapperインタフェースページングメソッドの には、ページングプラグインがメソッドをブロックするためにこのフィールドを める があります)
    */
    private String pageSqlId;
    /**
    *ページング・オブジェクト・インタフェースの (MapperインタフェースAutoPageパラメータの .ページング・インタフェースのページング・オブジェクト がここと することを する)
    */
    private String autoPageParamName;
    /**
    *
    
    	 *      :
    	 *  StatementHandler 
    	 *    ---RoutingStatementHandler
    	 *    ---BaseStatementHandler
    	 *       ---SimpleStatementHandler
    	 *       ---PreparedStatementHandler
    	 *       ---CallableStatementHandler 
    	 *    :       
    	 *   SimpleStatementHandler     Statement
    	 *   PreparedStatementHandler   PreparedStatement
    	 *   CallableStatementHandler   CallableStatement
    	 *   
    	 *     :  
    	 *   1、Mybatis   Sql            RoutingStatementHandler
    	 *   2、   RoutingStatementHandler       StatementHandler   delegate  
    	 *   3、RoutingStatementHandler   Statement        BaseStatementHandler
    	 *              ( SimpleStatementHandler、 PreparedStatementHandler CallableStatementHandler)
    	 *   4、 RoutingStatementHandler    StatementHandler            delegate     。
    	 *   5、   PageInterceptor     @Signature    Interceptor   StatementHandler   prepare  , 
    	 *                   Mybatis     RoutingStatementHandler      Interceptor plugin       ,
    	 *                                 RoutingStatementHandler  。
    	 * 
    */
    @Override
    public Object intercept(Invocation ivk) throws Throwable {
    RoutingStatementHandler statementHandler = (RoutingStatementHandler) PluginUtils.realTarget(ivk.getTarget());
    BaseStatementHandler delegate = (BaseStatementHandler) ReflectHelper.getValueByFieldName(statementHandler,
    "delegate");
    MappedStatement mappedStatement = (MappedStatement) ReflectHelper.getValueByFieldName(delegate,
    "mappedStatement");
    if (mappedStatement.getId().contains(pageSqlId){//ページングが なSQLをブロック
    BoundSql boundSql = delegate.getBoundSql();
    //ページングSQLのparameterType に するエンティティパラメータ、つまりMapperインタフェースでページングメソッドを するパラメータ.このパラメータは にしてはならない
    ParamMap parameterObject = (ParamMap) boundSql.getParameterObject();
    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 + ") b";//レコード
    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();
    AutoPage page = (AutoPage) parameterObject.get(autoPageParamName);
    page.setTotalCount(count);
    parameterObject.put(autoPageParamName, 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 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 = (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, AutoPage page) {
    if (page != null && databaseType != null && !databaseType.equals("")) {
    StringBuffer pageSql = new StringBuffer();
    if ("mysql".equals(databaseType.trim())) {
    pageSql.append(sql);
    pageSql.append("limit "+ page.getCurrentDBIndex() + ","+ page.getPageSize());
    } else if ("oracle".equals(databaseType.trim())) {
    pageSql.append("select * from (select tmp_tb.*,ROWNUM row_id from (");
    pageSql.append(sql);
    pageSql.append(") tmp_tb where ROWNUM<=");
    pageSql.append(page.getCurrentDBIndex() + page.getPageSize());
    pageSql.append(") where row_id>");
    pageSql.append(page.getCurrentDBIndex());
    }
    return pageSql.toString();
    } else {
    return sql;
    }
    }
    @Override
    public Object plugin(Object target) {
    //statementHandlerのサブクラスかどうかを する
    if (target instanceof StatementHandler) {
    //そうであればpluginのwarpメソッドを び し、パッケージします.
    return Plugin.wrap(target, this);
    }
    return target;
    }
    @Override
    public void setProperties(Properties p) {
    autoPageParamName = p.getProperty("autoPageParamName");
    if (autoPageParamName == null || autoPageParamName.equals("")) {
    try {
    throw new PropertyException("autoPageParamName property is not found!");
    } catch (PropertyException e) {
    log.warn(「ページング の :」,e.getMessage()
    e.printStackTrace();
    }
    }
    databaseType = p.getProperty("databaseType");
    if (databaseType == null || databaseType.equals("")) {
    try {
    throw new PropertyException("dialect property is not found!");
    } catch (PropertyException e) {
    log.warn(「ページング の :」,e.getMessage()
    e.printStackTrace();
    }
    }
    pageSqlId = p.getProperty("pageSqlId");
    if (pageSqlId == null || pageSqlId.equals("")) {
    try {
    throw new PropertyException("pageSqlId property is not found!");
    } catch (PropertyException e) {
    log.warn(「ページング の :」,e.getMessage()
    e.printStackTrace();
    }
    }
    }
    }
    3、 ツール
    package com.dsanjun.common.autopage;
    
    import java.lang.reflect.Field;
    
    /**
     *     
     * 
     * @author dyw
     * @date 2019 9 20 
     */
    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);
    		}
    	}
    }
    

    4、 ( にpluginsを )