MySQL 和 JDBC 与 rewriteBatchedStatements=true

Posted

技术标签:

【中文标题】MySQL 和 JDBC 与 rewriteBatchedStatements=true【英文标题】:MySQL and JDBC with rewriteBatchedStatements=true 【发布时间】:2014-12-06 02:46:24 【问题描述】:

我一直在阅读here、here 和here,了解使用rewriteBatchedStatements=true 的优势

如果我理解正确的话,使用rewriteBatchedStatements=true,JDBC 会将尽可能多的查询打包到单个网络数据包中,从而降低网络开销。我说的对吗?

然后我注意到在 mysql 服务器中为 max_allowed_packet 定义的值可能会导致查询出现问题(查询未在服务器上执行)。

所以我的第二个问题是,JDBC 是否知道分配给max_allowed_packet 的值,因此使数据包小于max_allowed_packet 的定义值,或者这是开发人员必须考虑的事情?

如果我理解错了,也请告诉我。

【问题讨论】:

为什么投反对票?需要解释一下吗? rewriteBatchedStatements 和 hibernate.jdbc.batch_size 属性是否相关?我假设 batch_size 属性驱动在一个插入中附加多少值。请澄清! 【参考方案1】:

使用 rewriteBatchedStatements=true 时,JDBC 会将尽可能多的查询打包到单个网络数据包中,从而降低网络开销。我说的对吗?

是的。以下代码

String myConnectionString =
        "jdbc:mysql://localhost:3307/mydb?" +
        "useUnicode=true&characterEncoding=UTF-8";
try (Connection con = DriverManager.getConnection(myConnectionString, "root", "whatever")) 
    try (PreparedStatement ps = con.prepareStatement("INSERT INTO jdbc (`name`) VALUES (?)")) 
        for (int i = 1; i <= 5; i++) 
            ps.setString(1, String.format(
                    "Line %d: Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.", 
                    i));
            ps.addBatch();
        
        ps.executeBatch();
    

即使我创建了一个批处理,也会发送单独的 INSERT 语句

INSERT INTO jdbc (`name`) VALUES ('Line 1: Lorem ipsum ...')
INSERT INTO jdbc (`name`) VALUES ('Line 2: Lorem ipsum ...')

但是,如果我将连接字符串更改为包含 rewriteBatchedStatements=true

String myConnectionString =
        "jdbc:mysql://localhost:3307/mydb?" +
        "useUnicode=true&characterEncoding=UTF-8" +
        "&rewriteBatchedStatements=true";

然后 JDBC 将发送一个或多个多行 INSERT 语句

INSERT INTO jdbc (`name`) VALUES ('Line 1: Lorem ipsum ...'),('Line 2: Lorem ipsum ...')

JDBC 是否知道分配给 max_allowed_pa​​cket 的值并因此使数据包小于为 max_allowed_pa​​cket 定义的值...?

是的。如果启用 MySQL 常规日志并检查它,您将看到 MySQL Connector/J 在连接时检查一堆变量,其中一个是 max_allowed_packet。您还可以设置一个小的 max_allowed_packet 值并验证 JDBC 是否将一个批处理拆分为多个多行 INSERT 语句,如果整个批处理的单个此类语句将超过 max_allowed_packet

【讨论】:

但是关于 ACID 有一个副作用:如果没有 rewriteBatchedStatements,我们可以插入部分行,但现在即使只有一个重复键,我们也可以不插入任何内容。 附注:您不应该关闭 conps,因为它会被 try-with-resources 块自动关闭。 @GordThompson 知道为什么 rewriteBatchedStatements 对于 mysql 默认为 false 吗?启用它有什么成本/缺点吗? 有了这样的东西,最好有一种选择加入的理念,而不是强加于你的理念。但是对于这个问题,它(就像所有代码库一样)可能有错误(希望不会)。 google.com/…

以上是关于MySQL 和 JDBC 与 rewriteBatchedStatements=true的主要内容,如果未能解决你的问题,请参考以下文章

MySQL 和 JDBC 缓存(?)问题与 Scala 中的过程调用有关

Java解惑 之 MySQL与JDBC编程

第十三章.MySQL数据库与JDBC编程(下)

JDBC的介绍与使用

jdbc是啥, 和mysql啥关系,需要下载啥吗

MySQL 数据库与JDBC编程