精华内容
下载资源
问答
  • Mybatis 之 ParameterHandler

    千次阅读 2017-09-11 22:39:54
    在StatementHandler使用prepare()方法后,接下来就是使用ParameterHandler来设置参数,让我们看看它的定义: package org.apache.ibatis.executor.parameter; import java.sql.PreparedStatement; import java....

    在StatementHandler使用prepare()方法后,接下来就是使用ParameterHandler来设置参数,让我们看看它的定义:

    package org.apache.ibatis.executor.parameter;
    
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    
    /**
     * A parameter handler sets the parameters of the {@code PreparedStatement}
     *
     * @author Clinton Begin
     */
    public interface ParameterHandler {
    
      Object getParameterObject();
    
      void setParameters(PreparedStatement ps)
          throws SQLException;
    
    }

    getParameterObject()是获取参数的,而setParameters()是设置参数的,相当于对一条sql所有的参数都执行ps.setXXX(value);


    DefaultParameterHandler是它的实现类:

    package org.apache.ibatis.scripting.defaults;
    
    import java.sql.PreparedStatement;
    import java.sql.SQLException;
    import java.util.List;
    
    import org.apache.ibatis.executor.ErrorContext;
    import org.apache.ibatis.executor.parameter.ParameterHandler;
    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.reflection.MetaObject;
    import org.apache.ibatis.session.Configuration;
    import org.apache.ibatis.type.JdbcType;
    import org.apache.ibatis.type.TypeException;
    import org.apache.ibatis.type.TypeHandler;
    import org.apache.ibatis.type.TypeHandlerRegistry;
    
    /**
     * @author Clinton Begin
     * @author Eduardo Macarron
     */
    public class DefaultParameterHandler implements ParameterHandler {
    
      private final TypeHandlerRegistry typeHandlerRegistry;
    
      private final MappedStatement mappedStatement;
      private final Object parameterObject;  //所有的参数值
      private BoundSql boundSql;
      private Configuration configuration;
    
      public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
        this.mappedStatement = mappedStatement;
        this.configuration = mappedStatement.getConfiguration();
        this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
        this.parameterObject = parameterObject;
        this.boundSql = boundSql;
      }
    
      @Override
      public Object getParameterObject() {
        return parameterObject;
      }
    
      @Override
      public void setParameters(PreparedStatement ps) {
        ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
        //获取所有参数,ParameterMapping是java类型和jdbc类型的对应关系
        List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
        if (parameterMappings != null) {
          for (int i = 0; i < parameterMappings.size(); i++) {
            ParameterMapping parameterMapping = parameterMappings.get(i);
            if (parameterMapping.getMode() != ParameterMode.OUT) {
              //参数值
              Object value;
              //获取参数名称
              String propertyName = parameterMapping.getProperty();
              if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
                //获取参数值
                value = boundSql.getAdditionalParameter(propertyName);
              } else if (parameterObject == null) {
                value = null;
              } else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass()))
                //如果是单个值则直接赋值   
                value = parameterObject;
              } else {
                MetaObject metaObject = configuration.newMetaObject(parameterObject);
                value = metaObject.getValue(propertyName);
              }
              //获取参数值对应的jdbc类型
              TypeHandler typeHandler = parameterMapping.getTypeHandler();
              JdbcType jdbcType = parameterMapping.getJdbcType();
              if (value == null && jdbcType == null) {
                jdbcType = configuration.getJdbcTypeForNull();
              }
              try {
                //设置参数值和jdbc类型的对应关系
                typeHandler.setParameter(ps, i + 1, value, jdbcType);
              } catch (TypeException e) {
                throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
              } catch (SQLException e) {
                throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
              }
            }
          }
        }
      }
    
    }
    getParameterObject是获取参数,这个参数值就是你传递进来的值,可能是个实体、map或单个基本类型数据。

    重点看setParameters(),首先它读取了ParameterObject参数对象,然后用typeHandler对参数进行设置,而typeHandler里面需要对jdbcType和javaType进行处理,然后就设置参数了。也很好理解。所以当我们使用TypeHandler的时候完全可以控制如何设置SQL参数。设置参数,其实就是你在sql语句中配置的java对象和jdbc类型对应的关系,例如#{id,jdbcType=INTEGER},id默认类型是javaType=class java.lang.Integer。





    展开全文
  • 目录 ParameterHandler 简介 ParameterHandler 创建 ParameterHandler 中的参数从何而来 ParameterHandler 解析 MyBatis 四大核心组件我们已经了解到...

    MyBatis 四大核心组件我们已经了解到了两种,一个是 Executor ,它是MyBatis 解析SQL请求首先会经过的第一道关卡,它的主要作用在于创建缓存,管理 StatementHandler 的调用,为 StatementHandler 提供 Configuration 环境等。StatementHandler 组件最主要的作用在于创建 Statement 对象与数据库进行交流,还会使用 ParameterHandler 进行参数配置,使用 ResultSetHandler 把查询结果与实体类进行绑定。那么本篇就来了解一下第三个组件 ParameterHandler。

    ParameterHandler 简介

    ParameterHandler 相比于其他的组件就简单很多了,ParameterHandler 译为参数处理器,负责为 PreparedStatement 的 sql 语句参数动态赋值,这个接口很简单只有两个方法

    /**
     * A parameter handler sets the parameters of the {@code PreparedStatement}
     * 参数处理器为 PreparedStatement 设置参数
     */
    public interface ParameterHandler {
    
      Object getParameterObject();
    
      void setParameters(PreparedStatement ps)
          throws SQLException;
    
    }

    ParameterHandler 只有一个实现类 DefaultParameterHandler , 它实现了这两个方法。

    • getParameterObject: 用于读取参数
    • setParameters: 用于对 PreparedStatement 的参数赋值

    ParameterHandler 创建

    参数处理器对象是在创建 StatementHandler 对象的同时被创建的,由 Configuration 对象负责创建

    BaseStatementHandler.java

    protected BaseStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
      this.configuration = mappedStatement.getConfiguration();
      this.executor = executor;
      this.mappedStatement = mappedStatement;
      this.rowBounds = rowBounds;
    
      this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
      this.objectFactory = configuration.getObjectFactory();
    
      if (boundSql == null) { // issue #435, get the key before calculating the statement
        generateKeys(parameterObject);
        boundSql = mappedStatement.getBoundSql(parameterObject);
      }
    
      this.boundSql = boundSql;
    
      // 创建参数处理器
      this.parameterHandler = configuration.newParameterHandler(mappedStatement, parameterObject, boundSql);
      // 创建结果映射器
      this.resultSetHandler = configuration.newResultSetHandler(executor, mappedStatement, rowBounds, parameterHandler, resultHandler, boundSql);
    }

    在创建 ParameterHandler 时,需要传入SQL的mappedStatement 对象,读取的参数和SQL语句

    注意:一个 BoundSql 对象,就代表了一次sql语句的实际执行,而 SqlSource 对象的责任,就是根据传入的参数对象,动态计算这个 BoundSql, 也就是 Mapper 文件中节点的计算,是由 SqlSource 完成的,SqlSource 最常用的实现类是 DynamicSqlSource

    Configuration.java

    public ParameterHandler newParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
      // 创建ParameterHandler
      ParameterHandler parameterHandler = mappedStatement.getLang().createParameterHandler(mappedStatement, parameterObject, boundSql);
      parameterHandler = (ParameterHandler) interceptorChain.pluginAll(parameterHandler);
      return parameterHandler;
    }

    上面是 Configuration 创建 ParameterHandler 的过程,它实际上是交由 LanguageDriver 来创建具体的参数处理器,LanguageDriver 默认的实现类是 XMLLanguageDriver,由它调用 DefaultParameterHandler 中的构造方法完成 ParameterHandler 的创建工作

    public ParameterHandler createParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
      return new DefaultParameterHandler(mappedStatement, parameterObject, boundSql);
    }
    
    public DefaultParameterHandler(MappedStatement mappedStatement, Object parameterObject, BoundSql boundSql) {
      this.mappedStatement = mappedStatement;
      this.configuration = mappedStatement.getConfiguration();
      // 获取 TypeHandlerRegistry 注册
      this.typeHandlerRegistry = mappedStatement.getConfiguration().getTypeHandlerRegistry();
      this.parameterObject = parameterObject;
      this.boundSql = boundSql;
    }

    上面的流程是创建 ParameterHandler 的过程,创建完成之后,该进行具体的解析工作,那么 ParameterHandler 如何解析SQL中的参数呢?SQL中的参数从哪里来的?

    ParameterHandler 中的参数从何而来

    你可能知道 Parameter 中的参数是怎么来的,无非就是从 Mapper 配置文件中映射过去的啊,就比如如下例子

    1515111-20190807231123882-227673915.png

    参数肯定就是图中标红的 1 ,然后再传到XML对应的 SQL 语句中,用 #{} 或者 ${} 来进行赋值啊,

    1515111-20190807231133268-1219817070.png

    嗯,你讲的没错,可是你知道这个参数是如何映射过来的吗?或者说你知道 Parameter 的解析过程吗?或许你不是很清晰了,我们下面就来探讨一下 ParameterHandler 对参数的解析,这其中涉及到 MyBatis 中的动态代理模式

    在MyBatis 中,当 deptDao.findByDeptNo(1) 将要执行的时候,会被 JVM 进行拦截,交给 MyBatis 中的代理实现类 MapperProxy 的 invoke 方法中,这也是执行 SQL 语句的主流程。

    1515111-20190807231142981-835042774.png

    然后交给 Executor 、StatementHandler进行对应的参数解析和执行,因为是带参数的 SQL 语句,最终会创建 PreparedStatement 对象并创建参数解析器进行参数解析

    SimpleExecutor.java

    1515111-20190807231153862-1689775186.png

    handler.parameterize(stmt) 最终会调用到 DefaultParameterHandler 中的 setParameters 方法,我在源码上做了注释,为了方便拷贝,我没有采用截图的形式

    public void setParameters(PreparedStatement ps) {
      ErrorContext.instance().activity("setting parameters").object(mappedStatement.getParameterMap().getId());
      // parameterMappings 就是对 #{} 或者 ${} 里面参数的封装
      List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
      if (parameterMappings != null) {
        // 如果是参数化的SQL,便需要循环取出并设置参数的值
        for (int i = 0; i < parameterMappings.size(); i++) {
          ParameterMapping parameterMapping = parameterMappings.get(i);
          // 如果参数类型不是 OUT ,这个类型与 CallableStatementHandler 有关
          // 因为存储过程不存在输出参数,所以参数不是输出参数的时候,就需要设置。
          if (parameterMapping.getMode() != ParameterMode.OUT) {
            Object value;
            // 得到#{}  中的属性名
            String propertyName = parameterMapping.getProperty();
            // 如果 propertyName 是 Map 中的key
            if (boundSql.hasAdditionalParameter(propertyName)) { // issue #448 ask first for additional params
              // 通过key 来得到 additionalParameter 中的value值
              value = boundSql.getAdditionalParameter(propertyName);
            }
            // 如果不是 additionalParameters 中的key,而且传入参数是 null, 则value 就是null
            else if (parameterObject == null) {
              value = null;
            }
            // 如果 typeHandlerRegistry 中已经注册了这个参数的 Class对象,即它是Primitive 或者是String 的话
            else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
              value = parameterObject;
            } else {
              // 否则就是 Map
              MetaObject metaObject = configuration.newMetaObject(parameterObject);
              value = metaObject.getValue(propertyName);
            }
            // 在通过SqlSource 的parse 方法得到parameterMappings 的具体实现中,我们会得到parameterMappings的typeHandler
            TypeHandler typeHandler = parameterMapping.getTypeHandler();
            // 获取typeHandler 的jdbc type
            JdbcType jdbcType = parameterMapping.getJdbcType();
            if (value == null && jdbcType == null) {
              jdbcType = configuration.getJdbcTypeForNull();
            }
            try {
              typeHandler.setParameter(ps, i + 1, value, jdbcType);
            } catch (TypeException e) {
              throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
            } catch (SQLException e) {
              throw new TypeException("Could not set parameters for mapping: " + parameterMapping + ". Cause: " + e, e);
            }
          }
        }
      }
    }

    ParameterHandler 解析

    我们在 MyBatis 核心配置综述之 StatementHandler 一文中了解到 Executor 管理的是 StatementHandler 对象的创建以及参数赋值,那么我们的主要入口还是 Executor 执行器

    下面用一个流程图表示一下 ParameterHandler 的解析过程,以简单执行器为例

    1515111-20190807231207153-238300434.png

    像是 doQuery,doUpdate,doQueryCursor等方法都会先调用到

    // 生成 preparedStatement 并调用 prepare 方法,并为参数赋值
    private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
      Statement stmt;
      Connection connection = getConnection(statementLog);
      stmt = handler.prepare(connection, transaction.getTimeout());
      handler.parameterize(stmt);
      return stmt;
    }

    然后在生成 preparedStatement 调用DefaultParameterHandler进行参数赋值。

    公众号提供 优质Java资料 以及CSDN免费下载 权限,欢迎你关注我
    1515111-20190807231446837-350627522.png

    转载于:https://www.cnblogs.com/cxuanBlog/p/11318502.html

    展开全文
  • mybatis自定义插件

    2021-08-28 16:28:33
    ParameterHandler:参数处理器 ResultSetHandler:结果集处理器 这四个执行器的在mybatis体系中产生的作用如下: 自定义插件实现 将需要实现自定义逻辑的类实现 Interceptor 接口,并指定想要拦截的方法签名即可...

    插件扩展概念

    mybatis为了自身支持扩展,为自身的四个关键流程提供了基于动态代理的扩展接口实现,他们分别是:

    • Executor:执行器
    • StatementHandler:JDBC处理器
    • ParameterHandler:参数处理器
    • ResultSetHandler:结果集处理器

    这四个执行器的在mybatis体系中产生的作用如下:
    在这里插入图片描述

    自定义插件实现

    将需要实现自定义逻辑的类实现 Interceptor 接口,并指定想要拦截的方法签名即可实现拦截。

    @Intercepts({@Signature(
      type= Executor.class,
      method = "update",
      args = {MappedStatement.class,Object.class})})
    public class ExamplePlugin implements Interceptor {
            // 当执行目标方法时会被方法拦截
        public Object intercept(Invocation invocation) throws Throwable {
          long begin = System.currentTimeMillis();
            try {
                return invocation.proceed();// 继续执行原逻辑;
            } finally {
                System.out.println("执行时间:"+(System.currentTimeMillis() - begin));
            }
        }
            // 生成代理对象,可自定义生成代理对象,这样就无需配置@Intercepts注解。另外需要自行判断是否为拦截目标接口。
        public Object plugin(Object target) {
            return Plugin.wrap(target,this);// 调用通用插件代理生成机器
        }
    }
    

    在config.xml 中添加插件配置

    <plugins>
      <plugin interceptor="org.mybatis.example.ExamplePlugin"/>
    </plugins>
    

    插件代理机制

    在mybatis的总管家Configuration 中有一个InterceptorChain(拦截链)保存了所有拦截器,当创建四大对象之后就会调用拦截链,对目标对象进行拦截代理,相应的图如下:
    在这里插入图片描述

    源码实现示例

    以configuration创建Executor为例,其余三种的拦截逻辑与它类似,就不多说了。
    创建完之后,进行增强:

     public Executor newExecutor(Transaction transaction, ExecutorType executorType) {
        executorType = executorType == null ? defaultExecutorType : executorType;
        executorType = executorType == null ? ExecutorType.SIMPLE : executorType;
        Executor executor;
        if (ExecutorType.BATCH == executorType) {
          executor = new BatchExecutor(this, transaction);
        } else if (ExecutorType.REUSE == executorType) {
          executor = new ReuseExecutor(this, transaction);
        } else {
          executor = new SimpleExecutor(this, transaction);
        }
        if (cacheEnabled) {
          executor = new CachingExecutor(executor);
        }
    
        //通过责任链的方式来实现executor的增强
        executor = (Executor) interceptorChain.pluginAll(executor);
        return executor;
      }
    

    我们沿着interceptorChain.pluginAll再继续看下去:

    Plugin.wrap(target, this)
    

    继续

    Map<Class<?>, Set<Method>> 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;
    

    这里通过动态代理的方式返回了Plugin类,当调用所拦截的代理类的方法时,会触发Plugin类的invoke方法,如下所示:

    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        try {
          Set<Method> methods = signatureMap.get(method.getDeclaringClass());
          if (methods != null && methods.contains(method)) {
            return interceptor.intercept(new Invocation(target, method, args));
          }
          return method.invoke(target, args);
        } catch (Exception e) {
          throw ExceptionUtil.unwrapThrowable(e);
        }
      }
    

    在这里如果当前方法是被拦截的方法,则会调用自定义拦截器的intercept方法,intercept方法一般会在执行自定义逻辑后再执行原方法,这样即可实现自定义逻辑,一般会自定义插件的场景有,分页插件,日志打印,对某个字段进行加密之类的。
    为了帮助理解,在这里贴出自定义的类以及自定义的拦截器,方便调试:

    package com;
    
    
    import org.apache.ibatis.plugin.*;
    import org.junit.Test;
    
    import java.util.Properties;
    
    public class PluginTest {
    
        @Test
        public void pluginWrapTest(){
            MyPlugin myPlugin= new MyPlugin() {
                @Override
                public String sayHello(String name) {
                    System.out.println("hello"+name);
                    return name+"hello";
                }
    
                @Override
                public String sayGood(String name) {
                    System.out.println("good"+name);
                    return name+"good";
                }
            };
            MyPlugin wrap= (MyPlugin) Plugin.wrap(myPlugin,new MyInterceptor());
            wrap.sayHello("ddd");
        }
    
        public interface MyPlugin{
            String sayHello(String name);
    
            String sayGood(String name);
        }
    
        @Intercepts({@Signature(type = MyPlugin.class,args = {String.class},method="sayHello"),@Signature(type = MyPlugin.class,args = {String.class},method="sayGood")})
        public static class MyInterceptor implements Interceptor {
    
            @Override
            public Object intercept(Invocation invocation) throws Throwable {
                System.out.println("lydon do:"+invocation.getMethod().getName());
                return invocation.proceed();
            }
    
            @Override
            public Object plugin(Object target) {
                return null;
            }
    
            @Override
            public void setProperties(Properties properties) {
    
            }
        }
    }
    
    

    本文材料有些参考自源码阅读网

    展开全文
  • Mybatis自定义插件

    千次阅读 2018-05-10 13:41:23
    Mybatis自定义插件针对Mybatis四大对象(Executor、StatementHandler 、ParameterHandler 、ResultSetHandler )进行拦截,具体拦截方式为: 1、Executor:拦截执行器的方法(log记录) 2、StatementHandler :拦截...

    Mybatis自定义插件针对Mybatis四大对象(Executor、StatementHandler 、ParameterHandler 、ResultSetHandler )进行拦截,具体拦截方式为:
    1、Executor:拦截执行器的方法(log记录)
    2、StatementHandler :拦截Sql语法构建的处理
    3、ParameterHandler :拦截参数的处理
    4、ResultSetHandler :拦截结果集的处理
    前两种应用较为广泛。

    Mybatis自定义插件必须实现Interceptor接口:

    public interface Interceptor {
        Object intercept(Invocation invocation) throws Throwable;
        Object plugin(Object target);
        void setProperties(Properties properties);
    }

    intercept方法:拦截器具体处理逻辑方法
    plugin方法:根据签名signatureMap生成动态代理对象
    setProperties方法:设置Properties属性

    自定义插件demo:

    // ExamplePlugin.java
    @Intercepts({@Signature(
      type= Executor.class,
      method = "update",
      args = {MappedStatement.class,Object.class})})
    public class ExamplePlugin implements Interceptor {
      public Object intercept(Invocation invocation) throws Throwable {
      Object target = invocation.getTarget(); //被代理对象
      Method method = invocation.getMethod(); //代理方法
      Object[] args = invocation.getArgs(); //方法参数
      // do something ...... 方法拦截前执行代码块
      Object result = invocation.proceed();
      // do something .......方法拦截后执行代码块
      return result;
      }
      public Object plugin(Object target) {
        return Plugin.wrap(target, this);
      }
      public void setProperties(Properties properties) {
      }
    }

    一个@Intercepts可以配置多个@Signature,@Signature中的参数定义如下:
    type:表示拦截的类,这里是Executor的实现类
    method:表示拦截的方法,这里是拦截Executor的update方法
    args:表示方法参数

    展开全文
  • Mybatis源码解析--ParameterHandler 背景 在Mybatis源码解析--StatementHandler中我们知道StatementHandler是对JDBC中Statement功能的封装,而针对3种Statement提供了对应的StatementHandler,而StatementHandler...
  • 自定义枚举类型处理器 EnumTypeHandler类 CodeBaseEnum类 CodeEnumUtil类 测试Gender类 TypeHandler简介 在MyBatis中,StatementHandler负责对需要执行的SQL语句进行预编译处理,主要完成以下两项工作: 1....
  • Mybatis自定义插件-Interceptor ** MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法调用包括: Executor (update, query, flushStatements, commit, ...
  • Mybatis自定义拦截器

    千次阅读 2018-03-30 18:49:01
    需求背景: 在插入数据时需要提前设置 ID 和创建时间, 在更新时设置修改时间. 实现: 定义 Mybatis 拦截器只...mybatis 的四大对象:[ParameterHandler],[ResultSetHandler],[StatementHandler],[Executor]. me...
  • Mybatis 3 自定义Plugin

    2020-03-15 18:01:42
    Mybatis 3 自定义plugin MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。 默认情况下,MyBatis 允许使用插件来拦截的方法调用包括: Executor (update, query, flushStatements, commit, rollback, ...
  • mybatis自定义拦截器

    2021-10-11 11:16:18
    1. mybatis自定义拦截器实现步骤: 实现org.apache.ibatis.plugin.Interceptor接口。 添加拦截器注解org.apache.ibatis.plugin.Intercepts。 配置文件中添加拦截器。 2. 在mybatis中可被拦截的类型有四种(按照...
  • 自定义Mybatis分页插件

    2020-04-20 17:17:30
    Mybatis实现自定义插件需要实现Interceptor接口: * 在mybatis中有四大拦截器,拦截的方法为其接口 * Executor(Mybatis的拦截器,执行增删改查) * StatementHandler(sql语法构建拦截器,也是实现分页的拦截器类型)...
  • mybatis 自定义拦截器

    2020-11-30 14:47:12
    mybatis自定义拦截器实现步骤: 实现org.apache.ibatis.plugin.Interceptor接口。 添加拦截器注解org.apache.ibatis.plugin.Intercepts。 配置文件中添加拦截器。 在mybatis中可被拦截的类型有四种(按照拦截顺序...
  • mybatis 自定义插件

    千次阅读 2020-10-03 21:50:42
    我们可以基于mybatis插件机制实现分页、分表、监控等功能,mybatis四大组件包括Executor、StatementHandler、ParameterHandler、ResultSetHandler,他们提供了简单易用的插件扩展机制。 插件扩展需两步: 1、实现...
  • 先看如何自定义一个插件 1、新建类实现 Interceptor 接口,并指定想要拦截的方法签名 /** * MyBatis 插件 */ @Intercepts({@Signature(type = Executor.class, method = "query", args = {MappedStatement....
  • MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法...ParameterHandler (getParameterObject, setParameters):处理参数 ResultSetHandler (handleResultSets
  • springboot集成mybatis自定义插件开发

    千次阅读 2018-12-23 16:58:21
    什么是mybatis插件 mybatis插件就是在执行数据库操作的时候,对于特定方法进行拦截增强,做一些额外的处理的一种方式。 myabtis的插件的增强原理是利用...ParameterHandler ResultSetHandler 其中: Execu...
  • 前言 MyBatis自身提供了接口,支持在映射语句的某一点进行拦截做一些处理。所以在我们使用mybatis这...Mybatis自定义插件针对Mybatis四大对象(Executor、StatementHandler 、ParameterHandler 、ResultSetHandler ...
  • springboot集成自定义mybatis分页插件 每天多学一点点~ 好久没研究新东西了,最近看了下pagehelper插件,动态拼接sql,决心模仿下写一个简单的~ 话不多说,这就开始吧… 文章目录springboot集成自定义mybatis分页...
  • 在上篇插件原理中我们谈到了ParameterHandler 和 ResultSetHandler MyBatis原理第四篇——statementHandler对象(sqlSession内部核心实现,插件的基础) 这篇文章我们就着重的讨论这两个对象。 1、...
  • 自定义的TypeHandler 1、JsonTypeHandler.java import com.dreawer.domain.BaseDomain; import com.dreawer.persistence.config.DwDaoHandler; import com.dreawer.persistence.config.DwMybatisConfig; import ...
  • 文章目录一、环境准备1、导入以下依赖2、创建mybatis核心配置文件(SqlMapConfig.xml)二、创建实体类和mapper层1、创建User实体类2、创建自定义的Page类和PageHelper3、创建HdzPageInterceptor并实现Interceptor...
  • 上一篇讲到PreparedStatementHandler的时候中间对参数处理的时候使用的是ParameterHandler;而在其查询最后也会使用一个resultSetHandler。本篇主要看看这两个类的逻辑 ParameterHandler 对SQL执行方法参数处理的...
  • * 自定义注解:自动进行日志打印 */ @Target({ElementType.PARAMETER, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) public @interface AutoLogAnnotation { } 第二步:写切面 import ...
  • Mybatis实现自定义Plugins拦截器

    千次阅读 2019-02-26 00:42:06
    MyBatis 自定义拦截器,可以拦截的接口只有四种 Executor.class,StatementHandler.class,ParameterHandler.class 和 ResultSetHandler.class。 在某种情景下,如果这四种接口自带的某个方法不能满足我们的要求时,...
  • 文章目录Mybatis参数读取源码分析一、ParameterHandler二、DefaultParameterHandler三、流程调试3.1 SimpleExecutor#doQuery3.2 SimpleExecutor#prepareStatement3.3 PreparedStatementHandler#parameterize3.4 ...
  • Mybatis 自定义自动分页 1.JDBCToMyBatisUtils.java package com.util.query; import java.util.List; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; import org....

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 3,677
精华内容 1,470
关键字:

自定义parameterhandler