MyBatis源码初识三 sql执行流程

源码流程图

在这里插入图片描述

源码分析

获取sqlSession

SqlSession session = sqlSessionFactory.openSession();

openSession

public SqlSession openSession() {
  return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
  Transaction tx = null;
  try {
    //获取环境
    final Environment environment = configuration.getEnvironment();
    //获取事务工厂
    final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
    tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
    //获取执行器(SimpleExecutor--默认|ReuseExecutor|BatchExecutor)
    final Executor executor = configuration.newExecutor(tx, execType);
    //创建DefaultSqlSession返回
    return new DefaultSqlSession(configuration, executor, autoCommit);
  } catch (Exception e) {
    closeTransaction(tx); // may have fetched a connection so lets call close()
    throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
  } finally {
    ErrorContext.instance().reset();
  }
}

创建执行器

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) {
    //把当前的简单的执行器包装成一个CachingExecutor
    executor = new CachingExecutor(executor);
  }
  //拦截器插件包装执行器
  executor = (Executor) interceptorChain.pluginAll(executor);
  return executor;
}

插件

  public Object pluginAll(Object target) {
    for (Interceptor interceptor : interceptors) {
      target = interceptor.plugin(target);
    }
    return target;
  }

创建插件代理

public static Object wrap(Object target, Interceptor interceptor) {
  // 获取interceptor注解中的signature注解
  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;
}

获取mapper代理类

UserMapper mapper = session.getMapper(UserMapper.class);

getMapper方法

public <T> T getMapper(Class<T> type) {
  return configuration.getMapper(type, this);
}

configuration.getMapper

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
  return mapperRegistry.getMapper(type, sqlSession);
}

mapperRegistry.getMapper

public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
  //根据类型从缓存中获取MapperProxyFactory
  final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>) knownMappers.get(type);
  if (mapperProxyFactory == null) {
    throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
  }
  try {
    //通过MapperProxyFactory创建代理类
    return mapperProxyFactory.newInstance(sqlSession);
  } catch (Exception e) {
    throw new BindingException("Error getting mapper instance. Cause: " + e, e);
  }
}

创建mapper的代理类

public T newInstance(SqlSession sqlSession) {
  //真实处理业务的代理对象
  final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession, mapperInterface, methodCache);
  //创建代理
  return newInstance(mapperProxy);
}

protected T newInstance(MapperProxy<T> mapperProxy) {
  //动态代理
  return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}

执行查询

User user = mapper.selectById(1L);

调用代理类的invoke方法

  public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
    try {
      if (Object.class.equals(method.getDeclaringClass())) {
        return method.invoke(this, args);
      } else if (method.isDefault()) {
        return invokeDefaultMethod(proxy, method, args);
      }
    } catch (Throwable t) {
      throw ExceptionUtil.unwrapThrowable(t);
    }
    //缓存并获取MapperMethod
    final MapperMethod mapperMethod = cachedMapperMethod(method);
    //真正执行的方法
    return mapperMethod.execute(sqlSession, args);
  }
public Object execute(SqlSession sqlSession, Object[] args) {
  Object result;
  //判断操作类型
  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()) {
        result = executeForMap(sqlSession, args);
      } else if (method.returnsCursor()) {
        result = executeForCursor(sqlSession, args);
      } else {
        //查询结果集为一个的
        //解析参数
        Object param = method.convertArgsToSqlCommandParam(args);
        //查询单条记录,得到结果
        result = sqlSession.selectOne(command.getName(), param);
        if (method.returnsOptional()
            && (result == null || !method.getReturnType().equals(result.getClass()))) {
          result = Optional.ofNullable(result);
        }
      }
      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()) {
    throw new BindingException("Mapper method '" + command.getName()
        + " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
  }
  return result;
}

selectOne

public <T> T selectOne(String statement, Object parameter) {
  //调用selectList
  List<T> list = this.selectList(statement, parameter);
  //返回一条记录,直接返回
  if (list.size() == 1) {
    return list.get(0);
  } else if (list.size() > 1) {
    //多余1条,报错
    throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
  } else {
    return null;
  }
}

selectList

public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
  try {
    //获取MappedStatement
    MappedStatement ms = configuration.getMappedStatement(statement);
    //调用执行查询
    return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
  } catch (Exception e) {
    throw ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
  } finally {
    ErrorContext.instance().reset();
  }
}

executor.query

public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
  //根据参数解析sql
  BoundSql boundSql = ms.getBoundSql(parameterObject);
  //获取缓存key
  CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
  //查询
  return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}

缓存key生成

  public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {
    if (closed) {
      throw new ExecutorException("Executor was closed.");
    }
    CacheKey cacheKey = new CacheKey();
    //当前方法的id
    cacheKey.update(ms.getId());
    //分页
    cacheKey.update(rowBounds.getOffset());
    cacheKey.update(rowBounds.getLimit());
    //sql
    cacheKey.update(boundSql.getSql());
    List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
    TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();
    // mimic DefaultParameterHandler logic
    for (ParameterMapping parameterMapping : parameterMappings) {
      if (parameterMapping.getMode() != ParameterMode.OUT) {
        Object value;
        String propertyName = parameterMapping.getProperty();
        if (boundSql.hasAdditionalParameter(propertyName)) {
          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);
        }
        //参数
        cacheKey.update(value);
      }
    }
    if (configuration.getEnvironment() != null) {
      //环境
      cacheKey.update(configuration.getEnvironment().getId());
    }
    return cacheKey;
  }

二级缓存查询数据

public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
      throws SQLException {
  //判断是否开启二级缓存
  Cache cache = ms.getCache();
  //如果开启了二级缓存
  if (cache != null) {
    //判断是否需要刷新缓存
    flushCacheIfRequired(ms);
    //判断是否使用缓存
    if (ms.isUseCache() && resultHandler == null) {
      ensureNoOutParams(ms, boundSql);
      //如果使用缓存,从二级缓存中获取
      @SuppressWarnings("unchecked")
      List<E> list = (List<E>) tcm.getObject(cache, key);
      if (list == null) {
        //二级缓存中没有数据,去数据库中查询
        list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
        //放到二级缓存中
        tcm.putObject(cache, key, list); // issue #578 and #116
      }
      return list;
    }
  }
  //没有卡其二级缓存,直接去查询
  return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}

真实查询

public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
  ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
  //已经关闭,则抛出 ExecutorException 异常
  if (closed) {
    throw new ExecutorException("Executor was closed.");
  }
  if (queryStack == 0 && ms.isFlushCacheRequired()) {
    clearLocalCache();
  }
  List<E> list;
  try {
    // 从一级缓存中获取
    queryStack++;
    list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
    // 一级缓存中有数据
    if (list != null) {
      handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
    } else {
      // 一级缓存中无数据,从数据库中获取
      list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
    }
  } finally {
    queryStack--;
  }
  if (queryStack == 0) {
    for (DeferredLoad deferredLoad : deferredLoads) {
      deferredLoad.load();
    }
    deferredLoads.clear();
    if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
      clearLocalCache();
    }
  }
  return list;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值