本期目标
追踪
Connection.createStatement()
Statement.executeUpdate(String sql)
追踪
Connection.createStatement()
在PgConnection中找到createStatement()方法:
该方法调用了同名方法,并传递了两个参数,查询两个常量的注释:
TYPE_FORWARD_ONLY 表示返回的集合ResultSet只能顺序正向遍历。
CONCUR_READ_ONLY 表示返回的集合ResultSet只可以读取其中的数据,不允许修改集合中的数据。
继续追踪到:
该方法首先调用isClosed()方法检查连接是否被close,在连接正常情况下才会继续执行,否则会throw exception。
继而再次调用新的同名方法,传递了三个参数,增加的参数通过getHoldability()方法获得,该方法如下:
我们发现该方法实际上返回了PgConnection的一个属性,该属性:
即传递的第三个参数实际上等价于:ResultSet.CLOSE_CURSORS_AT_COMMIT,参考注释如下:
因而三个参数实际上为:
TYPE_FORWARD_ONLY 表示返回的集合ResultSet只能顺序正向遍历。
CONCUR_READ_ONLY 表示返回的集合ResultSet只可以读取其中的数据,不允许修改集合中的数据。
CLOSE_CURSORS_AT_COMMIT 表示表示修改提交时当前ResultSet结果集关闭
继续追踪至:
我们发现其调用了PgStatement的构造函数,传递了之前三个参数,并将当前连接作为一个新的参数传递。
追踪该构造函数:
Statement.executeUpdate(String sql)
在PGStatement中找到该方法:
该方法核心部分调用了三个方法,对其依次进行追踪:
executeWithFlags(sql, QueryExecutor.QUERY_NO_RESULTS)
QUERY_NO_RESULTS:这个常量用于标记查询执行时的一个特定标志,表明执行该查询时并不期望返回结果集。
结构如下:
其调用了executeCachedSql方法,并传递了三个参数,新增的参数为:
推测该参数应该用于标识无返回列的情况。
继续向下追踪:
preferQueryMode(String) 默认值:extended 意义:指定使用哪种模式对数据库执行查询:
simple 表示(‘Q’ execute,无解析,无绑定,仅文本模式),
extended 表示始终使用绑定/执行消息,
extendedForPrepared 表示仅针对准备好的语句进行扩展,
extendedCacheEverything 表示使用extended协议并尝试将每个语句(包括Statement.execute(String sql))缓存在查询缓存中。
查询键的主要作用是为特定的SQL查询或命令生成一个唯一的标识符,这个标识符用于在缓存中查找、存储或验证查询的结果。当应用程序执行一个查询时,查询缓存机制(如果启用了的话)会首先检查是否已经为相同的查询(即具有相同查询键的查询)缓存了结果。如果是,就可以直接返回缓存中的结果,而无需再次执行实际的数据库查询,从而节省时间和资源。
最后的查询过程在
res = executeWithFlags(cachedQuery, flags)
处实现,未详述。
executeCachedSql(String sql, int flags,String @Nullable [] columnNames) 方法关联要素较多,除少数注释外,将单独记录,此处不再详述。
checkNoResultUpdate()
该方法检查上一步调用的executeWithFlags方法是否正常执行,按照逻辑,其不会产生查询结果,若其产生了,则throw Exception,指示有异常产生。
需要注意的是,PgStatement类中查询方法的查询结果是保存在result属性中的,不会在直接查询的方法直接return,故该检查即为检查result是否为空。
getUpdateCount()
返回最近一次执行executeUpdate方法时影响的行数,未细究
debug
在之前追踪到的几个关键函数部分打上断点,调试运行。
如上图所示,传递空数组,其起到标识作用
preferQueryMode实际就是这个queryExecutor对象的preferQueryMode属性
总结
- Connection.createStatement(),无传递参数,其将以一系列事先约定好的默认值取作为PgStatement的构造方法参数,以此构造出一个PgStatement对象。用到的默认值如下:
TYPE_FORWARD_ONLY 表示返回的集合ResultSet只能顺序正向遍历。
CONCUR_READ_ONLY 表示返回的集合ResultSet只可以读取其中的数据,不允许修改集合中的数据。
CLOSE_CURSORS_AT_COMMIT 表示表示修改提交时当前ResultSet结果集关闭
- Statement.executeUpdate(String sql),该方法调的最底层execute方法的执行流程实际上应该是有一定标准的,而逐级调用的过程,实际上就是在给其增加默认配置,使其能按标准执行的过程。