最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

MyBatis核心源碼深度剖析SQL語(yǔ)句執(zhí)行過程

 更新時(shí)間:2022年05月20日 14:05:24   作者:趙廣陸  
這篇文章主要介紹了MyBatis核心源碼深度剖析SQL執(zhí)行過程,mybatis執(zhí)行SQL的流程都是根據(jù)statement字符串從configuration中獲取對(duì)應(yīng)的mappedStatement,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友參考下吧

1 SQL語(yǔ)句的執(zhí)行過程介紹

MyBatis核心執(zhí)行組件:

在這里插入圖片描述

2 SQL執(zhí)行的入口分析

2.1 為Mapper接口創(chuàng)建代理對(duì)象

// 方式1:
User user = session.selectOne("com.oldlu.dao.UserMapper.findUserById", 101);
// 方式2:
UserMapper mapper = session.getMapper(UserMapper.class);
List<User> userList = mapper.findAll();

2.2 執(zhí)行代理邏輯

方式1入口分析:
session是DefaultSqlSession類型的,因?yàn)閟qlSessionFactory默認(rèn)生成的SqlSession是
DefaultSqlSession類型。
selectOne()會(huì)調(diào)用selectList()。

// DefaultSqlSession類
public <E> List<E> selectList(String statement, Object parameter, RowBounds
rowBounds) {
  try {
    MappedStatement ms = configuration.getMappedStatement(statement);
    // CURD操作是交給Excetor去處理的
    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();
 }
}

方式2入口分析:
獲取代理對(duì)象:

//DefaultSqlSession類 ====================>
@Override
public <T> T getMapper(Class<T> type) {
  return configuration.getMapper(type, this);
  }
// Configuration類 ====================>
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
  return mapperRegistry.getMapper(type, sqlSession);
}
//MapperRegistry ----> apperProxyFactory.newInstance ====================>
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
  //從緩存中獲取該Mapper接口的代理工廠對(duì)象
  final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>)
knownMappers.get(type);
  //如果該Mapper接口沒有注冊(cè)過,則拋異常
  if (mapperProxyFactory == null) {
    throw new BindingException("Type " + type + " is not known to the
MapperRegistry.");
 }
  try {
    //【使用代理工廠創(chuàng)建Mapper接口的代理對(duì)象】
    return mapperProxyFactory.newInstance(sqlSession);
 } catch (Exception e) {
    throw new BindingException("Error getting mapper instance. Cause: " + e,
e);
 }
}
//MapperProxyFactory  --->此時(shí)生成代理對(duì)象 ====================>
protected T newInstance(MapperProxy<T> mapperProxy) {
  //Mybatis底層是調(diào)用JDK的Proxy類來創(chuàng)建代理實(shí)例
  return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new
Class[] { mapperInterface }, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
  final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession,
mapperInterface, methodCache);
  return newInstance(mapperProxy);
}

代理對(duì)象執(zhí)行邏輯:

