我是靠谱客的博主 狂野钢笔,最近开发中收集的这篇文章主要介绍java statement 关闭_java – 在单次执行后关闭PreparedStatement – 这是一个设计缺陷吗?...,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

我已经调查了很多地方,并且听到了许多可疑的声明,其中PreparedStatement应该优先于声明无处不在,即使只是为了表现的好处;一直到声称PreparedStatements应该专门用于批处理语句而不是其他任何东西.

但是,我所遵循的(主要是在线)讨论似乎存在盲点.让我提出一个具体的方案.

我们有一个EDA设计的应用程序和数据库连接池.事件来了,其中一些需要持久性,一些则不需要.一些是人工生成的(例如,每隔X分钟更新/重置一些东西).

有些事件是顺序处理的,但其他类型的事件(也需要持久性)可以(并且将会)同时处理.

除了那些人工生成的事件之外,没有关于需要持久性的事件如何到来的结构.

这个应用程序是在很久以前设计的(大约是2005年),并且支持多个DBMS.典型的事件处理程序(需要持久性):

>从池中获取连接

>准备sql语句

>执行准备好的声明

>处理结果集(如果适用),将其关闭

>密切准备好的声明

>如有必要,准备一份不同的陈述并以同样的方式处理

>返回池连接

如果事件需要批处理,则语句将准备一次并使用addBatch / executeBatch方法.这是一个明显的性能优势,这些情况与此问题无关.

最近,我收到一个意见,即准备(解析)一个语句,执行一次并关闭的整个想法本质上是对PreparedStatement的滥用,无论是否使用服务器或客户端预处理语句,都提供零性能优势DBMSes(Oracle,DB2,MSSQL,MySQL,Derby等)甚至不会将这样的语句提升为准备好的语句缓存(或者至少,它们的默认JDBC驱动程序/数据源不会).

此外,我不得不在MySQL的开发环境中测试某些场景,似乎Connector / J使用分析器同意这个想法.对于所有非批处理的预准备语句,调用close()打印:

PreparedStatement已创建,但使用次数为1次或更少次.准备一次语句并多次重复使用它会更有效

由于前面概述的应用程序设计选择,使用PreparedStatement实例缓存来保存连接池中每个连接的任何事件使用的每个SQL语句听起来都是一个糟糕的选择.

有人可以进一步详细说明吗?逻辑“准备 – 执行(一次) – 关闭”是否存在缺陷并且基本上不鼓励?

附:对于Connector / J明确指定useUsageAdvisor = true和cachePrepStmts = true并且使用useServerPrepStmts = true或useServerPrepStmts = false仍然会在每个非批处理SQL语句的PreparedStatement实例上调用close()时产生有关效率的警告.

解决方法:

Is the logic prepare-execute [once]-close flawed and essentially discouraged?

我本身并不认为这是一个问题.给定的SQL语句需要在某些时候“准备”,无论是显式(使用PreparedStatement)还是“动态”(使用Statement).如果我们使用PreparedStatement而不是Statement来执行只执行一次的事情,可能会产生更多的开销,但是所涉及的开销不太可能很大,特别是如果你引用的语句是真的:

typical DBMSes (Oracle, DB2, MSSQL, MySQL, Derby, etc.) will not even promote such a statement to prepared statement cache (or at least, their default JDBC driver/datasource will not).

不鼓励的是这样的模式:

for (int thing : thingList) {

PreparedStatement ps = conn.prepareStatement(" {some constant SQL statement} ");

ps.setInt(1, thing);

ps.executeUpdate();

ps.close();

}

因为PreparedStatement只使用一次,并且一遍又一遍地准备相同的SQL语句. (尽管如果SQL语句及其执行计划确实被缓存,即使这可能也不是什么大问题.)更好的方法是

PreparedStatement ps = conn.prepareStatement(" {some constant SQL statement} ");

for (int thing : thingList) {

ps.setInt(1, thing);

ps.executeUpdate();

}

ps.close();

……或者甚至更好,“尝试用资源”……

try (PreparedStatement ps = conn.prepareStatement(" {some constant SQL statement} ")) {

for (int thing : thingList) {

ps.setInt(1, thing);

ps.executeUpdate();

}

}

请注意,即使不使用批处理也是如此. SQL语句仍然只准备一次并多次使用.

标签:java,jdbc,eda

来源: https://codeday.me/bug/20190519/1136538.html

最后

以上就是狂野钢笔为你收集整理的java statement 关闭_java – 在单次执行后关闭PreparedStatement – 这是一个设计缺陷吗?...的全部内容,希望文章能够帮你解决java statement 关闭_java – 在单次执行后关闭PreparedStatement – 这是一个设计缺陷吗?...所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(42)

评论列表共有 0 条评论

立即
投稿
返回
顶部