ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Mybatis拦截器介绍

2020-12-31 15:32:33  阅读:253  来源: 互联网

标签:拦截器 statement 介绍 SQLException Statement Mybatis 拦截 throws


一、Mybatis拦截器介绍

  Mybatis拦截器设计的思路是为了供用户灵活的实现自己的逻辑,而不动mybatis固有的逻辑,简而言之就是如果Mybatis是一只虾,我们要做的是将虾肉掏空,放入自己喜欢吃的东西进去,而依旧保持吓得壳身。通过Mybatis拦截器我们能拦截某些方法的调用,我们可以选择在这些被拦截方法执行前后加上我们自己的逻辑,达到丰富方法的效果;也可以在执行这些方法的时候拦截住,转而实现自己设计的方法,而最后不执行被拦截的方法。Mybatis中有很多核心对象,大致如下:

SqlSession 负责和数据库进行交互,实现完成常对数据操作的增删改查功能
Executor Mybatis执行器,调度的核心,负责SQL语句的生成和维护
StatementHandler 封装并操作Jdbc statement,例如设置参数,将statement结果集转化为List集合
ParameterHandler 负责将用户传递的参数转换为Jdbc statement所需要的参数进行传递
ResultSetHandler 负责将Jdbc返回的ResultSet结果集对象转换为List类型的集合
TypeHandler 负责将java数据类型和Jdbc数据类型之间的转换和映射
MappedStatement MappedStatement维护了一条mapper.xml文件里面 select 、update、delete、insert节点的封装
Configuration MyBatis所有的配置信息都维持在Configuration对象之中
BoundSql 表示动态生成的SQL语句以及相应的参数信息

 

 

 

 

 

 

 

 

 

 

 

Mybatis拦截器并不能拦截mybatis核心对象中所有方法,相反的,MyBatis拦截器可以拦截四个对象中方法,分别是:Executor、StatementHandler、ParameterHandler 和ResultSetHandler。

 1. Executor

Executor是mybatis核心接口,数据库增删改语句是通过Executor接口的update方法进行的,查询是通过query方法进行,代码如下:

public interface Executor {
    /*
    * 执行update/insert/delete
    * */
    int update(MappedStatement ms , Object paramter)throws SQLException;

    /*
    * 执行查询,先在缓存中查找
    * Mybatis提供了一个简单的逻辑分页使用类RowBounds(物理分页当然就是我们在sql语句中指定limit和offset值),在DefaultSqlSession提供的某些查询接口中我们可以看到RowBounds是作为参数用来进行分页的
    * */
    <E> List<E> query(MappedStatement ms , Object paramter , RowBounds rowBounds , ResultSetHandler resultSetHandler , CacheKey cacheKey , BoundSql boundSql)throws SQLException;

    /*
    * 执行查询
    * */
     <E> List<E> query(MappedStatement ms , Object paramter , ResultSetHandler resultSetHandler)throws SQLException;

     /*
     * 执行查询,结果放在Cursor里面
     * */
     <E> Cursor<E> queryCursor(MappedStatement ms , Object paramter)throws SQLException;
     
}

2. ParameterHandler

ParameterHandler用来设置参数规则,当StatementHandler使用prepare()方法后,接下来就是使用它来设置参数。所以如果有对参数做自定义逻辑处理的时候,可以通过拦截ParameterHandler来实现。ParameterHandler里面可以拦截的方法解释如下:

public interface ParameterHandler {
    /*
    * 设置参数规则的时候使用——PreparedStatement
    * */
    void setParamters(PreparedStatement ps) throws SQLException;
}

3. StatementHandler

StatementHandler负责处理Mybatis与JDBC之间Statement的交互。

 

public interface StatementHandler {
    /*
    * 从连接中获取一个Statement
    * */
    Statement prepare(Connection conn , Integer transactionTimeout)throws SQLException;

    /*
    * 设置statement执行里需要的参数
    * */
    void paramterize(Statement statement)throws SQLException;

    /**
     * 批量
     */
    void batch(Statement statement)
            throws SQLException;

    /**
     * 更新:update/insert/delete语句
     */
    int update(Statement statement)
            throws SQLException;

    /**
     * 执行查询
     */
    <E> List<E> query(Statement statement, ResultHandler resultHandler)
            throws SQLException;

    <E> Cursor<E> queryCursor(Statement statement)
            throws SQLException;
}

一般只拦截prepare方法。

在Mybatis里面RoutingStatementHandler是SimpleStatementHandler(对应Statement)、PreparedStatementHandler(对应PreparedStatement)、CallableStatementHandler(对应CallableStatement)的路由类,所有需要拦截StatementHandler里面的方法的时候,对RoutingStatementHandler做拦截处理就可以了,如下的写法可以过滤掉一些不必要的拦截类。

@Intercepts({
        @Signature(
                type = Statement.class ,
                method =  "prepare",
                args = {Connection.class , Integer.class}
        )
})
public class TableShardInterceptor implements Interceptor {
    /*
    * mybatis运行时要执行的拦截方法
    * */
    @Override
    public Object intercept(Invocation invocation ) throws Throwable{
        if(invocation.getTarget()instanceof RoutingStatementHandler){
            //to do 自己的逻辑
        }
        return invocation.proceed();
    }
    /*
    * target:拦截对象
    *
    * */
    @Override
    public Object plugin(Object target){
        // 当目标类是StatementHandler类型时,才包装目标类,否者直接返回目标本身,减少目标被代理的次数
        return (target instanceof RoutingStatementHandler)? Plugin.wrap(target,this):target;
    }
    //实现插件参数传递
    @Override
    public void setProperties(Properties properties){

    }


}

 4. ResultSetHandler

  ResultSetHandler用于对查询到的结果做处理。所以如果你有需求需要对返回结果做特殊处理的情况下可以去拦截ResultSetHandler的处理。ResultSetHandler里面常用拦截方法如下:

public interface ResultSetHandler {
    /*
    * 将statement执行后产生的结果集(可能有多个结果集)映射为结果表
    * */
    <E> List<E> handResultSets(Statement stmt)throws SQLException;
    <E> List<E> handleCursorResultSet(Statement stmt)throws SQLException;

    /*
    * 处理存储过程执行后的输出参数
    * */
    void handleOutputParameters(CallableStatement cs) throws SQLException;
}

至此,拦截器介绍由此结束。

部分内容参考自:https://blog.csdn.net/wuyuxing24/article/details/89343951

标签:拦截器,statement,介绍,SQLException,Statement,Mybatis,拦截,throws
来源: https://www.cnblogs.com/yeyuting/p/14212527.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有