【发布时间】:2015-07-14 02:27:17
【问题描述】:
我并不是要问他们究竟做了什么,而是要问他们为什么要以现在的方式实施。如果准备好的语句完全由数据库处理,它不是对所有连接都可用吗?但似乎大部分都是由驱动程序针对连接处理的,我无法理解其背后的原因。
询问 Postgres。
【问题讨论】:
标签: java mysql postgresql jdbc prepared-statement
我并不是要问他们究竟做了什么,而是要问他们为什么要以现在的方式实施。如果准备好的语句完全由数据库处理,它不是对所有连接都可用吗?但似乎大部分都是由驱动程序针对连接处理的,我无法理解其背后的原因。
询问 Postgres。
【问题讨论】:
标签: java mysql postgresql jdbc prepared-statement
如果准备好语句,则将其发送到数据库,数据库解析和分析该语句并返回某种句柄 (=id),以后可以根据需要经常使用该句柄来执行该语句。因此,与其一遍又一遍地将整个语句发送到数据库,不如只将句柄和可能的查询参数传输到数据库。
正如您已经发现的那样,prepared statements 绑定到当前数据库连接,因此当连接关闭时,该语句将从数据库缓存中删除。
我不知道你认为将这些准备好的陈述公开给所有联系会有什么好处。如果您确实希望将公共语句存储在服务器上,请改用stored procedures 或SQL views!
【讨论】:
PREPARE name-of-statement AS query-for-statement 或协议级别的等价物,PostgreSQL 回复成功或错误。提出连接中唯一名称的责任在客户端。
prepared statement 绑定到连接有几个原因(从 JDBC 和从数据库的角度来看),它们归结为“简单”:
资源管理:通过将语句与连接相关联,很容易清理任何尚未显式关闭的语句:如果连接关闭,任何打开的语句也将关闭。
在大多数数据库系统中,语句句柄也是游标句柄,这意味着它一次只能由一个连接使用,将其绑定到一个连接会更有意义。
语句生命周期(或至少执行生命周期,参见 2)与事务相关联,事务也绑定到连接。一些数据库允许一个连接上有多个活动事务,但 JDBC 假定每个连接一个。
在大多数数据库系统中,语句的准备取决于准备它的事务的元数据 (DDL) 可见性,拥有全局池会使这变得复杂(例如,允许使用哪个连接/查看哪个语句)。
有时在准备时会部分检查用户权限和特权。全局池会使这复杂化(参见 4)。
我现在可能忘记了其他一些原因。我认为最重要的是第一个(如果有全局池,其他的实现方式会有所不同)。
这并不会阻止数据库系统也拥有一个全局准备好的语句池(或至少:准备元数据,如访问路径、执行计划等)。然而,从用户的角度来看,一个准备好的语句的实例仍然绑定到一个连接。
【讨论】: