为什么JDBC驱动程序将预准备语句保持在连接级别?

时间:2015-05-04 16:03:47

标签: java mysql postgresql jdbc prepared-statement

我不是要问他们究竟做了什么,而是为什么他们按照他们的方式实施。如果准备好的语句完全由数据库处理,那么所有连接都不可用吗?但看起来大多数是由驱动程序处理连接,我无法理解背后的原因。

询问Postgres。

2 个答案:

答案 0 :(得分:2)

如果准备了一个语句,它将被发送到数据库,该数据库解析并分析该语句并发回某种句柄(= id),该句柄稍后可用于根据需要经常执行该语句。因此,不是一遍又一遍地将整个语句发送到数据库,只需将句柄和可能的查询参数传输到数据库。

正如您已经发现的那样,预准备语句绑定到当前数据库连接,因此当连接关闭时,语句将从数据库缓存中删除。

我不知道你怎么认为将这些准备好的陈述公开给所有联系会有任何好处。如果您确实希望拥有存储在服务器上的公开声明,请改用stored proceduresSQL views

答案 1 :(得分:1)

准备好的语句绑定到连接有几个原因(从数据库的JDBC 的角度来看),它们归结为&#34;简单&#34;:< / p>

  1. 资源管理:通过将语句与连接相关联,可以很容易地清除尚未明确关闭的任何语句:如果连接关闭,任何打开语句也将关闭。

    < / LI>
  2. 在大多数数据库系统中,语句句柄也是游标句柄,这意味着它一次只能由一个连接使用,将它绑定到连接然后更有意义。

    < / LI>
  3. 语句生存期(或至少执行生命周期,请参阅2)与事务关联,事务也绑定到连接。某些数据库允许连接上有多个活动事务,但JDBC假定每个连接有一个。

  4. 在大多数数据库系统中,语句的准备取决于准备它的事务的元数据(DDL)可见性,具有全局池会使其复杂化(例如,允许使用哪个连接/查看哪个语句)。

  5. 有时 - 部分 - 在准备时检查用户权限和特权。全局池会使这一点复杂化(见4)。

  6. 我现在可能还有其他一些原因。我认为最重要的是第一个(如果存在全局池,其他的将以不同的方式实现)。

    这并不能阻止数据库系统拥有全局预处理语句池(或者至少:准备元数据,如访问路径,执行计划等)。但是,从用户的角度来看,预准备语句的实例仍然绑定到连接。