//MapperProxy   ====================>
/**代理對(duì)象執(zhí)行的方法,代理以后,所有Mapper的方法調(diào)用時(shí),都會(huì)調(diào)用這個(gè)invoke方法*/
public Object invoke(Object proxy, Method method, Object[] args) throws
Throwable {
 try {
  if (Object.class.equals(method.getDeclaringClass())) {
   //如果是Object方法,則調(diào)用方法本身
   return method.invoke(this, args);
 } else {
   //調(diào)用接口方法:根據(jù)被調(diào)用接口的Method對(duì)象,從緩存中獲取MapperMethodInvoker對(duì)象
   //apper接口中的每一個(gè)方法都對(duì)應(yīng)一個(gè)MapperMethodInvoker對(duì)象,而MapperMethodInvoker
對(duì)象里面的MapperMethod保存著對(duì)應(yīng)的SQL信息和返回類型以完成SQL調(diào)用 ...
   return cachedInvoker(method).invoke(proxy, method, args, sqlSession);
 }
} catch (Throwable t) {
  throw ExceptionUtil.unwrapThrowable(t);
}
}
/**
獲取緩存中MapperMethodInvoker,如果沒有則創(chuàng)建一個(gè),而MapperMethodInvoker內(nèi)部封裝這一
個(gè)MethodHandler
*/
private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {
  try {
    return methodCache.computeIfAbsent(method, m -> {
      if (m.isDefault()) {
        //如果調(diào)用接口的是默認(rèn)方法(default方法)
        try {
          if (privateLookupInMethod == null) {
            return new
DefaultMethodInvoker(getMethodHandleJava8(method));
         } else {
            return new
DefaultMethodInvoker(getMethodHandleJava9(method));
         }
       } catch (IllegalAccessException | InstantiationException |
InvocationTargetException
            | NoSuchMethodException e) {
          throw new RuntimeException(e);
       }
     } else {
        //如果調(diào)用的普通方法(非default方法),則創(chuàng)建一個(gè)PlainMethodInvoker并放
入緩存,其中MapperMethod保存對(duì)應(yīng)接口方法的SQL以及入?yún)⒑统鰠⒌臄?shù)據(jù)類型等信息
        return new PlainMethodInvoker(new MapperMethod(mapperInterface,
method, sqlSession.getConfiguration()));
     }
   });
 } catch (RuntimeException re) {
    Throwable cause = re.getCause();
throw cause == null ? re : cause;
 }
}
// MapperProxy內(nèi)部類: PainMethodInvoker  ====================>
// 當(dāng)cacheInvoker返回了PalinMethodInvoker實(shí)例之后,緊接著調(diào)用了這個(gè)實(shí)例的
PlainMethodInvoker:invoke方法
@Override
public Object invoke(Object proxy, Method method, Object[] args, SqlSession
sqlSession) throws Throwable {
 //Mybatis實(shí)現(xiàn)接口方法的核心: MapperMethod::execute方法:
 return mapperMethod.execute(sqlSession, args);
}
// MapperMethod  ====================>
public Object execute(SqlSession sqlSession, Object[] args) {
  Object result;
  switch (command.getType()) {
    case INSERT: {
      // 將args進(jìn)行解析,如果是多個(gè)參數(shù)則,則根據(jù)@Param注解指定名稱將參數(shù)轉(zhuǎn)換為Map,
如果是封裝實(shí)體則不轉(zhuǎn)換
      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 {
        //解析參數(shù),因?yàn)镾qlSession::selectOne方法參數(shù)只能傳入一個(gè),但是我們
Mapper中可能傳入多個(gè)參數(shù),
        //有可能是通過@Param注解指定參數(shù)名,所以這里需要將Mapper接口方法中的多個(gè)參
數(shù)轉(zhuǎn)化為一個(gè)ParamMap,
        //也就是說如果是傳入的單個(gè)封裝實(shí)體,那么直接返回出來;如果傳入的是多個(gè)參數(shù),
實(shí)際上都轉(zhuǎn)換成了Map
        Object param = method.convertArgsToSqlCommandParam(args);
        //可以看到動(dòng)態(tài)代理最后還是使用SqlSession操作數(shù)據(jù)庫(kù)的
        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;
}
// 此時(shí)我們發(fā)現(xiàn): 回到了sqlsession中
private <E> Object executeForMany(SqlSession sqlSession, Object[] args) {
  List<E> result;
  Object param = method.convertArgsToSqlCommandParam(args);
  if (method.hasRowBounds()) {
   RowBounds rowBounds = method.extractRowBounds(args);
   result = sqlSession.selectList(command.getName(), param, rowBounds);
 } else {
   result = sqlSession.selectList(command.getName(), param);
 }
 // ...
  return result;
}

在這里插入圖片描述

3 查詢語(yǔ)句的執(zhí)行過程分析

3.1 selectOne方法分析

// DefaultSqlSession類  ===============>
// selectOne
@Override
public <T> T selectOne(String statement, Object parameter) {
  // //selectOne()會(huì)調(diào)用selectList()。
  List<T> list = this.selectList(statement, parameter);
  if (list.size() == 1) {
    return list.get(0);
 } else if (list.size() > 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 ms = configuration.getMappedStatement(statement);
    // CURD操作是交給Excetor去處理的
    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();
 }
}

3.2 sql獲取

// CachingExecutor ===============>
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds
rowBounds, ResultHandler resultHandler) throws SQLException {
  // 獲取綁定的sql命令,比如"SELECT * FROM xxx"
  BoundSql boundSql = ms.getBoundSql(parameterObject); 
  CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
  return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
@Override
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);
}
//真正執(zhí)行query操作的是SimplyExecutor代理來完成的,SimplyExecutor的父類BaseExecutor的
query方法中:
// BaseExecutor類:SimplyExecutor的父類 =================>
@Override
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());
  if (closed) {
    throw new ExecutorException("Executor was closed.");
 }
  if (queryStack == 0 && ms.isFlushCacheRequired()) {
    clearLocalCache();
 }
  List<E> list;
  try {
    queryStack++;
    //localCache是一級(jí)緩存,如果找不到就調(diào)用queryFromDatabase從數(shù)據(jù)庫(kù)中查找
    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;
}
//第一次,沒有緩存,所以會(huì)調(diào)用queryFromDatabase方法來執(zhí)行查詢。
private <E> List<E> queryFromDatabase(...) throws SQLException {
  List<E> list;
  localCache.putObject(key, EXECUTION_PLACEHOLDER);
  try {
    // 查詢
    list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
 } finally {
    localCache.removeObject(key);
 }
  localCache.putObject(key, list);
  if (ms.getStatementType() == StatementType.CALLABLE) {
    localOutputParameterCache.putObject(key, parameter);
 }
  return list;
}
// SimpleExecutor類 ============================>
public <E> List<E> doQuery(...) throws SQLException {
  Statement stmt = null;
  try {
    Configuration configuration = ms.getConfiguration();
    StatementHandler handler = configuration.newStatementHandler(....);
    // 1:SQL查詢參數(shù)的設(shè)置
    stmt = prepareStatement(handler, ms.getStatementLog());
    // StatementHandler封裝了Statement
    // 2:SQL查詢操作和結(jié)果集的封裝
    return handler.<E>query(stmt);
 } finally {
    closeStatement(stmt);
 }
}

