栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mybatis 插件机制

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mybatis 插件机制

mybatis 4大插件

分页插件功能设计


代码

    
      
    
  
package com.wfg.interceptor;

import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.metaObject;
import org.apache.ibatis.reflection.SystemmetaObject;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Map;
import java.util.Properties;


@Intercepts(@Signature(type = StatementHandler.class,method = "prepare",args = {Connection.class,Integer.class}))
public class PageInterception implements Interceptor {
  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    System.out.println("====");
    StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
    BoundSql boundSql = statementHandler.getBoundSql();
    Object parameterObject = boundSql.getParameterObject();
    Page page = null;
    if(parameterObject instanceof Page){
      page = (Page)parameterObject;
    }else if (parameterObject instanceof Map){
      page = (Page) ((Map) parameterObject).values().stream().filter(v->v instanceof Page).findFirst().orElse(null);
    }
    //select * from users offset 0 limit 50;
    //1. 求总行数
    if(page!=null){
      int count = selectCount(invocation);
      //2.修改sql
      String newSql = String.format(" %s limit %s , %s ",boundSql.getSql(),page.getPageSize(),page.getOffSet());
      SystemmetaObject.forObject(boundSql).setValue("sql", newSql);
    }

    return invocation.proceed();
  }
  private int selectCount(Invocation invocation) throws SQLException {
    int count = 0;
    PreparedStatement preparedStatement = null;
    ResultSet resultSet = null;
    try {
      StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
      String sql = statementHandler.getBoundSql().getSql();
      String tmp = "select count(0) " + sql.substring(sql.indexOf("from"),sql.length());
      Connection connection = (Connection)invocation.getArgs()[0];
      preparedStatement = connection.prepareStatement(tmp);
      statementHandler.getParameterHandler().setParameters(preparedStatement);
      resultSet = preparedStatement.executeQuery();
      if(resultSet.next()){
        count = resultSet.getInt(1);
      }
    }finally {
      if(resultSet != null && !resultSet.isClosed())resultSet.close();
      if(preparedStatement != null && !preparedStatement.isClosed())preparedStatement.close();
    }


    return count;
  }

  @Override
  public Object plugin(Object target) {
    System.out.println("*****"+ target.getClass().getName());
    return Plugin.wrap(target,this);
  }

  @Override
  public void setProperties(Properties properties) {
    System.out.println("--------"+properties.getProperty("aa"));
  }
}

package com.wfg.interceptor;


public class Page {
  private Integer index;
  private Integer total;
  private Integer pageSize;

  public Integer getIndex() {
    return index;
  }

  public void setIndex(Integer index) {
    this.index = index;
  }

  public Integer getTotal() {
    return total;
  }

  public void setTotal(Integer total) {
    this.total = total;
  }

  public Integer getPageSize() {
    return pageSize;
  }

  public void setPageSize(Integer pageSize) {
    this.pageSize = pageSize;
  }

  public Integer getOffSet(){
    return pageSize*(index-1);
  }
}

总结


关键代码:

package org.apache.ibatis.plugin;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

import org.apache.ibatis.reflection.ExceptionUtil;
import org.apache.ibatis.util.MapUtil;


public class Plugin implements InvocationHandler {

  private final Object target;
  private final Interceptor interceptor;
  private final Map, Set> signatureMap;

  private Plugin(Object target, Interceptor interceptor, Map, Set> signatureMap) {
    this.target = target;
    this.interceptor = interceptor;
    this.signatureMap = signatureMap;
  }

  public static Object wrap(Object target, Interceptor interceptor) {
    //获取配置的签名
    Map, Set> signatureMap = getSignatureMap(interceptor);
    Class type = target.getClass();
    Class[] interfaces = getAllInterfaces(type, signatureMap);
    if (interfaces.length > 0) {
      return Proxy.newProxyInstance(
          type.getClassLoader(),
          interfaces,
          new Plugin(target, interceptor, signatureMap));
    }
    return target;
  }

  @Override
  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      Set methods = signatureMap.get(method.getDeclaringClass());
      if (methods != null && methods.contains(method)) {
        //匹配成功后 调用我们自定义的intercept中的intercept方法
        return interceptor.intercept(new Invocation(target, method, args));
      }
      return method.invoke(target, args);
    } catch (Exception e) {
      throw ExceptionUtil.unwrapThrowable(e);
    }
  }

  private static Map, Set> getSignatureMap(Interceptor interceptor) {
    Intercepts interceptsAnnotation = interceptor.getClass().getAnnotation(Intercepts.class);
    // issue #251
    if (interceptsAnnotation == null) {
      throw new PluginException("No @Intercepts annotation was found in interceptor " + interceptor.getClass().getName());
    }
    Signature[] sigs = interceptsAnnotation.value();
    Map, Set> signatureMap = new HashMap<>();
    for (Signature sig : sigs) {
      Set methods = MapUtil.computeIfAbsent(signatureMap, sig.type(), k -> new HashSet<>());
      try {
        Method method = sig.type().getMethod(sig.method(), sig.args());
        methods.add(method);
      } catch (NoSuchMethodException e) {
        throw new PluginException("Could not find method on " + sig.type() + " named " + sig.method() + ". Cause: " + e, e);
      }
    }
    return signatureMap;
  }

  private static Class[] getAllInterfaces(Class type, Map, Set> signatureMap) {
    Set> interfaces = new HashSet<>();
    while (type != null) {
      for (Class c : type.getInterfaces()) {
        if (signatureMap.containsKey(c)) {
          interfaces.add(c);
        }
      }
      type = type.getSuperclass();
    }
    return interfaces.toArray(new Class[0]);
  }

}

sql统计功能

基于Executor 进行拦截,需要拦截缓存命中数据

这两个功能分布可以看看PagePlugi 和duri中功能是如何实现的进行学习对比

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/346441.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号