mybatis-spring 框架原理与源码解析--执行流程

本文从用户在Spring项目中调用Mapper接口执行查询开始,详细解析mybatis的执行流程,涉及MapperProxy、MapperMethod、SqlSessionTemplate、SqlSessionInterceptor等关键步骤,包括SQL参数转换、SqlSession的创建与操作、查询执行等,概述了mybatis一次查询的基本步骤,并预告将深入探讨XML和注解Mapper解析、插件机制、ParameterHandler、ResultSetHandler、TypeHandler及Spring事务管理。
摘要由CSDN通过智能技术生成

上一篇文章https://blog.csdn.net/yange1025/article/details/84709273介绍了如何在Spring项目中配置mybatis以及mybatis的启动过程。本篇文章将从用户发起一笔查询到返回查询结果来介绍mybatis的执行流程。

入口从用户从Spring容器获取Mapper接口对应的bean,并调用接口方法执行查询开始。我们知道从Spring容器获取的Mapper bean是通过动态代理生成的,其所有方法的调用都会转嫁到MapperProxy的invoke方法

1 org.apache.ibatis.binding.MapperProxy#invoke

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      // 如果是Object类中声明的方法,则直接反射调用该方法
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, args);
      }
      // 如果是接口中的default方法,则通过Java动态语言支持MethodHandle调用
      else if (isDefaultMethod(method)) {
        return invokeDefaultMethod(proxy, method, args);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
    // 其他的是Mapper接口方法的实现
    final MapperMethod mapperMethod = cachedMapperMethod(method);
    return mapperMethod.execute(sqlSession, args);
  }

1.1 org.apache.ibatis.binding.MapperMethod#execute

  public Object execute(SqlSession sqlSession, Object[] args) {
    Object result;
    // command的name是mapper接口的方法名,如:com.my.UserMapper.retrieve
    switch (command.getType()) {
      // 插入
      case INSERT: {
      Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.insert(command.getName(), param));
        break;
      }
      // 更新
      case UPDATE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.update(command.getName(), param));
        break;
      }
      // 删除
      case DELETE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.delete(command.getName(), param));
        break;
      }
      // 查询
      case SELECT:
        if (method.returnsVoid() && method.hasResultHandler()) { // 无返回值
          executeWithResultHandler(sqlSession, args);
          result = null;
        } else if (method.returnsMany()) { // 返回集合
          result = executeForMany(sqlSession, args);
        } else if (method.returnsMap()) { // 返回Map
          result = executeForMap(sqlSession, args);
        } else if (method.returnsCursor()) { // 游标查询
          result = executeForCursor(sqlSession, args);
        } else { // 单条记录查询
          // 将方法参数转换成sql参数
          Object param = method.convertArgsToSqlCommandParam(args);
          // 调用sqlSession执行查询
          result = sqlSession.selectOne(command.getName(), param);
        }
        break;
      case FLUSH:
        result = sqlSession.flushStatements();
        break;
      default:
        throw new BindingException("Unknown execution method for: " + command.getName());
    }
    if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
      
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值