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

打印 上一主题 下一主题

主题 952|帖子 952|积分 2856

use java mysql connector
  1. // fake mysql select code
  2. // ... datasource init
  3. Connection conn = datasource.getConnection();
  4. PreparedStatement pst = conn.prepareStatement("select id, task_name from t_task where id = ?");
  5. pst.setLong(1, 31);
  6. pst.executeQuery();
复制代码
按照直觉, 既然用了 preparedStatement, 执行过一次后会在服务端缓存好预编译的语句, 之后就能省去这个解析过程,直接提交参数执行就好了

  • 但是,  mysql connector 默认创建的是 ClientPreparedStatement
  1. public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
  2.         try {
  3.             synchronized(this.getConnectionMutex()) {
  4.                 this.checkClosed();
  5.                 ClientPreparedStatement pStmt = null;
  6.                 boolean canServerPrepare = true;
  7.                 String nativeSql = (Boolean)this.processEscapeCodesForPrepStmts.getValue() ? this.nativeSQL(sql) : sql;
  8.                 if ((Boolean)this.useServerPrepStmts.getValue() && (Boolean)this.emulateUnsupportedPstmts.getValue()) {
  9.                     canServerPrepare = this.canHandleAsServerPreparedStatement(nativeSql);
  10.                 }
  11.               // useServerPrepStmts = false
  12.                 if ((Boolean)this.useServerPrepStmts.getValue() && canServerPrepare) {
  13.                       // ... 省略一些代码
  14.                     } else {
  15.                             //... 省略一些代码
  16.                             pStmt = (ClientPreparedStatement)this.clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
  17.                         }
  18.                     }
  19.                 } else {
  20.                     pStmt = (ClientPreparedStatement)this.clientPrepareStatement(nativeSql, resultSetType, resultSetConcurrency, false);
  21.                 }
  22.                 return (PreparedStatement)pStmt;
  23.             }
  24.         } catch (CJException var17) {
  25.             throw SQLExceptionsMapping.translateException(var17, this.getExceptionInterceptor());
  26.         }
  27.     }
复制代码
因为默认并没有设置 useServerPrepStmts = true, 默认是false 去指定要求服务端缓存 创建的 clientPrepareStatement 客户端语句

  • 是不是 ClientPreparedStatement 看着客户端侧进行一些元数据的缓存?
    pst.executeQuery();   代码中有一段逻辑, 如果cacheResultSetMetadata=true的话,会缓存元数据,但是并没有
  1.                   boolean cacheResultSetMetadata = (Boolean)locallyScopedConn.getPropertySet().getBooleanProperty(PropertyKey.cacheResultSetMetadata).getValue();
  2.                     String origSql = ((PreparedQuery)this.query).getOriginalSql();
  3.                     if (cacheResultSetMetadata) {
  4.                         cachedMetadata = locallyScopedConn.getCachedMetaData(origSql);
  5.                     }
复制代码
所以,虽然每次还是从服务端拿返回 参数 和 resultSet 的一些元数据

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

  • proxy 接收到 com_query  交由 MySQLComQueryPacketExecutor 处理
[code]   public Collection

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

自由的羽毛

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表