mysql connector 执行 select 和 shardingshpere-proxy 的处理过程

use java mysql connector

// fake mysql select code
// ... datasource init
Connection conn = datasource.getConnection();
PreparedStatement pst = conn.prepareStatement("select id, task_name from t_task where id = ?");
pst.setLong(1, 31);
pst.executeQuery();

按照直觉, 既然用了 preparedStatement, 执行过一次后会在服务端缓存好预编译的语句, 之后就能省去这个解析过程,直接提交参数执行就好了

  1. 但是, mysql connector 默认创建的是 ClientPreparedStatement
public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
        try {
            synchronized(this.getConnectionMutex()) {
                this.checkClosed();
                ClientPreparedStatement pStmt = null;
                boolean canServerPrepare = true;
                String nativeSql = (Boolean)this.processEscapeCodesForPrepStmts.getValue() ? this.nativeSQL(sql) : sql;
                if ((Boolean)this.useServerPrepStmts.getValue() && (Boolean)this.emulateUnsupportedPstmts.getValue()) {
                    canServerPrepare = this.canHandleAsServerPreparedStatement(nativeSql);
                }
              // useServerPrepStmts = false
                if ((Boolean)this.useServerPrepStmts.getValue() && canServerPrepare) {
                      // ... 省略一些代码
                    } else {
                    	//... 省略一些代码
                            pStmt = (ClientPreparedStatement)this.clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
                        }
                    }
                } else {
                    pStmt = (ClientPreparedStatement)this.clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
                }

                return (PreparedStatement)pStmt;
            }
        } catch (CJException var17) {
            throw SQLExceptionsMapping.translateException(var17, this.getExceptionInterceptor());
        }
    }

因为默认并没有设置 useServerPrepStmts = true, 默认是false 去指定要求服务端缓存 创建的 clientPrepareStatement 客户端语句

  1. 是不是 ClientPreparedStatement 看着客户端侧进行一些元数据的缓存?
    pst.executeQuery(); 代码中有一段逻辑, 如果cacheResultSetMetadata=true的话,会缓存元数据,但是并没有
                  boolean cacheResultSetMetadata = (Boolean)locallyScopedConn.getPropertySet().getBooleanProperty(PropertyKey.cacheResultSetMetadata).getValue();
                    String origSql = ((PreparedQuery)this.query).getOriginalSql();
                    if (cacheResultSetMetadata) {
                        cachedMetadata = locallyScopedConn.getCachedMetaData(origSql);
                    }

所以,虽然每次还是从服务端拿返回 参数 和 resultSet 的一些元数据

  1. 最终发往服务端(这边场景是proxy) 的 sql 其实是非参数化的 com_query 命令
    image

  2. proxy 接收到 com_query 交由 MySQLComQueryPacketExecutor 处理

   public Collection<DatabasePacket<?>> execute() throws SQLException {
        ResponseHeader responseHeader = proxyBackendHandler.execute();
        if (responseHeader instanceof QueryResponseHeader) {
            return processQuery((QueryResponseHeader) responseHeader);
        }
        responseType = ResponseType.UPDATE;
        return processUpdate((UpdateResponseHeader) responseHeader);
    }

MySQLComQueryPacketExecutor 常规文本查询,在 proxy frontend 处理过程较为的简单,直接交给 backend 执行,后续就和 sharding-jdbc 核心处理逻辑一致了,比如 分库分表、读写分离、单库单表直接执行

扩展:

原文链接:https://www.cnblogs.com/mushishi/p/17329876.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:mysql connector 执行 select 和 shardingshpere-proxy 的处理过程 - Python技术站

(0)
上一篇 2023年4月18日
下一篇 2023年4月19日

相关文章

  • java接收ios文件上传的示例代码

    下面是针对Java接收iOS文件上传的完整攻略,包含两个示例代码。 准备工作 首先,需要构建一个用于接收文件上传的Java Web应用程序。在这个Web应用程序中,我们需要实现文件接收的API,并对上传的文件进行处理并进行必要的持久性存储或其他操作。 为了接收iOS文件上传,我们需要支持常见的文件上传协议,例如HTTP POST、HTTP PUT或WebDA…

    Java 2023年5月19日
    00
  • java中int、double、char等变量的取值范围详析

    Java中int、double、char等变量的取值范围详析 Java中的整型、浮点型和字符型等基本数据类型都有各自的取值范围。理解这些取值范围知识,有助于我们编写更加严谨和正确的代码。本篇攻略将详细介绍Java中int、double、char等变量的取值范围。 int类型的取值范围 Java中的int类型是32位有符号整数类型,其取值范围为-2,147,4…

    Java 2023年5月26日
    00
  • 详细介绍SpringCloud之Ribbon

    详细介绍SpringCloud之Ribbon 什么是Ribbon? Ribbon是Netflix开源项目之一,主要功能是提供客户端的负载均衡算法及服务调用。它是Spring Cloud体系中较为重要的组件,可以与Eureka、Consul、Zookeeper等注册中心组合使用,实现服务间的调用与负载均衡。 Ribbon的负载均衡算法 Ribbon提供了多种负…

    Java 2023年6月16日
    00
  • 使用kafka-console-consumer.sh不停报WARN的问题及解决

    下面是使用kafka-console-consumer.sh不停报WARN的问题及解决的完整攻略: 问题描述 在使用kafka-console-consumer.sh脚本消费kafka消息时,可能会出现不停报WARN的问题,警告信息如下: WARN [Consumer clientId=consumer-1, groupId=my-group] Connec…

    Java 2023年5月20日
    00
  • spring @Conditional的使用与扩展源码分析

    让我为您详细介绍“spring @Conditional的使用与扩展源码分析”的攻略。 什么是spring @Conditional @Conditional 是 Spring 中一种条件注解,可以根据满足指定的条件来决定是否创建这个 Bean。例如,可以使用 @Conditional 注解,根据不同的环境条件或者配置来创建不同的 Bean 实例。@Cond…

    Java 2023年5月19日
    00
  • jabsorb笔记_几个小例子第1/2页

    jabsorb笔记_几个小例子第1/2页 什么是jabsorb jabsorb是一个 JavaScript 对象表示法 (JSON) 库,它将 Java 对象转换为 JSON 格式并反向转换。它具有很高的效率和灵活性,并且易于使用。 jabsorb的使用方法 jabsorb的使用非常简单,只需要引入jabsorb的jar包,然后创建一个JSONRPCBrid…

    Java 2023年6月15日
    00
  • 在IDEA中集成maven详细流程图示例

    下面是“在IDEA中集成Maven”的详细攻略,包含两条流程示例。 在IDEA中集成Maven详细攻略 1. 配置Maven环境 Maven是Java项目的构建工具,需要先安装配置Maven环境。这里给出两种安装方式: 方式一:通过IDEA自带的Maven安装 打开IDEA,选择File-Settings-Build, Execution, Deployme…

    Java 2023年5月20日
    00
  • Java线程池的简单使用方法实例教程

    下面我们先来介绍一下Java线程池的概念和作用。 Java线程池是为了解决频繁创建和销毁线程带来的性能开销问题而设计的。线程池会事先创建一定数量的线程,并维护一个任务队列,当有任务需要执行时,就将任务放入队列中。线程池中的线程会不断的从队列中取出任务并执行,执行完后将线程归还给线程池,这样就避免了反复创建和销毁线程的开销。 接下来,我们将介绍Java线程池的…

    Java 2023年5月19日
    00
合作推广
合作推广
分享本页
返回顶部