让我们回顾一下如何通过JDBC插入Clob或Blob

LOB是所有数据库以及JDBC中的PITA。 正确处理它们需要花费几行代码,并且可以确保最终会出错。 因为您必须考虑以下几点:

  • 首先,LOB是繁重的资源,需要特殊的生命周期管理。 分配LOB后,最好“释放”它,以减轻GC的压力。 本文详细介绍了为什么需要释放吊球
  • 分配和释放吊球的时间至关重要。 它的寿命可能比ResultSetPreparedStatementConnection / Transactions中的任何一个都更长。 每个数据库都单独管理这样的生命周期,在极端情况下,您可能必须阅读规格
  • 对于中小型LOB,您可以使用String而不是Clobbyte[]代替Blob ,但这可能并非总是如此,甚至可能会导致一些令人讨厌的错误,例如Oracle可怕的ORA-01461:可以绑定LONG值仅用于插入LONG列

因此,如果您正在使用JDBC进行低级工作(而不是通过HibernatejOOQ来抽象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 here
        if (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;
    }


    @Override
    public 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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值