3.3 參數(shù)設(shè)置

// SimplyExecutor類 ============================>
// 【1】 參數(shù)設(shè)置: prepareStatement
private Statement prepareStatement(StatementHandler handler, Log statementLog)
throws SQLException {
  Statement stmt;
  // 通過getConnection方法來獲取一個(gè)Connection,
  Connection connection = getConnection(statementLog);
  // 調(diào)用prepare方法來獲取一個(gè)Statement
  stmt = handler.prepare(connection, transaction.getTimeout());
 
  // 設(shè)置SQL查詢中的參數(shù)值 ***
  handler.parameterize(stmt);
  return stmt;
}
// RoutingStatementHandler ============================>
// PreparedStatementHandler ============================>
@Override
public void parameterize(Statement statement) throws SQLException {
  parameterHandler.setParameters((PreparedStatement) statement);
}
// DefaultParameterHandler ============================> 此時(shí)參數(shù)設(shè)置成功
@Override
public void setParameters(PreparedStatement ps) {
  ErrorContext.instance().activity("setting
parameters").object(mappedStatement.getParameterMap().getId());
  List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
  if (parameterMappings != null) {
    for (int i = 0; i < parameterMappings.size(); i++) {
      ParameterMapping parameterMapping = parameterMappings.get(i);
      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);
       }
        TypeHandler typeHandler = parameterMapping.getTypeHandler();
        JdbcType jdbcType = parameterMapping.getJdbcType();
        if (value == null && jdbcType == null) {
          jdbcType = configuration.getJdbcTypeForNull();
       }
      try {
          typeHandler.setParameter(ps, i + 1, value, jdbcType);
       } catch (TypeException | SQLException e) {
          throw new TypeException("Could not set parameters for
mapping.....");
       }
     }
   }
 }
}

3.4 SQL執(zhí)行和結(jié)果集的封裝

