【问题标题】:Inserting Binary data into MySQL (without PreparedStatement's)将二进制数据插入 MySQL(没有 PreparedStatement)
【发布时间】:2012-04-25 17:46:05
【问题描述】:

我正在尝试在不使用准备好的语句的情况下将一些二进制数据插入 MySQL 数据库。这样做的原因是我将数千个语句连接到一个插入运行一次。 (MySQL 转储和导入的具体工作方式)

我尝试了以下语句,但都失败了:

INSERT INTO my_table VALUES (1,'g=���F|�}X����',2);

INSERT INTO my_table VALUES (1,CAST('g=���F|�}X���' AS BINARY),2);

INSERT INTO my_table VALUES (1,CONVERT('g=���F|�}X���', BINARY),2);

INSERT INTO my_table VALUES (1,BINARY 'g=���F|�}X���',2)

我得到的错误是:

com.mysql.jdbc.MysqlDataTruncation:数据截断:第 1 行的“binary_data”列的数据太长

我用来执行语句的代码很简单:

conn.createStatement().executeUpdate(sql);

PreparedStatements 工作正常(但在这种情况下太慢了)

数据库中的实际 String I 显示有点不同:

g=÷óF|¸}X£ì[

二进制视图:67 3d 81 f7 19 f3 46 7c b8 7d 58 8c 10 a3 ec 5b

Java 字节:103、61、-127、-9、25、-13、70、124、-72、125、88、-116、16、-93、-20、91

这可能与编码有关吗?

非常感谢任何提示, 罗

【问题讨论】:

  • 二进制数据只能通过PreparedStatementCallableStatement插入,不能使用简单的Statement
  • 您知道您所做的“优化”可能毫无价值吗?准备好的语句的重点是它们是由 MySQL“预编译”的,你只需向 MySQL 提供参数。无论您是否连接语句,无论如何您都会发送数千个值。很自然,这成了一个问题,因为您不能轻易地插入二进制数据。
  • 您是如何生成INSERT 语句的?编码可能很重要,但您还必须担心正确的转义(例如,如果二进制数据中有 ')。你也检查你的JDBCconnection parameters,比如useUnicodecharacterEncoding

标签: java mysql jdbc


【解决方案1】:

找到了解决方案....虽然我在任何地方都没有看到记录.....

您可以通过写入转换为HEX并以0x开头的字节直接插入二进制数据

例如:

INSERT INTO my_table VALUES (1,0x19c0300dc90e7cedf64703ed8ae8683b,2);

【讨论】:

  • 我没有意识到mysql会像这样自动解码十六进制,感谢这篇有用的帖子。
  • 符号 x'19c0300dc90e7cedf64703ed8ae8683b' 也有效。这都记录在 MySQL 参考手册的 §9.1.4 中。
【解决方案2】:

您是否尝试过在批处理模式下使用 PreparedStatement?

    PreparedStatement pStmt = ...;
    while(...) { // use for or whatever loop
        pStmt.clearParameters();
        pStmt.setBinaryStream(2, ...);
        pStmt.addBatch();
    }
    pStmt.executeBatch();

有关如何使用 JDBC 和 MySQL 提高批处理效率的更多详细信息,请查看此处:MySQL and JDBC with rewriteBatchedStatements=true

【讨论】:

  • 是的 - 已经一次批处理 2000 条语句。尝试编写比标准 mysql 导入更快的东西(具有额外的自定义功能)当前性能比标准导入慢 40%,即使我正在并行处理 - 具有二进制列的表(我正在使用 PreparedStatements 处理是最慢的)
  • @Ro.所以,那么 PreparedStatement 并不比 Stamement 慢。如果是,你应该问一个问题,为什么会这样,因为不应该这样。
  • Mysql 连接器 j 有 client-side 准备好的语句。它有一个重写批处理参数,允许重写批处理插入语句重写为 on 语句。
  • @jilen 我不明白你的评论。请举个例子(如果您有其他见解或发布自己的答案,请随时编辑答案)
  • @AngeloFuchs stackoverflow.com/questions/26307760/…我指的是这个。
【解决方案3】:

准备好的语句无疑是最快的方法。您发现它太慢的原因可能是因为您没有在事务中使用它。你也许可以用 base 64 做一些可爱的事情,但它会很慢。

【讨论】:

    猜你喜欢
    • 2019-04-25
    • 1970-01-01
    • 2013-11-23
    • 2010-11-27
    • 1970-01-01
    • 2013-10-15
    • 2011-07-11
    • 1970-01-01
    • 2015-06-09
    相关资源
    最近更新 更多