jdbc读取blob类型内存问题
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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
InputStream ins = blob.getBinaryStream();之前将网线拔了,就会出现sql连接异常。可以证明是重新去链接DB取流了 。现在问题是如果我此时把数据库内数据改了,可是取出来的还是旧的数据,猜测肯能这个流是从ResultSe里取出的。我现在想ResultSet能及时反映数据库的内容
Oracle的驱动包应该不好找源代码。暂时手边没有oracle也没法给你测试,说一下测试方法。
建议用截包工具测试一下便知。如果读取流的时候仍然有从数据库读出数据,就证明至少不是一次性全部放在应用程序内存的。至于第二个问题,可以用JOptionPane.showMessageDialog弹一个对话框阻断当前线程之后,你手工修改数据库来测试。
因为数据库连接是走网络通信,估计Blob的io流还是有buffered流的性质,具体这个要看具体的JDBC-Driver来实现
这个不一定是全部加载到内存,connection和statement有一个方法叫做setFetchSize,用来设置一个游标宽度,调用next的时候,会一次性取指定的结果条数到内存里面来,后面的next就单纯在内存里面操作,等内存里面的遍历完再取。而不是一次性全部到内存的。
不过,这个设置是否会生效,得看驱动的具体实现,比如mysql的老驱动(3.0)完全不管这个,都是一次性全加载,是有堆溢出的风险的。
下载个jd-gui反编译就能看代码了。我就想ResultSet自己重新读取DB
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源代码嘛?