// RoutingStatementHandler ============================>
@Override
public <E> List<E> query(Statement statement) throws SQLException {
  return delegate.<E>query(statement);
}
// PreparedStatementHandler ============================>
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler)
throws SQLException {
  // 這里就到了熟悉的PreparedStatement了
  PreparedStatement ps = (PreparedStatement) statement;
  // 執(zhí)行SQL查詢操作
  ps.execute();
  // 結(jié)果交給ResultHandler來處理
  return resultSetHandler.<E> handleResultSets(ps);
}
// DefaultResultSetHandler類(封裝返回值,將查詢結(jié)果封裝成Object對(duì)象)
@Override
public List<Object> handleResultSets(Statement stmt) throws SQLException {
  ErrorContext.instance().activity("handling
results").object(mappedStatement.getId());
  final List<Object> multipleResults = new ArrayList<Object>();
  int resultSetCount = 0;
  ResultSetWrapper rsw = getFirstResultSet(stmt);
  List<ResultMap> resultMaps = mappedStatement.getResultMaps();
 int resultMapCount = resultMaps.size();
  validateResultMapsCount(rsw, resultMapCount);
  while (rsw != null && resultMapCount > resultSetCount) {
    ResultMap resultMap = resultMaps.get(resultSetCount);
    handleResultSet(rsw, resultMap, multipleResults, null);
    rsw = getNextResultSet(stmt);
    cleanUpAfterHandlingResultSet();
    resultSetCount++;
 }
  String[] resultSets = mappedStatement.getResultSets();
  if (resultSets != null) {
    while (rsw != null && resultSetCount < resultSets.length) {
      ResultMapping parentMapping =
nextResultMaps.get(resultSets[resultSetCount]);
      if (parentMapping != null) {
        String nestedResultMapId = parentMapping.getNestedResultMapId();
        ResultMap resultMap =
configuration.getResultMap(nestedResultMapId);
        handleResultSet(rsw, resultMap, null, parentMapping);
     }
      rsw = getNextResultSet(stmt);
      cleanUpAfterHandlingResultSet();
      resultSetCount++;
   }
 }
  return collapseSingleResultList(multipleResults);
}

在這里插入圖片描述

4 更新語(yǔ)句的執(zhí)行過程分析

  • xecutor 的 update 方法分析
  • insert、update 和 delete 操作都會(huì)清空一二級(jí)緩存
  • doUpdate 方法
  • PreparedStatementHandler 的 update 方法
  • 默認(rèn)是創(chuàng)建PreparedStatementHandler,然后執(zhí)行prepareStatement方法。
  • 執(zhí)行結(jié)果為受影響行數(shù)
  • 執(zhí)行更新語(yǔ)句的SQL

4.1 sqlsession增刪改方法分析

// DefaultSqlSession ===============>
@Override
 public int insert(...) {
  return update(statement, parameter);
}
 @Override
 public int update(String statement) {
  return update(statement, null);
}
 @Override
  public int delete(...) {
  return update(....);
}
// insert 、delete操作是通過調(diào)用update語(yǔ)句進(jìn)行的相關(guān)邏輯
 @Override
 public int update(String statement, Object parameter) {
  try {
   dirty = true;
   MappedStatement ms = configuration.getMappedStatement(statement);
   // 增刪改 最終底層都是 update
   return executor.update(ms, wrapCollection(parameter));
   
 } catch (Exception e) {
   throw ExceptionFactory.wrapException("Error updating database. Cause: " +
e, e);
 } finally {
   ErrorContext.instance().reset();
 }
}

4.2 sql獲取

// CachingExecutor  ===============>
@Override
public int update(MappedStatement ms, Object parameterObject) throws
SQLException {
  // 執(zhí)行增刪改,清除緩存
  flushCacheIfRequired(ms);
  // 跳轉(zhuǎn)BaseExecutor
  return delegate.update(ms, parameterObject);
}
// BaseExecutor   ===============>
@Override
public int update(MappedStatement ms, Object parameter) throws SQLException {
  ErrorContext.instance().resource(ms.getResource()).activity("executing an
update").object(ms.getId());
  if (closed) {
    throw new ExecutorException("Executor was closed.");
 }
  // 清除 LocalCache 一級(jí)緩存
  clearLocalCache();
  //執(zhí)行 doUpdate
  return doUpdate(ms, parameter);
}
// SimpleExecutor  ===============>
// doUpdate
@Override
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
  Statement stmt = null;
  try {
    Configuration configuration = ms.getConfiguration();
    StatementHandler handler = configuration.newStatementHandler(...);
    // 【1】.獲取statement,并進(jìn)行參數(shù)映射
    stmt = prepareStatement(handler, ms.getStatementLog());
    // 【2】.handler.update()方法執(zhí)行具體sql指令
    return handler.update(stmt);
 } finally {
    closeStatement(stmt);
 }
}

4.3 參數(shù)設(shè)置

// SimplyExecutor類 ============================>
//【1】 prepareStatement
private Statement prepareStatement(StatementHandler handler, Log statementLog)
throws SQLException {
  Statement stmt;
  Connection connection = getConnection(statementLog);
  // 使用connection對(duì)象信息創(chuàng)建statement,并將超時(shí)時(shí)間綁定
  stmt = handler.prepare(connection, transaction.getTimeout());
  // parameterize方法設(shè)置sql執(zhí)行時(shí)候需要的參數(shù)
  handler.parameterize(stmt);
  return stmt;
}
// RoutingStatementHandler ============================>
// PreparedStatementHandler ============================>
@Override
public void parameterize(Statement statement) throws SQLException {
  parameterHandler.setParameters((PreparedStatement) statement);
}
// DefaultParameterHandler ============================> 此時(shí)參數(shù)設(shè)置成功
@Override
public void setParameters(PreparedStatement ps) {
  ErrorContext.instance().activity("setting
parameters").object(mappedStatement.getParameterMap().getId());
  List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
  if (parameterMappings != null) {
    for (int i = 0; i < parameterMappings.size(); i++) {
      ParameterMapping parameterMapping = parameterMappings.get(i);
      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);
       }
        TypeHandler typeHandler = parameterMapping.getTypeHandler();
        JdbcType jdbcType = parameterMapping.getJdbcType();
        if (value == null && jdbcType == null) {
          jdbcType = configuration.getJdbcTypeForNull();
       }
        try {
          typeHandler.setParameter(ps, i + 1, value, jdbcType);
       } catch (TypeException | SQLException e) {
          throw new TypeException("Could not set parameters for
mapping.....");
       }
     }
   }
 }
}

