10、自定义mybatis的plugin拦截器

利用mybatis的拦截器,拦截其他的方法

在上一篇中我知道拦截器的入口在InterceptorChain中的putAll,
由putAll方法生成对象的代理,由代理的对象执行对象的方法。
因此只要得到InterceptorChain对象,则一切就可以解决了。
Configuration没有提供interceptorChain属性的get方法。

因此需要修改源码,为interceptorChain属性添加get方法。

修改源码

方法由两种
1. 直接下载源码修改后编译
2. 在本地的项目中键包org.apache.ibatis.session,然后在包下面建类
Configuration,把原来Configuration类中的内容复制过去,在修改,
当本地有和源码中有相同的类名切具有相同的包的时候,优先加载本地的

具体实现

Configuration类

package org.apache.ibatis.session;


/**
 * @author Clinton Begin
 */
public class Configuration {
   

    protected final MapperRegistry mapperRegistry = new MapperRegistry(this);
    protected final InterceptorChain interceptorChain = new InterceptorChain();
    protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
    protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
    protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection");
    protected final Map<String, Cache> caches = new StrictMap<Cache>("Caches collection");
    protected final Map<String, ResultMap> resultMaps = new StrictMap<ResultMap>("Result Maps collection");
    protected final Map<String, ParameterMap> parameterMaps = new StrictMap<ParameterMap>("Parameter Maps collection");
    protected final Map<String, KeyGenerator> keyGenerators = new StrictMap<KeyGenerator>("Key Generators collection");
    protected final Set<String> loadedResources = new HashSet<String>();
    protected final Map<String, XNode> sqlFragments = new StrictMap<XNode>("XML fragments parsed from previous mappers");
    protected final Collection<XMLStatementBuilder> incompleteStatements = new LinkedList<XMLStatementBuilder>();
    protected final Collection<CacheRefResolver> incompleteCacheRefs = new LinkedList<CacheRefResolver>();
    protected final Collection<ResultMapResolver> incompleteResultMaps = new LinkedList<ResultMapResolver>();
    protected final Collection<MethodResolver> incompleteMethods = new LinkedList<MethodResolver>();
    /*
     * A map holds cache-ref relationship. The key is the namespace that
     * references a cache bound to another namespace and the value is the
     * namespace which the actual cache is bound to.
     */
    protected final Map<String, String> cacheRefMap = new HashMap<String, String>();

    protected Environment environment;
    //setting的配置
    /**
     * 1.该配置影响的所有映射器中配置的缓存的全局开关。
     */
    protected boolean cacheEnabled = true;
    /**
     * 2.延迟加载的全局开关。当开启时,所有关联对象都会延迟加载。 特定关联关系中可通过设置fetchType属性来覆盖该项的开关状态。
     */
    protected boolean lazyLoadingEnabled = false;
    /**
     * 3.当开启时,任何方法的调用都会加载该对象的所有属性。否则,每个属性会按需加载。默认false
     */
    protected boolean aggressiveLazyLoading;
    /**
     * 4. 是否允许单一语句返回多结果集(需要兼容驱动)。
     */
    protected boolean multipleResultSetsEnabled = true;
    /**
     * 5.使用列标签代替列名。不同的驱动在这方面会有不同的表现
     */
    protected boolean useColumnLabel = true;
    /**
     * 6.允许 JDBC 支持自动生成主键,需要驱动兼容
     */
    protected boolean useGeneratedKeys;
    /**
     * 7.指定 MyBatis 应如何自动映射列到字段或属性。
     * NONE 表示取消自动映射;
     * PARTIAL 只会自动映射没有定义嵌套结果集映射的结果集。(意思就是映射文件中,对于resultMap标签,如果没有显式定义result标签,
     * mybatis不会帮你把结果映射到model(pojo)上.除了id属性有具体值外,其余都没有)
     * FULL 会自动映射任意复杂的结果集(无论是否嵌套)。
     */
    protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL;
    /**
     * 8.指定发现自动映射目标未知列(或者未知属性类型)的行为。
     * NONE: 不做任何反应
     * WARNING: 输出提醒日志 ('org.apache.ibatis.session.AutoMappingUnknownColumnBehavior' 的日志等级必须设置为 WARN)
     * FAILING: 映射失败 (抛出 SqlSessionException)
     */

