PreparedStatement.executeQuery()方法执行过程
1. executeQuery()方法调用代码
// executeQuery()方法调用方式String sql = "select id, name, password, is_delete, create_by, create_time, modify_by, modify_time from user where name like concat_ws('', '%', ?,'%')";log.info("== sql = " + sql);Connection conn = jdbcUtil.getConnection();PreparedStatement ps = conn.prepareStatement(sql);ps.setString(1, username);ResultSet rs = ps.executeQuery();
2. executeQuery()方法执行过程
PreparedStatement是一个接口,以上代码使用的是ClientPreparedStatement实现类
/*** Executes the SQL query in this <code>PreparedStatement</code> object* and returns the <code>ResultSet</code> object generated by the query.** -- 在PreparedStatement对象中执行SQL查询,并返回查询生成的ResultSet对象** @return a <code>ResultSet</code> object that contains the data produced by the* query; never <code>null</code>* @exception SQLException if a database access error occurs;* this method is called on a closed <code>PreparedStatement</code> or the SQL* statement does not return a <code>ResultSet</code> object* @throws SQLTimeoutException when the driver has determined that the* timeout value that was specified by the {@code setQueryTimeout}* method has been exceeded and has at least attempted to cancel* the currently running {@code Statement}*/@Overridepublic java.sql.ResultSet executeQuery() throws SQLException {// bobo 进入同步代码块中,// connection 是否已经关闭synchronized (checkClosed().getConnectionMutex()) {// bobo 本方法中connection对象JdbcConnection locallyScopedConn = this.connection;// bobo 校验是否是dml的sql语句/*** - 校验是否是dml的sql语句* - 先判断首字母是否是由I,U,D,A,C,T,R字母开始,即* I - INSERT - 插入* U - UPDATE - 更新* D - DELETE、DROP - 删除数据、删除表* A - ALTER - 修改表* C - CREATE - 创建表、数据库* T - TRUNCATE - 删除表所有记录* R - RENAME - 重命名* - 如果是以上任意一种,抛异常 SQLException*/checkForDml(((PreparedQuery<?>) this.query).getOriginalSql(), ((PreparedQuery<?>) this.query).getParseInfo().getFirstStmtChar());// bobo 初始化批量生成主键keythis.batchedGeneratedKeys = null;// bobo 重置取消状态resetCancelledState();// bobo 立刻关闭所有结果集/*** Close all result sets in this statement. This includes multi-results* - 关闭此语句中的所有结果集。这包括multi-results* @throws SQLException*/implicitlyCloseAllOpenResults();// bobo 清除所有警告clearWarnings();// bobo ping 服务器,是否可以了解/*** Detect if the connection is still good by sending a ping command to the server.* - 通过向服务器发送ping命令来检测连接是否仍然有效*/if (this.doPingInstead) {doPingInstead();return this.results;}// bobo 设置流的超时时间setupStreamingTimeout(locallyScopedConn);// bobo 拼接sql语句,将参数匹配到对应?位置处Message sendPacket = ((PreparedQuery<?>) this.query).fillSendPacket();// bobo 初始化数据库String oldDb = null;if (!locallyScopedConn.getDatabase().equals(this.getCurrentDatabase())) {oldDb = locallyScopedConn.getDatabase();locallyScopedConn.setDatabase(this.getCurrentDatabase());}//// Check if we have cached metadata for this query...//// bobo 检查是否缓存了此查询的元数据// bobo 缓存的结果集CachedResultSetMetaData cachedMetadata = null;boolean cacheResultSetMetadata = locallyScopedConn.getPropertySet().getBooleanProperty(PropertyKey.cacheResultSetMetadata).getValue();// bobo select id, name, password, is_delete, create_by, create_time, modify_by, modify_time from user where name like concat_ws('', '%', ?,'%')// bobo 源sql语句,即带有占位符的sql语句String origSql = ((PreparedQuery<?>) this.query).getOriginalSql();// bobo 是否缓存了数据if (cacheResultSetMetadata) {// bobo 获取缓存的数据cachedMetadata = locallyScopedConn.getCachedMetaData(origSql);}// bobo 初始化行数locallyScopedConn.setSessionMaxRows(this.maxRows);// bobo 执行sql语句,返回执行后的结果集/*** - 获取结果集* - 存放在 result.rowData.rows字节数组中*/this.results = executeInternal(this.maxRows, sendPacket, createStreamingResultSet(), true, cachedMetadata, false);if (oldDb != null) {locallyScopedConn.setDatabase(oldDb);}// bobo 缓存中有数据,则将缓存中数据赋值给结果集if (cachedMetadata != null) {locallyScopedConn.initializeResultsMetadataFromCache(origSql, cachedMetadata, this.results);} else {// bobo 是否创建缓存数据,将得到的结果集数据添加到缓存中if (cacheResultSetMetadata) {locallyScopedConn.initializeResultsMetadataFromCache(origSql, null /* will be created */, this.results);}}// bobo 这个结果集返回的auto_increment的值,即自增主键的值this.lastInsertId = this.results.getUpdateID();// bobo 返回获取的结果集return this.results;}}
主要执行sql语句,获取数据的代码如下
/*** -- 在PreparedStatement对象中执行SQL查询,并返回查询生成的ResultSet对象*/@Overridepublic java.sql.ResultSet executeQuery() throws SQLException {// bobo 进入同步代码块中,// connection 是否已经关闭synchronized (checkClosed().getConnectionMutex()) {··· ···// bobo 拼接sql语句,将参数匹配到对应?位置处Message sendPacket = ((PreparedQuery<?>) this.query).fillSendPacket();··· ···// bobo 执行sql语句,返回执行后的结果集/*** - 获取结果集* - 存放在 result.rowData.rows字节数组中*/this.results = executeInternal(this.maxRows, sendPacket, createStreamingResultSet(), true, cachedMetadata, false);··· ···// bobo 返回获取的结果集return this.results;}}
文章转载自博博JAVA学习之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。




