广告
返回顶部
首页 > 资讯 > 精选 >MyBatis的SQL语句执行过程是什么
  • 760
分享到

MyBatis的SQL语句执行过程是什么

2023-06-30 15:06:22 760人浏览 八月长安
摘要

这篇文章主要介绍“mybatis的sql语句执行过程是什么”,在日常操作中,相信很多人在MyBatis的SQL语句执行过程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MyBatis的SQL语句执行过程

这篇文章主要介绍“mybatissql语句执行过程是什么”,在日常操作中,相信很多人在MyBatis的SQL语句执行过程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MyBatis的SQL语句执行过程是什么”的疑惑有所帮助!接下来,请跟着小编一起来学习吧!

    1 SQL语句的执行过程介绍

    MyBatis核心执行组件:

    MyBatis的SQL语句执行过程是什么

    2 SQL执行的入口分析

    2.1 为Mapper接口创建代理对象

    // 方式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 执行代理逻辑

    方式1入口分析:
    session是DefaultSqlSession类型的,因为sqlSessionFactory默认生成的SqlSession是
    DefaultSqlSession类型。
    selectOne()会调用selectList()。

    // DefaultSqlSession类public <E> List<E> selectList(String statement, Object parameter, RowBoundsrowBounds) {  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入口分析:
    获取代理对象:

    //DefaultSqlSession类 ====================>@Overridepublic <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接口的代理工厂对象  final MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory<T>)knownMappers.get(type);  //如果该Mapper接口没有注册过,则抛异常  if (mapperProxyFactory == null) {    throw new BindingException("Type " + type + " is not known to theMapperRegistry."); }  try {    //【使用代理工厂创建Mapper接口的代理对象】    return mapperProxyFactory.newInstance(sqlSession); } catch (Exception e) {    throw new BindingException("Error getting mapper instance. Cause: " + e,e); }}//MapperProxyFactory  --->此时生成代理对象 ====================>protected T newInstance(MapperProxy<T> mapperProxy) {  //Mybatis底层是调用jdk的Proxy类来创建代理实例  return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), newClass[] { mapperInterface }, mapperProxy);}public T newInstance(SqlSession sqlSession) {  final MapperProxy<T> mapperProxy = new MapperProxy<>(sqlSession,mapperInterface, methodCache);  return newInstance(mapperProxy);}

    代理对象执行逻辑:

    //MapperProxy   ====================>public Object invoke(Object proxy, Method method, Object[] args) throwsThrowable { try {  if (Object.class.equals(method.getDeclarinGClass())) {   //如果是Object方法,则调用方法本身   return method.invoke(this, args); } else {   //调用接口方法:根据被调用接口的Method对象,从缓存中获取MapperMethodInvoker对象   //apper接口中的每一个方法都对应一个MapperMethodInvoker对象,而MapperMethodInvoker对象里面的MapperMethod保存着对应的SQL信息和返回类型以完成SQL调用 ...   return cachedInvoker(method).invoke(proxy, method, args, sqlSession); }} catch (Throwable t) {  throw ExceptionUtil.unwrapThrowable(t);}}private MapperMethodInvoker cachedInvoker(Method method) throws Throwable {  try {    return methodCache.computeIfAbsent(method, m -> {      if (m.isDefault()) {        //如果调用接口的是默认方法(default方法)        try {          if (privateLookupInMethod == null) {            return newDefaultMethodInvoker(getMethodHandleJava8(method));         } else {            return newDefaultMethodInvoker(getMethodHandleJava9(method));         }       } catch (IllegalAccessException | InstantiationException |InvocationTargetException            | NoSuchMethodException e) {          throw new RuntimeException(e);       }     } else {        //如果调用的普通方法(非default方法),则创建一个PlainMethodInvoker并放入缓存,其中MapperMethod保存对应接口方法的SQL以及入参和出参的数据类型等信息        return new PlainMethodInvoker(new MapperMethod(mapperInterface,method, sqlSession.getConfiguration()));     }   }); } catch (RuntimeException re) {    Throwable cause = re.getCause();throw cause == null ? re : cause; }}// MapperProxy内部类: PainMethodInvoker  ====================>// 当cacheInvoker返回了PalinMethodInvoker实例之后,紧接着调用了这个实例的PlainMethodInvoker:invoke方法@Overridepublic Object invoke(Object proxy, Method method, Object[] args, SqlSessionsqlSession) throws Throwable { //Mybatis实现接口方法的核心: MapperMethod::execute方法: return mapperMethod.execute(sqlSession, args);}// MapperMethod  ====================>public Object execute(SqlSession sqlSession, Object[] args) {  Object result;  switch (command.getType()) {    case INSERT: {      // 将args进行解析,如果是多个参数则,则根据@Param注解指定名称将参数转换为Map,如果是封装实体则不转换      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 {        //解析参数,因为SqlSession::selectOne方法参数只能传入一个,但是我们Mapper中可能传入多个参数,        //有可能是通过@Param注解指定参数名,所以这里需要将Mapper接口方法中的多个参数转化为一个ParamMap,        //也就是说如果是传入的单个封装实体,那么直接返回出来;如果传入的是多个参数,实际上都转换成了Map        Object param = method.convertArgsToSqlCommandParam(args);        //可以看到动态代理最后还是使用SqlSession操作数据库的        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 methodwith a primitive return type (" + method.getReturnType() + ")."); }  return result;}// 此时我们发现: 回到了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;}

    MyBatis的SQL语句执行过程是什么

    3 查询语句的执行过程分析

    3.1 selectOne方法分析

    // DefaultSqlSession类  ===============>// selectOne@Overridepublic <T> T selectOne(String statement, Object parameter) {  // //selectOne()会调用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 bereturned by selectOne(), but found: " + list.size()); } else {    return null; }}// selectListpublic <E> List<E> selectList(String statement, Object parameter, RowBoundsrowBounds) {  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, RowBoundsrowBounds, 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);}@Overridepublic <E> List<E> query(MappedStatement ms, Object parameterObject, RowBoundsrowBounds, 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);}//真正执行query操作的是SimplyExecutor代理来完成的,SimplyExecutor的父类BaseExecutor的query方法中:// BaseExecutor类:SimplyExecutor的父类 =================>@Overridepublic <E> List<E> query(MappedStatement ms, Object parameter, RowBoundsrowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throwsSQLException {  ErrorContext.instance().resource(ms.getResource()).activity("executing aquery").object(ms.getId());  if (closed) {    throw new ExecutorException("Executor was closed."); }  if (queryStack == 0 && ms.isFlushCacheRequired()) {    clearLocalCache(); }  List<E> list;  try {    queryStack++;    //localCache是一级缓存,如果找不到就调用queryFromDatabase从数据库中查找    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;}//第一次,没有缓存,所以会调用queryFromDatabase方法来执行查询。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查询参数的设置    stmt = prepareStatement(handler, ms.getStatementLog());    // StatementHandler封装了Statement    // 2:SQL查询操作和结果集的封装    return handler.<E>query(stmt); } finally {    closeStatement(stmt); }}

    3.3 参数设置

    // SimplyExecutor类 ============================>// 【1】 参数设置: prepareStatementprivate Statement prepareStatement(StatementHandler handler, Log statementLog)throws SQLException {  Statement stmt;  // 通过getConnection方法来获取一个Connection,  Connection connection = getConnection(statementLog);  // 调用prepare方法来获取一个Statement  stmt = handler.prepare(connection, transaction.getTimeout());   // 设置SQL查询中的参数值 ***  handler.parameterize(stmt);  return stmt;}// RoutingStatementHandler ============================>// PreparedStatementHandler ============================>@Overridepublic void parameterize(Statement statement) throws SQLException {  parameterHandler.setParameters((PreparedStatement) statement);}// DefaultParameterHandler ============================> 此时参数设置成功@Overridepublic void setParameters(PreparedStatement ps) {  ErrorContext.instance().activity("settingparameters").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 formapping.....");       }     }   } }}

    3.4 SQL执行和结果集的封装

    // RoutingStatementHandler ============================>@Overridepublic <E> List<E> query(Statement statement) throws SQLException {  return delegate.<E>query(statement);}// PreparedStatementHandler ============================>@Overridepublic <E> List<E> query(Statement statement, ResultHandler resultHandler)throws SQLException {  // 这里就到了熟悉的PreparedStatement了  PreparedStatement ps = (PreparedStatement) statement;  // 执行SQL查询操作  ps.execute();  // 结果交给ResultHandler来处理  return resultSetHandler.<E> handleResultSets(ps);}// DefaultResultSetHandler类(封装返回值,将查询结果封装成Object对象)@Overridepublic List<Object> handleResultSets(Statement stmt) throws SQLException {  ErrorContext.instance().activity("handlingresults").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);}

    MyBatis的SQL语句执行过程是什么

    4 更新语句的执行过程分析

    • xecutor 的 update 方法分析

    • insert、update 和 delete 操作都会清空一二级缓存

    • doUpdate 方法

    • PreparedStatementHandler 的 update 方法

    • 默认是创建PreparedStatementHandler,然后执行prepareStatement方法。

    • 执行结果为受影响行数

    • 执行更新语句的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操作是通过调用update语句进行的相关逻辑 @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  ===============>@Overridepublic int update(MappedStatement ms, Object parameterObject) throwsSQLException {  // 执行增删改,清除缓存  flushCacheIfRequired(ms);  // 跳转BaseExecutor  return delegate.update(ms, parameterObject);}// BaseExecutor   ===============>@Overridepublic int update(MappedStatement ms, Object parameter) throws SQLException {  ErrorContext.instance().resource(ms.getResource()).activity("executing anupdate").object(ms.getId());  if (closed) {    throw new ExecutorException("Executor was closed."); }  // 清除 LocalCache 一级缓存  clearLocalCache();  //执行 doUpdate  return doUpdate(ms, parameter);}// SimpleExecutor  ===============>// doUpdate@Overridepublic int doUpdate(MappedStatement ms, Object parameter) throws SQLException {  Statement stmt = null;  try {    Configuration configuration = ms.getConfiguration();    StatementHandler handler = configuration.newStatementHandler(...);    // 【1】.获取statement,并进行参数映射    stmt = prepareStatement(handler, ms.getStatementLog());    // 【2】.handler.update()方法执行具体sql指令    return handler.update(stmt); } finally {    closeStatement(stmt); }}

    4.3 参数设置

    // SimplyExecutor类 ============================>//【1】 prepareStatementprivate Statement prepareStatement(StatementHandler handler, Log statementLog)throws SQLException {  Statement stmt;  Connection connection = getConnection(statementLog);  // 使用connection对象信息创建statement,并将超时时间绑定  stmt = handler.prepare(connection, transaction.getTimeout());  // parameterize方法设置sql执行时候需要的参数  handler.parameterize(stmt);  return stmt;}// RoutingStatementHandler ============================>// PreparedStatementHandler ============================>@Overridepublic void parameterize(Statement statement) throws SQLException {  parameterHandler.setParameters((PreparedStatement) statement);}// DefaultParameterHandler ============================> 此时参数设置成功@Overridepublic void setParameters(PreparedStatement ps) {  ErrorContext.instance().activity("settingparameters").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 formapping.....");       }     }   } }}

    4.4 SQL执行

    // RoutingStatementHandler ============================> @Override public int update(Statement statement) throws SQLException {  return delegate.update(statement);}// PreparedStatementHandler ============================>@Overridepublic int update(Statement statement) throws SQLException {  // 这里就是底层JDBC的PreparedStatement 操作了  PreparedStatement ps = (PreparedStatement) statement;  // 执行SQL增删改操作  ps.execute();  // 获取影响的行数  int rows = ps.getUpdateCount();  Object parameterObject = boundSql.getParameterObject();  KeyGenerator keyGenerator = mappedStatement.geTKEyGenerator();  keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);  // 返回影响的行数  return rows;}

    到此,关于“MyBatis的SQL语句执行过程是什么”的学习就结束了,希望能够解决大家的疑惑。理论与实践的搭配能更好的帮助大家学习,快去试试吧!若想继续学习更多相关知识,请继续关注编程网网站,小编会继续努力为大家带来更多实用的文章!

    --结束END--

    本文标题: MyBatis的SQL语句执行过程是什么

    本文链接: https://www.lsjlt.com/news/329839.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • MyBatis的SQL语句执行过程是什么
      这篇文章主要介绍“MyBatis的SQL语句执行过程是什么”,在日常操作中,相信很多人在MyBatis的SQL语句执行过程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”MyBatis的SQL语句执行过程...
      99+
      2023-06-30
    • MySql中sql语句执行过程是什么
      今天小编给大家分享一下MySql中sql语句执行过程是什么的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下吧。sql语句的执行过程...
      99+
      2023-07-05
    • SQL查询语句执行的过程是什么
      这篇文章主要介绍“SQL查询语句执行的过程是什么”,在日常操作中,相信很多人在SQL查询语句执行的过程是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”SQL查询语句执行的过程是什么”的疑惑有所帮助!接下来...
      99+
      2023-06-30
    • SQL语句的执行过程
      1.语法校验      如果在SQL计划缓存中没有对应的执行计划,服务器首先会对用户请求的SQL语句进行语法效验,如果有语法错误,服务器会结束查询操作,并用返回相应的错误信息给...
      99+
      2022-10-18
    • 一条SQL更新语句的执行过程是什么
      这篇“一条SQL更新语句的执行过程是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“一条SQL更新语句的执行过程是什么”文...
      99+
      2023-06-30
    • 一条SQL语句执行过程
      目录一、MySQL 体系架构- 连接池组件- 缓存组件- 分析器- 优化器- 执行器二、写操作执行过程三、读操作执行过程四、SQL执行顺序一、MySQL 体系架构 - 连接池组件 ...
      99+
      2022-11-13
    • Java MyBatis是怎么执行一条SQL语句的
      今天小编给大家分享一下Java MyBatis是怎么执行一条SQL语句的的相关知识点,内容详细,逻辑清晰,相信大部分人都还太了解这方面的知识,所以分享这篇文章给大家参考一下,希望大家阅读完这篇文章后有所收获,下面我们一起来了解一下...
      99+
      2023-07-02
    • SQL查询语句执行的过程
      目录MySQL基本架构Server 层1、连接器2、查询缓存3、分析器4、优化器5、执行器SQL语句举例: SELECT * FROM `test` WHERE `i...
      99+
      2022-11-13
    • 怎么在MyBatis中执行SQL语句
      这期内容当中小编将会给大家带来有关怎么在MyBatis中执行SQL语句,文章内容丰富且以专业的角度为大家分析和叙述,阅读完这篇文章希望大家可以有所收获。基础组件我们要理解 Mybatis 的执行过程,就必须先了解 Mybatis 中都有哪一...
      99+
      2023-06-15
    • MyBatis核心源码深度剖析SQL语句执行过程
      目录1 SQL语句的执行过程介绍2 SQL执行的入口分析2.1 为Mapper接口创建代理对象2.2 执行代理逻辑3 查询语句的执行过程分析3.1 selectOne方法分...
      99+
      2022-11-13
    • java switch语句的执行过程是什么
      这篇文章主要介绍“java switch语句的执行过程是什么”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“java switch语句的执行过程是什么”文章能帮助大家解决问题。1、语法switch(常...
      99+
      2023-06-30
    • Java MyBatis是如何执行一条SQL语句的
      目录背景阅读环境阅读过程加载XML的过程创建Mapper获得一个Mapper执行一个Mapper的方法结论背景 在前两天的一次面试中,面试官问了一个和标题一样的问题,由于一直认为My...
      99+
      2022-11-13
    • Oracle数据库SQL语句的执行过程
      这篇文章主要讲解了“Oracle数据库SQL语句的执行过程”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“Oracle数据库SQL语句的执行过程”吧!1、用户...
      99+
      2022-10-18
    • MySQL查询语句的执行过程是什么
      这篇文章主要介绍MySQL查询语句的执行过程是什么,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!首先先简单的将一个查询语句背后MySQL做了什么捋一捋:客户端发送一条查询给服务器。服务器先检查查询缓存,如果命中了缓存...
      99+
      2023-06-14
    • java中switch语句的执行过程是什么
      今天就跟大家聊聊有关java中switch语句的执行过程是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。Java的特点有哪些Java的特点有哪些1.Java语言作为静态面向对象编...
      99+
      2023-06-14
    • SQL语句解析执行的过程及原理
      目录一、sqlSession简单介绍二、获得sqlSession对象源码分析三、SQL执行流程,以查询为例一、sqlSession简单介绍 拿到SqlSessionFactory对象...
      99+
      2022-11-13
    • 一条SQL语句执行过程时怎样的
      本篇内容主要讲解“一条SQL语句执行过程时怎样的”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“一条SQL语句执行过程时怎样的”吧!一、MySQL 体系架构- 连接池组件负责与客户端的通信,是半双...
      99+
      2023-06-29
    • 深入理解:Mysql执行SQL语句过程
       开发人员基本都知道,我们的数据存在数据库中(目前最多的是mysql和oracle,由于作者更擅长mysql,所以这里默认数据库为mysql),服务器通过sql语句将查询数据的请求传入到mysql数据库。数据库拿到sql语句以后。...
      99+
      2023-06-02
    • java jdbc执行sql语句的方法是什么
      在Java中使用JDBC执行SQL语句的方法主要有以下几种:1. 使用Statement对象执行SQL语句:```javaState...
      99+
      2023-09-27
      java jdbc sql
    • 批量执行sql语句的方法是什么
      批量执行sql语句的方法是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。 代码如下: DECLARE @MyCo...
      99+
      2022-10-18
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作