    protected AutoMappingUnknownColumnBehavior autoMappingUnknownColumnBehavior = AutoMappingUnknownColumnBehavior.NONE;
    /**
     * 9. 配置默认的执行器。
     * SIMPLE 就是普通的执行器;REUSE 执行器会重用预处理语句(prepared statements);
     * BATCH 执行器将重用语句并执行批量更新。
     */
    protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
    /**
     * 10.设置超时时间,它决定驱动等待数据库响应的秒数。
     */
    protected Integer defaultStatementTimeout;
    /**
     * 11.果集获取数量(fetchSize)设置一个提示值,此参数只可以在查询设置中被覆盖。
     */
    protected Integer defaultFetchSize;
    /**
     * 12. 允许在嵌套语句中使用分页(RowBounds)。 If allow, set the false.
     */
    protected boolean safeRowBoundsEnabled;
    /**
     * 13.允许在嵌套语句中使用分页(ResultHandler)。 If allow, set the false.
     */
    protected boolean safeResultHandlerEnabled = true;
    /**
     * 14.是否开启自动驼峰命名规则(camel case)映射
     */
    protected boolean mapUnderscoreToCamelCase;
    /**
     * 15. MyBatis 利用本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询。
     * 默认值为 SESSION,这种情况下会缓存一个会话中执行的所有查询。
     * 若设置值为 STATEMENT,本地会话仅用在语句执行上,对相同 SqlSession 的不同调用将不会共享数据。
     */
    protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
    /**
     * 16.当没有为参数提供特定的 JDBC 类型时,为空值指定 JDBC 类型
     */
    protected JdbcType jdbcTypeForNull = JdbcType.OTHER;
    /**
     * 17. 指定哪个对象的方法触发一次延迟加载。
     */
    protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(Arrays.asList(new String[]{
  "equals", "clone", "hashCode", "toString"}));
    /**
     * 18. 指定动态 SQL 生成的默认语言。
     */
    protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry();
    /**
     * 19. 指定当结果集中值为 null 的时候是否调用映射对象的 setter(map 对象时为 put)方法,
     * 这对于有 Map.keySet() 依赖或 null 值初始化的时候是有用的。
     * 注意基本类型(int、boolean等)是不能设置成 null 的。
     */
    protected boolean callSettersOnNulls;
    /**
     * 20. 当返回行的所有列都是空时,MyBatis默认返回null。
     * 当开启这个设置时,MyBatis会返回一个空实例。
     * 它也适用于嵌套的结果集 (i.e. collectioin and association)。(从3.4.2开始)
     */
    protected boolean returnInstanceForEmptyRow;
    /**
     * 21.指定 MyBatis 增加到日志名称的前缀。
     */
    protected String logPrefix;
    /**
     * 22.指定 MyBatis 所用日志的具体实现,未指定时将自动查找。
     */
    protected Class<? extends Log> logImpl;
    /**
     * 23. 指定 Mybatis 创建具有延迟加载能力的对象所用到的代理工具。默认JAVASSIST
     * CGLIB | JAVASSIST
     */
    protected ProxyFactory proxyFactory = new JavassistProxyFactory(); // #224 Using internal Javassist instead of OGNL



    /**
     * 24.指定VFS的实现(虚拟文件系统)
     */
    protected Class<? extends VFS> vfsImpl;
    /**
     * 25.允许使用方法签名中的名称作为语句参数名称。
     * 为了使用该特性,你的工程必须采用Java 8编译,并且加上-parameters选项。(从3.4.1开始)
     */
    protected boolean useActualParamName = true;
    /**26.
     * Configuration factory class.
     * Used to create Configuration for loading deserialized unread properties.
     *
     * @see <a href='https://code.google.com/p/mybatis/issues/detail?id=300'>Issue 300 (google code)</a>
     */
    protected Class<?> configurationFactory;
    protected Properties variables = new Properties();
    protected ReflectorFactory reflectorFactory = new DefaultReflectorFactory();
    protected ObjectFactory objectFactory = new DefaultObjectFactory();
    prote
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
MyBatis提供了自定义拦截的功能,可以在执行SQL语句前后进行一些自定义的操作,比如日志记录、权限校验等。要实现自定义拦截,你需要按照以下步骤进行操作: 1. 创建一个Java类,实现`Interceptor`接口。这个接口定义MyBatis拦截的方法。 ```java public class MyInterceptor implements Interceptor { @Override public Object intercept(Invocation invocation) throws Throwable { // 在执行SQL语句前后进行一些自定义操作 // 这里可以写你的逻辑代码 return invocation.proceed(); // 继续执行下一个拦截或目标对象的方法 } @Override public Object plugin(Object target) { return Plugin.wrap(target, this); // 使用当前拦截包装目标对象 } @Override public void setProperties(Properties properties) { // 设置一些属性值 } } ``` 2. 在MyBatis配置文件(比如`mybatis-config.xml`)中配置自定义拦截。 ```xml <configuration> <!-- 其他配置 --> <plugins> <plugin interceptor="com.example.MyInterceptor"> <!-- 可以设置一些属性值 --> </plugin> </plugins> </configuration> ``` 注意,`com.example.MyInterceptor`是你自己实现的拦截类的全限定名。 通过以上步骤,你就可以实现自定义拦截了。当MyBatis执行SQL语句时,会先调用你的拦截的`intercept`方法,在该方法内部你可以编写你想要的逻辑。还可以通过`plugin`方法对目标对象进行包装,以实现多个拦截的链式调用。 希望能帮到你!如有更多问题,请继续提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值