jdbc读取blob类型内存问题

发布于 2021-11-16 02:23:28 字数 684 浏览 835 评论 6

Connection con = ConnectionFactory.getConnection();

 con.setAutoCommit(false);

 Statement st = con.createStatement();

 ResultSet rs = st.executeQuery("select contents from  BLOBIMG  where  id=1");

    if (rs.next()) {

        java.sql.Blob blob = rs.getBlob(1);

    在这里BLOB还是是在数据库的内存里吗?还是在本地java的对象里?

        InputStream ins = blob.getBinaryStream();

    在这读流的时候会不会重新检索数据库?是读取ResultSet里面结果?

    如果读取ResultSet里面的时候数据库里面的数据已经变了怎么去最新的啊

    求各位大神帮解答下谢谢诶

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

情痴 2021-11-19 10:22:04

InputStream ins = blob.getBinaryStream();之前将网线拔了,就会出现sql连接异常。可以证明是重新去链接DB取流了 。现在问题是如果我此时把数据库内数据改了,可是取出来的还是旧的数据,猜测肯能这个流是从ResultSe里取出的。我现在想ResultSet能及时反映数据库的内容

离去的眼神 2021-11-18 19:48:29

Oracle的驱动包应该不好找源代码。暂时手边没有oracle也没法给你测试,说一下测试方法。

建议用截包工具测试一下便知。如果读取流的时候仍然有从数据库读出数据,就证明至少不是一次性全部放在应用程序内存的。至于第二个问题,可以用JOptionPane.showMessageDialog弹一个对话框阻断当前线程之后,你手工修改数据库来测试。

因为数据库连接是走网络通信,估计Blob的io流还是有buffered流的性质,具体这个要看具体的JDBC-Driver来实现

绝影如岚 2021-11-18 18:41:34

这个不一定是全部加载到内存,connection和statement有一个方法叫做setFetchSize,用来设置一个游标宽度,调用next的时候,会一次性取指定的结果条数到内存里面来,后面的next就单纯在内存里面操作,等内存里面的遍历完再取。而不是一次性全部到内存的。

情栀口红 2021-11-18 01:08:59

不过,这个设置是否会生效,得看驱动的具体实现,比如mysql的老驱动(3.0)完全不管这个,都是一次性全加载,是有堆溢出的风险的。

复古式 2021-11-18 00:37:10

下载个jd-gui反编译就能看代码了。我就想ResultSet自己重新读取DB

带上头具痛哭 2021-11-17 17:37:18

Hi,我看到了这样的一句话(来自ApiDoc),如下,
 it returns false
 when there are no more rows in the ResultSet
 object, 也就是说他自己内部有一组行,所以你查询出来的结果应该全部在这里面,而不是先去索引。 java.sql.Blob blob = rs.getBlob(1); ,这一句我觉得可能传递的数据就是ResultSet内部的数据,这里应该是一个指针。如果数据库的数据已经改变了,那么应该重新读取一遍吧,ResultSet内部的数据才会改变。但是不排除会有一种sql的触发机制去触发ResultSet,但是你想想,这个需要回调,如果sql内部拥有一个回调的话就需要保留ResultSet地址,这样做是不明智的,所以sql拥有触发机制的可能性比较小,你应该做的就是去重新读取并生成新的ResultSet对象。最好的方法是去看ResultSet源代码,以上是我的推测,应该八九不离十。弱弱地问一句,你知道咋去看java源代码嘛?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文