4.4 SQL執(zhí)行

// RoutingStatementHandler ============================>
 @Override
 public int update(Statement statement) throws SQLException {
  return delegate.update(statement);
}
// PreparedStatementHandler ============================>
@Override
public int update(Statement statement) throws SQLException {
  // 這里就是底層JDBC的PreparedStatement 操作了
  PreparedStatement ps = (PreparedStatement) statement;
  // 執(zhí)行SQL增刪改操作
  ps.execute();
  // 獲取影響的行數(shù)
  int rows = ps.getUpdateCount();
  Object parameterObject = boundSql.getParameterObject();
  KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
  keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
  // 返回影響的行數(shù)
  return rows;
}

5 小結(jié)

mybatis執(zhí)行SQL的流程都是:
1.根據(jù)statement字符串從configuration中獲取對(duì)應(yīng)的mappedStatement;
2.根據(jù)獲取的mappedStatement創(chuàng)建相應(yīng)的Statement實(shí)例;
3.根據(jù)傳入的參數(shù)對(duì)statement實(shí)例進(jìn)行參數(shù)設(shè)置;
4.執(zhí)行statement并執(zhí)行后置操作;

到此這篇關(guān)于MyBatis核心源碼深度剖析SQL執(zhí)行過程的文章就介紹到這了,更多相關(guān)MyBatis核心源碼剖析SQL執(zhí)行過程內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java中的通用路徑轉(zhuǎn)義符介紹

    Java中的通用路徑轉(zhuǎn)義符介紹

    這篇文章主要介紹了Java中的通用路徑轉(zhuǎn)義符介紹,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • JavaWeb之Ajax的基本使用與實(shí)戰(zhàn)案例

    JavaWeb之Ajax的基本使用與實(shí)戰(zhàn)案例

    ajax技術(shù)是使頁(yè)面能局部刷新的一種技術(shù),下面這篇文章主要給大家介紹了關(guān)于JavaWeb之Ajax的基本使用與實(shí)戰(zhàn)案例的相關(guān)資料,文中通過實(shí)例代碼介紹的非常詳細(xì),需要的朋友可以參考下
    2022-08-08
  • Java中四種引用類型詳細(xì)介紹

    Java中四種引用類型詳細(xì)介紹

    這篇文章主要介紹了Java中四種引用類型詳細(xì)介紹的相關(guān)資料,需要的朋友可以參考下
    2017-03-03
  • 使用JPA中@Query 注解實(shí)現(xiàn)update 操作方法(必看)

    使用JPA中@Query 注解實(shí)現(xiàn)update 操作方法(必看)

    下面小編就為大家?guī)硪黄褂肑PA中@Query 注解實(shí)現(xiàn)update 操作方法(必看)。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-06-06
  • 一文了解Java動(dòng)態(tài)代理的原理及實(shí)現(xiàn)

    一文了解Java動(dòng)態(tài)代理的原理及實(shí)現(xiàn)

    動(dòng)態(tài)代理指的是,代理類和目標(biāo)類的關(guān)系在程序運(yùn)行的時(shí)候確定的,客戶通過代理類來調(diào)用目標(biāo)對(duì)象的方法,是在程序運(yùn)行時(shí)根據(jù)需要?jiǎng)討B(tài)的創(chuàng)建目標(biāo)類的代理對(duì)象。本文將通過案例詳細(xì)講解一下Java動(dòng)態(tài)代理的原理及實(shí)現(xiàn),需要的可以參考一下
    2022-07-07
  • Java新特性之Nashorn_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    Java新特性之Nashorn_動(dòng)力節(jié)點(diǎn)Java學(xué)院整理

    這篇文章主要介紹了Java新特性之Nashorn的相關(guān)資料,需要的朋友可以參考下
    2017-06-06
  • springboot接入微信app支付的方法

    springboot接入微信app支付的方法

    本文使用springboot集成微信支付服務(wù),包含微信統(tǒng)一支付訂單接口,以及支付回調(diào)接口等,對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2021-05-05
  • Java SPI機(jī)制原理及代碼實(shí)例

    Java SPI機(jī)制原理及代碼實(shí)例

    這篇文章主要介紹了Java SPI機(jī)制原理及代碼實(shí)例,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-06-06
  • 解決cmd運(yùn)行java程序“找不到文件”提示的方案

    解決cmd運(yùn)行java程序“找不到文件”提示的方案

    在本篇文章里小編給大家分享的是關(guān)于解決cmd運(yùn)行java程序“找不到文件”提示的方案,有需要的朋友們可以參考下。
    2020-02-02
  • Java 重試框架 Sisyphus 配置的兩種方式

    Java 重試框架 Sisyphus 配置的兩種方式

    這一節(jié)讓我們一起學(xué)習(xí)下 sisyphus 基于函數(shù)式的配置和注解式的配置。為了滿足更加方便的配置,Retryer 類提供了許多可以配置的信息。下面一起進(jìn)入文章了解詳情內(nèi)容
    2021-11-11

最新評(píng)論

依安县| 盐津县| 瑞昌市| 武清区| 阿鲁科尔沁旗| 安陆市| 治县。| 汝南县| 铜陵市| 天峻县| 陆丰市| 鹤壁市| 松原市| 江达县| 富锦市| 安仁县| 阿坝| 建瓯市| 桐乡市| 东安县| 泾川县| 黄冈市| 曲靖市| 潞城市| 监利县| 武胜县| 大庆市| 沂水县| 许昌市| 阆中市| 紫阳县| 兖州市| 长宁区| 荥阳市| 电白县| 叙永县| 堆龙德庆县| 泸定县| 浦北县| 紫金县| 荆州市|