精华内容
下载资源
问答
  • 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:表示方法参数

    展开全文
  • 自定义枚举类型处理器 EnumTypeHandler类 CodeBaseEnum类 CodeEnumUtil类 测试Gender类 TypeHandler简介 在MyBatis中,StatementHandler负责对需要执行的SQL语句进行预编译处理,主要完成以下两项工作: 1....

    目录

    TypeHandler简介

    自定义枚举类型处理器

    EnumTypeHandler类

    CodeBaseEnum类 

    CodeEnumUtil类 

    测试Gender类 


    TypeHandler简介

    在MyBatis中,StatementHandler负责对需要执行的SQL语句进行预编译处理,主要完成以下两项工作:
    1.调用参数处理器(ParameterHandler)来设置需要传入SQL的参数;
    2.调用结果集处理器(ResultSetHandler)来处理查询到的结果数据;

    而不管要完成其中的哪一项工作都需要使用类型处理器(TypeHandler)来进行数据类型处理,无论是ParameterHandler为预处理语句(PreparedStatement)设置一个参数,还是ResultSetHandler将结果集中的一条记录转换为合适的Java类型。在整个过程中,TypeHandler负责完成数据库类型与JavaBean类型的转换工作。  

    自定义枚举类型处理器

    以枚举类型的处理器为例,MyBatis提供了EnumTypeHandlerEnumOrdinalTypeHandler两个处理器来处理枚举类型。这两个处理器之间的区别在于EnumTypeHandler是将枚举的name值存到数据库,而EnumOrdinalTypeHandler会将枚举的序号值(>=0)存入数据库。

    当然,我们还可以自己写一个TypeHandler来控制在设置参数或者取出结果集时应该如何对参数类型进行转换或封装。

    自定义一个TypeHandler需要以下几个步骤:
    1.实现TypeHandler接口或者继承BaseTypeHandler
    2.使用@MappedTypes(value = {})定义需要由该处理器处理的java类型。
      使用@MappedJdbcTypes(value = {})定义所对应的jdbcType类型。
    3.在自定义结果集标签或者参数处理的时候声明使用自定义TypeHandler进行处理或者在全局配置TypeHandler要处理的javaType

    以下是自定义的枚举类型处理器的源码。

    EnumTypeHandler类

    package org.mybatis.typehandler;
    
    import java.sql.CallableStatement;
    import java.sql.PreparedStatement;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    
    import org.apache.ibatis.type.BaseTypeHandler;
    import org.apache.ibatis.type.JdbcType;
    
    /**
     * mapper里字段到枚举类的映射。
     * 用法一: 
     * 	保存到数据库:#{enumDataField,typeHandler=com.mybatis.typehandler.EnumTypeHandler} 
     *  从数据库查出:
     *   <resultMap> <result property="enumDataField" column="enum_data_field"
     *   javaType="com.xxx.MyEnum"
     *   typeHandler="com.mybatis.typehandler.EnumTypeHandler"/>
     *   </resultMap>
     *
     * 用法二: 
     *  1)在mybatis-config.xml中指定handler: 
     *   <typeHandlers> 
     *   <typeHandler handler="com.mybatis.typehandler.EnumTypeHandler" javaType="com.xxx.MyEnum"/> 
     *   </typeHandlers>
     *  2)在MyClassMapper.xml里直接select/update/insert。
     */
    
    public class EnumTypeHandler<E extends Enum<?> & CodeBaseEnum> extends
    		BaseTypeHandler<CodeBaseEnum> {
    	private Class<E> clazz;
    
    	public EnumTypeHandler(Class<E> enumType) {
    		if (enumType == null)
    			throw new IllegalArgumentException("Type argument cannot be null");
    
    		this.clazz = enumType;
    	}
    
    	@Override
    	public void setNonNullParameter(PreparedStatement ps, int i,
    			CodeBaseEnum parameter, JdbcType jdbcType) throws SQLException {
    		ps.setInt(i, parameter.code());
    	}
    
    	@Override
    	public E getNullableResult(ResultSet rs, String columnName)
    			throws SQLException {
    		return CodeEnumUtil.codeOf(clazz, rs.getInt(columnName));
    	}
    
    	@Override
    	public E getNullableResult(ResultSet rs, int columnIndex)
    			throws SQLException {
    		return CodeEnumUtil.codeOf(clazz, rs.getInt(columnIndex));
    	}
    
    	@Override
    	public E getNullableResult(CallableStatement cs, int columnIndex)
    			throws SQLException {
    		return CodeEnumUtil.codeOf(clazz, cs.getInt(columnIndex));
    	}
    }

    CodeBaseEnum类 

    package org.mybatis.typehandler;
    
    public interface CodeBaseEnum {
    	int code();
    }

    CodeEnumUtil类 

    package org.mybatis.typehandler;
    
    public class CodeEnumUtil {
    	/**
    	 * @param enumClass
    	 * @param code
    	 * @param <E>
    	 * @return
    	 */
    	public static <E extends Enum<?> & CodeBaseEnum> E codeOf(
    			Class<E> enumClass, int code) {
    		E[] enumConstants = enumClass.getEnumConstants();
    		for (E e : enumConstants) {
    			if (e.code() == code)
    				return e;
    		}
    		return null;
    	}
    }

    测试Gender类 

    package org.mybatis.entity;
    
    import org.mybatis.typehandler.CodeBaseEnum;
    
    public enum Gender implements CodeBaseEnum {
    
    	MALE(0, "男"), FEMALE(1, "女");
    	private Integer code;
    	private String msg;
    
    	Gender(Integer code, String msg) {
    		this.code = code;
    		this.msg = msg;
    	}
    
    	public String getMsg() {
    		return msg;
    	}
    
    	public void setMsg(String msg) {
    		this.msg = msg;
    	}
    
    	@Override
    	public int code() {
    		return code;
    	}
    
    }
    

      

    展开全文
  • Mybatis 3 自定义Plugin

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

    Mybatis 3 自定义plugin

    MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。
    默认情况下,MyBatis 允许使用插件来拦截的方法调用包括:

    Executor (update, query, flushStatements, commit, rollback, getTransaction, close, isClosed)
    ParameterHandler (getParameterObject, setParameters)
    ResultSetHandler (handleResultSets, handleOutputParameters)
    StatementHandler (prepare, parameterize, batch, update, query)
    

    详情请参考官网

    实现自定义plugin

    只需实现 Interceptor 接口,即可以定义自己的plugin

    package com.example.plugin;
    
    import org.apache.ibatis.executor.Executor;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.plugin.Interceptor;
    import org.apache.ibatis.plugin.Intercepts;
    import org.apache.ibatis.plugin.Invocation;
    import org.apache.ibatis.plugin.Signature;
    import org.apache.ibatis.session.ResultHandler;
    import org.apache.ibatis.session.RowBounds;
    
    @Intercepts({
            @Signature(type = Executor.class, method = "query", args = {MappedStatement.class,Object.class, RowBounds.class, ResultHandler.class})
    })
    public class MyPlugin implements Interceptor {
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            System.out.println("要拦截的方法:" + invocation.getMethod());
            Object prObject = invocation.proceed();
            return prObject;
        }
    }
    
    

    mybatis 加载plugin

    在mybatis-config.xml中添加plugin配置

    <?xml version="1.0" encoding="UTF-8" ?>
    <!DOCTYPE configuration
            PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
            "http://mybatis.org/dtd/mybatis-3-config.dtd">
    <configuration>
        <plugins>
            <plugin interceptor="com.example.plugin.MyPlugin"></plugin>
        </plugins>
    </configuration>
    

    在application.xml引用mybatis-config.xml

    mybatis:
      type-handlers-package: com.example.handler
      config-location: classpath:mybatis-config.xml
    

    mybatis-config配置详情参考官网

    验证插件效果

    发送查询请求

    1Za2iB

    查看自己写的插件是否生效

    S520lZ

    展开全文
  • 自定义Mybatis分页插件

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

    Mybatis实现自定义插件需要实现Interceptor接口:
     * 在mybatis中有四大拦截器,拦截的方法为其接口
     * Executor(Mybatis的拦截器,执行增删改查)
     * StatementHandler(sql语法构建拦截器,也是实现分页的拦截器类型)
     * ParameterHandler(sql参数处理器)
     * ResultSetHandler(结果集处理,转集合)

    一 实现Interceptor接口

    import lombok.extern.slf4j.Slf4j;
    import org.apache.ibatis.executor.parameter.ParameterHandler;
    import org.apache.ibatis.executor.statement.StatementHandler;
    import org.apache.ibatis.mapping.MappedStatement;
    import org.apache.ibatis.plugin.*;
    import org.apache.ibatis.reflection.MetaObject;
    import org.apache.ibatis.reflection.SystemMetaObject;
    
    import java.sql.Connection;
    import java.util.Map;
    import java.util.Properties;
    @Intercepts({
            @Signature(type = StatementHandler.class,method = "prepare",args = {Connection.class,Integer.class})
    })
    @Slf4j
    public class PageInterceptor implements Interceptor {
        @Override
        public Object intercept(Invocation invocation) throws Throwable {
            StatementHandler statementHandler = (StatementHandler) invocation.getTarget();
            MetaObject metaObject = SystemMetaObject.forObject(statementHandler);
             //返回代理链的目标对象
            while(metaObject.hasGetter("h")){
                Object obj = metaObject.getValue("h");
                metaObject = SystemMetaObject.forObject(metaObject);
            }
            while(metaObject.hasGetter("target")){
                Object obj = metaObject.getValue("target");
                metaObject = SystemMetaObject.forObject(metaObject);
            }
            //mappedStatement对应xml文件的sql,id是完全限定类名+方法名
            MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
            String id = mappedStatement.getId();
             //如果方法ByPage结尾则分页处理
            if(id.matches(".+ByPage$")){
                //获取参数处理拦截器
               ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
               Map<String,Object> map = (Map<String, Object>) parameterHandler.getParameterObject();
               Integer page = 1;
               Integer size = 10;
               if(map != null && map.size()>0){
                    page = Integer.valueOf( map.get("page").toString());
                    size = Integer.valueOf( map.get("size").toString());
               }
               //获取原始sql
               String sql = statementHandler.getBoundSql().getSql();
              log.info("输出原始sql:"+sql);
                String orginSql = sql;
               if(sql.endsWith(";")){
                    orginSql = sql.substring(0, sql.length()-1);
               }
               String pageSql = orginSql +" limit " +(page-1)*size +","+ size;
              log.info("输出拼接sql"+ pageSql);
               metaObject.setValue("delegate.boundSql.sql", pageSql);
            }
            return invocation.proceed();
        }
    
        @Override
        public Object plugin(Object target) {
            return Plugin.wrap(target,this);
        }
    
        @Override
        public void setProperties(Properties properties) {
        }
    }
    

     

    二 注册拦截器插件(基于Springboot项目,通过代码注入bean属性):

        @Bean
        @ConfigurationProperties(prefix = "spring.datasource")
        public DataSource dataSource(){
            DataSourceBuilder dataSourceBuilder =DataSourceBuilder.create();
            dataSourceBuilder.driverClassName("com.mysql.cj.jdbc.Driver");
            dataSourceBuilder.url("jdbc:mysql://localhost:3306/test?serverTimezone=UTC");
            dataSourceBuilder.username("root");
            dataSourceBuilder.password("a");
            return dataSourceBuilder.build();
        }
    
    
        @Bean
        public SqlSessionFactory getSqlSession() throws Exception {
            SqlSessionFactoryBean sql = new SqlSessionFactoryBean();
            //设置mapper文件路径
            PathMatchingResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
            Resource[]  arr = resolver.getResources("classpath:mapper/*Mapper.xml");
            sql.setMapperLocations(arr);
            //设置别名
            sql.setTypeAliasesPackage("com.yc.serverconfig.entity");
            //设置拦截器
            sql.setPlugins(new PageInterceptor());
            sql.setDataSource(dataSource());
            return sql.getObject();
        }

    三 运行结果:

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

     

    展开全文
  • 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、实现...
  • 前言 MyBatis自身提供了接口,支持在映射语句的某一点进行拦截做一些处理。所以在我们使用mybatis这...Mybatis自定义插件针对Mybatis四大对象(Executor、StatementHandler 、ParameterHandler 、ResultSetHandler ...
  • Mybatis实现自定义Plugins拦截器

    千次阅读 2019-02-26 00:42:06
    MyBatis 自定义拦截器,可以拦截的接口只有四种 Executor.class,StatementHandler.class,ParameterHandler.class 和 ResultSetHandler.class。 在某种情景下,如果这四种接口自带的某个方法不能满足我们的要求时,...
  • MyBatis自定义插件开发

    2020-04-01 17:22:54
    interceptorChain.pluginAll(parameterHandler); 2.获取到所有的Interceptor(拦截器)(插件需要实现的接口) 调用interceptor.plugin(target);返回target包装后的对象 3.插件机制,我们可以使用插件为目标对象...
  • Mybatis自定义拦截器

    千次阅读 2018-03-30 18:49:01
    需求背景: 在插入数据时需要提前设置 ID 和创建时间, 在更新时设置修改时间. 实现: 定义 Mybatis 拦截器只...mybatis 的四大对象:[ParameterHandler],[ResultSetHandler],[StatementHandler],[Executor]. me...
  • mybatis插件功能非常强大,可以让我们无侵入式的对SQL的执行进行干涉,从SQL语句...MyBatis默认支持对4大对象(Executor,StatementHandler,ParameterHandler,ResultSetHandler)上的方法执行拦截,具体支持的方法...
  • springboot集成mybatis自定义插件开发

    千次阅读 2018-12-23 16:58:21
    什么是mybatis插件 mybatis插件就是在执行数据库操作的时候,对于特定方法进行拦截增强,做一些额外的处理的一种方式。 myabtis的插件的增强原理是利用...ParameterHandler ResultSetHandler 其中: Execu...
  • Mybatis在四大组件(Execurot,StatementHandler,ParameterHandler,ResultSetHandler)处提供了简单易用的插件扩展机制。Mybatis支持对四大核心对象进行拦截,对mybatis来说插件就是拦截器,用来增强核心对象功能...
  • 【mybatis系列】自定义实现拦截器插件Interceptor

    千次阅读 多人点赞 2020-10-24 06:18:07
    目录类型规则介绍intercept(Invocation invocation)plugin(Object target)setProperties(Properties properties)实战 ...2.ParameterHandler:拦截参数的处理。 3.ResultHandler:拦截结果集的处理。 4.StatementHandl
  • Mybatis插件通常意义就是自定义的拦截器,基于业务需求,需要在进行数据库查询之前或者之后进行拦截。如从线程变量中传递参数,动态修改SQL来实现数据的筛选,而不是每次在查询前,手动将条件注入到查询中;或者在不...
  • 文章内容输出来源:拉勾教育Java高薪训练营 插件说明 Mybatis提供了插件这一个扩展功能,可以支持开发者进行按需定制开发,丰富了...参数处理器ParameterHandler(setParameters等方法) 结果集处理器ResultSetHandl.
  • 2.ParameterHandler:拦截参数的处理。 3.ResultHandler:拦截结果集的处理。 4.StatementHandler:拦截Sql语法构建的处理。 规则 Intercepts注解需要一个Signature(拦截点)参数数组。通过Signature来指定拦截哪个...
  • 作者|码农沉思录来源:https://mp.weixin.qq.com/s/8PhJQPSDdrVRDOToJA17DA首先熟悉一下Mybatis的执行过程,如下图:类型先...2.ParameterHandler:拦截参数的处理。3.ResultHandler:拦截结果集的处理。4.Stateme...
  • mybatis的插件,实际上是拦截器,通过这些插件可以改变mybatis的默认行为。mybatis可以拦截的对象有: (1)Executor,执行的SQL全过程,包括组装参数、组装结果返回和执行SQL的...(3)ParameterHandler,执行SQ...
  • 首先熟悉一下Mybatis的执行过程...2.ParameterHandler:拦截参数的处理。3.ResultHandler:拦截结果集的处理。4.StatementHandler:拦截Sql语法构建的处理。1234规则Intercepts注解需要一个Signature(拦截点)参数数...
  • 首先熟悉一下Mybatis的...2.ParameterHandler:拦截参数的处理。 3.ResultHandler:拦截结果集的处理。 4.StatementHandler:拦截Sql语法构建的处理。规则Intercepts注解需要一个Signature(拦截点)参数数组。通过Si...
  • 本文同名博客老炮说Java:https://www.laopaojava.com/,每天更新Spring/SpringMvc/SpringBoot/实战项目等文章资料首先熟悉一下Mybatis的执行过程,如下图...2.ParameterHandler:拦截参数的处理。 3.ResultHandler...
  • 问题1:四大对象什么时候被代理,也就是:代理对象是什么时候创建的? 问题2:多个插件的情况下,代理能不能被代理?代理顺序和调用顺序的...里面包含了处理参数的ParameterHandler 和处理结果集的ResultSetHandler
  • 本文同名博客老炮说Java:https://www.laopaojava.com/,每天更新Spring/SpringMvc/SpringBoot/实战项目等文章资料首先熟悉一下Mybatis的执行过程,如下图...2.ParameterHandler:拦截参数的处理。 3.ResultHandler...
  • MyBatis 允许你在映射语句执行过程中的某一点进行拦截调用。默认情况下,MyBatis 允许使用插件来拦截的方法...ParameterHandler (getParameterObject, setParameters) ResultSetHandler (handleResultSets, handleOut
  • 基于retrofit2.1.0 核心类介绍 ParameterHandler 解析方法参数的注解获取他们信息,然后调用转换器... 转换器接口,我们自定义一些实现,可以通过它自定义,进行请求参数数据转换,相应参数自定义解析,还有设置数...
  • MyBatis插件开发基础

    2020-07-15 17:33:23
    四个处理:StatementHandler ParameterHandler ResultSetHandler TypeHandler ...自定义插件的编写逻辑: 根据MyBatis规则 编写一个 拦截器 ,在拦截器内部加入 自定义增强功能。 下面举例实现一个拦截查询
  • MyBatis 源码 学习一

    2015-05-20 17:31:50
    Configuration: MyBatis在运行期的基本上所有的数据...MyBatis允许用户的自定义插件可以拦截ParameterHandler,ResultSetHandler,StatementHandler,Executor接口,从而进行一些操作。     SqlSessionFacto...

空空如也

空空如也

1 2 3
收藏数 49
精华内容 19
关键字:

自定义parameterhandler