jdbc如何插入clob
LOB是所有数据库以及JDBC中的PITA。 正确处理它们需要花费几行代码,并且可以确保最终会出错。 因为您必须考虑以下几点:
- 首先,LOB是繁重的资源,需要特殊的生命周期管理。 分配LOB后,最好也“释放”它,以减轻GC的压力。 本文详细介绍了为什么需要释放吊球
- 分配和释放吊球的时间至关重要。 它的寿命可能比
ResultSet
,PreparedStatement
或Connection
/ transaction中的任何一个更长。 每个数据库都单独管理这样的寿命,在极端情况下,您可能必须阅读规格 - 对于中小型LOB,您可以使用
String
而不是Clob
或byte[]
代替Blob
,但这可能并非总是如此,甚至可能会导致一些令人讨厌的错误,例如Oracle可怕的ORA-01461:可以绑定LONG值仅用于插入LONG列
因此,如果您正在使用JDBC进行低级工作(而不是通过Hibernate或jOOQ抽象JDBC),则最好编写一个小型实用程序来处理正确的LOB处理。
最近,我们至少在某些数据库中重新发现了用于jOOQ集成测试的自己的实用程序,并认为这对于直接使用JDBC的一些读者可能非常有用。 考虑以下类别:
public class LOB implements AutoCloseable {private final Connection connection;private final List<Blob> blobs;private final List<Clob> clobs;public LOB(Connection connection) {this.connection = connection;this.blobs = new ArrayList<>();this.clobs = new ArrayList<>();}public final Blob blob(byte[] bytes) throws SQLException {Blob blob;// You may write more robust dialect // detection hereif (connection.getMetaData().getDatabaseProductName().toLowerCase().contains("oracle")) {blob = BLOB.createTemporary(connection, false, BLOB.DURATION_SESSION);}else {blob = connection.createBlob();}blob.setBytes(1, bytes);blobs.add(blob);return blob;}public final Clob clob(String string) throws SQLException {Clob clob;if (connection.getMetaData().getDatabaseProductName().toLowerCase().contains("oracle")) {clob = CLOB.createTemporary(connection, false, CLOB.DURATION_SESSION);}else {clob = connection.createClob();}clob.setString(1, string);clobs.add(clob);return clob;}@Overridepublic final void close() throws Exception {blobs.forEach(JDBCUtils::safeFree);clobs.forEach(JDBCUtils::safeFree);}
}
这个简单的类有一些不错的款待:
- 它是
AutoCloseable
,因此您可以使用try-with-resources语句释放您的吊球 - 它抽象了跨SQL方言创建LOB的过程。 无需记住Oracle的方式
要使用此类,只需编写如下内容:
try (LOB lob = new LOB(connection);PreparedStatement stmt = connection.prepareStatement("insert into lobs (id, lob) values (?, ?)")
) {stmt.setInt(1, 1);stmt.setClob(2, lob.clob("abc"));stmt.executeUpdate();
}
而已! 无需保留对lob的引用,如果它不为null,则可以安全地释放它,可以从异常中正确恢复,等等。只需将LOB
容器与PreparedStatement
一起放入try-with-resources语句中即可。
如果您对为什么必须首先调用Clob.free()
或Blob.free()
,请阅读有关它的文章 。 这将为您OutOfMemoryErrors
一两个OutOfMemoryErrors
翻译自: https://www.javacodegeeks.com/2015/04/lets-review-how-to-insert-clob-or-blob-via-jdbc.html
jdbc如何插入clob