JAVA处理Blob大对象

Blob对象是SQL Blob的Java语言映射。SQL Blob是一个内置类型,它可以将一个二进制大对象保存在数据库中。接口ResultSet、CallableStatement和PreparedStatement中的方法允许程序员使用与访问SQL 92内置类型同样的方式来访问SQL 99类型BLOB。
在标准实现中,JDBC驱动程序在后台使用SQL类型LOCATOR(BLOB)来实现Blob接口。LOCATOR(BLOB)指向保存在数据库服务器上的SQL BLOB值,而且这些操作作用在这个LOCATOR(定位器)上与作用在BLOB值本身有同样的结果。
意味着用户可以在一个Blob实例上执行操作而不必将这个BLOB数据物化到用户上,这将显著的提高性能。因为驱动程序在后台使用LOCATOR(BLOB),所以它的使用对程序员是完全透明的。

Blob实例的标准行为一直保持有效,直到这个事务(创建一个Blob的事务)执行了提交或者回滚操作。

1、创建Blob对象
下面的代码说明了如何创建一个Blob对象,其中stmt是一个Statement对象:

Statement stmt = con..createStatement(ResultSet.TYPE_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
ResultSet rs = stmt.excuteQuery(“SELECT DATA FROM TABLE 1”);

If (rs.next()){
rs.first();
Blob blob=rs.getBlob(“DATA”);
}

变量blob包含一个指向BLOB值的逻辑指针,该BLOB值保存在结果集rs的第一行的DATA列中。即使变量blob实际上并不包含BLOB值中的数值,应用程序在blob上执行操作仍然像在实际的数据上执行一样。即应用程序在blob上所作的任何操作都会对表中的BLOB值起作用。

2、物化BLOB数据

开发人员可以在Blob对象上调用JDBC API中的方法,就像这些方法直接
在该对象所指向的SQL BLOB上执行操作一样。然而,如果想在BLOB数据上执行操作,就必须首先将BLOB数据物化到客户。Blob接口提供了两个方法来物化BLOB数据:getBinaryStream,这个方法将BLOB数据物化为一个输入流;getBytes,这个方法将BLOB值得一部分或者全部物化为一个字节数组。下面的代码说明了如何将Blob所指向的BLOB值得全部物化为一个输入流:

java.io.InputStream in = blob.getBinaryStream();
byte b;
while((b = in.read()) >-1){
System.out.println(b);
}
接下来的代码同样物化了blob所指向的BLOB值得所有数据,但是它产生的是字节数组而不是输入流。

long len = blob.length();
byte [] data = blob.getBytes(1,len);
for(int i=0;i

3、存储Blob值
若要在数据库中存储Blob值,应用程序可以把它作为一个参数传递给
PreparedStatement的方法setBlob。下面的代码就实现了这个功能:
Blob stats = rs.getBlob(“STATS”);
PreparedStatement pstmt= con.preparedStatement(
“UPDATE SIGHTINGS SET MEAS= ? WHERE AREA = ‘BEIJING’ “);
pstmt.setBlob(1,stats);
pstmt.excuteUpdate();

FileInputStream fis1 = new FileInputStream(“D:/aa.jpg”);
pstmt.setBinaryStream(1, fis1, fis1.available());

4、发现Blob对象中的模式
如果一个Blob对象包含一个给定的字节集合,应用程序可以使用方法
position的两个方法来找到它。其中一个方法搜索一个给定的字节数组,而另一个在一个Blob对象中搜索一个给定的Blob对象。如果发现一个匹配的结果,则返回该模式字节的起始位置。

5、修改Blob对象的方法
JDBC 3.0 API中新增的方法setBytes和setBinaryStream允许应用程序对Blob对象进行修改。

方法setBytes有两个方法来向Blob对象添加数据。其中一个方法增加给定的字节数组的全部内容,而另一个方法增加给定字节数组的特定部分。两个方法都使用一个参数说明向Blob对象插入数据的起始位置。例如,下面的代码段在一个Blob对象blob1的第一个字节处写入整个字节数组bytes。在这种情况下,bytes包含了Blob对象blob的所有字节,因此执行的结果是blob2被写入了blob1的起始处。需要注意的是如果blob2的长度是1024字节,那么blob2的1024各字节将覆盖blob1的开头的1024各字节。
byte [] bytes = blob2.getBytes(1,blob2.length());
blob.setBytes(1,bytes,0,512);

下面的代码段说明如何仅仅向Blob对象加入一个字节数组的特定部分。在这种情况下,方法setBytes接受两个附加的参数来说明需要增加字节数组的哪一个部分。其中一个参数指明了这个字节数组的起始偏移量,另一个参数说明这个字节数组包含多少个连续的字节。
byte [] bytes={……};
blob.setBytes(1,bytes,0,512);
除了可以向Blob对象增加字节之外,Blob接口还提供了删除字节的方法。方法truncate接受一个字节数目作为一个参数并且根据这个数目来缩短Blob对象。

6、定位器和更新
在标准实现中,指向SQL BLOB的Blob对象使用了SQL LOCATOR类型。定位器(locator)是一个指向保存在数据库中的BLOB值的指针,而DBMS如何更新一个作为定位器实现的对象则依赖于具体的数据库。某些DBMS会更新表中的BLOB值,而另一些则仅仅更新BLOB值的一个副本,并不改变数据库中的值。在后一种情况下,应用程序必须直接更新BLOb值。

为了发现DBMS是如何更新BLOB值的,应用程序可以调用DatabaseMetaData的方法locatorsUpdateCopy。如果这个方法返回true,则应用程序必须自己更新数据库中的BLOB值。下面的代码显示了这个过程:首先从rs取回Blob对象,然后把它的值改为字节数据val的值。如果方法locatorsUpdateCopy返回true,那么它随后执行一个PreparedStatement对象来更新数据库中的值。如果方法locatorsUpdateCopy返回false,代码什么也不用做,因为数据库中的值已经被更新过了。
byte [] val ={0,1,2,3,4};
Blob data =rs.getBlob(“DATA”);
int numWritten = data.setBytes(1,val);
if (dbmd.locatorUpdateCopy() == true){
PreparedStatement pstmt= con . preparedStatement(
“UPDATE statistics SET DATA = ? WHERE REGION = ‘BEIJING’ “);
pstmt.setBlob(“DATA”,data);
pstmt.executeUpdate();
}

Original: https://www.cnblogs.com/hainange/p/6153231.html
Author: 海南一哥
Title: JAVA处理Blob大对象

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/537970/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

  • 测试用例千万不能随便,记录由一个测试用例异常引起的思考

    一 测试用例大家平时写不写? 我以前写测试用例只是针对业务接口,每个接口写一个,数据case也只是测一种。能跑通就可以了。要不同的场景case,那就改数据。重新跑一遍。简单省事。 …

    Java 2023年6月8日
    077
  • Gradle连载4-依赖包打包方式

    一、apply方法的使用 apply&#xA0;<span class="hljs-string">plugin:</span>…

    Java 2023年6月13日
    0101
  • 从零开始实现放置游戏(十一)——实现战斗挂机(2)注册登陆和游戏主界面

    本章主要实现注册登陆功能和游戏的主界面。有了游戏的界面,大家能有更直观的认识。 本章我们主要开发的是idlewow-game模块,其实就是游戏的客户端展示层。因为是放置游戏,为了方…

    Java 2023年6月5日
    087
  • Java的值传递

    特别注意:java只有值传递没有引用传递。 一、值传递和引用传递的定义 值传递(pass by value)是指在调用函数时将实际参数复制一份传递到函数中,这样在函数中如果对参数进…

    Java 2023年5月29日
    090
  • JavaCV的摄像头实战之五:推流

    欢迎访问我的GitHub 这里分类和汇总了欣宸的全部原创(含配套源码):https://github.com/zq2599/blog_demos 本篇概览 本文是《JavaCV的摄…

    Java 2023年6月8日
    092
  • Java SE 2、抽象类

    用abstract关键字来修饰一个类时,这个类就是抽象类 ​ 访问修饰符 abstract 类名 { ​ } 用abstract关键字来修饰一个方法时,这个方法就是抽象方法 ​ 访…

    Java 2023年6月7日
    069
  • Nginx笔记

    文档可以参考淘宝的: 安装(CentOs7): /etc/yum.repos.d/nginx.repo [nginx] name=nginx repo baseurl=http:/…

    Java 2023年5月30日
    051
  • LeetCode.1170-比较字符串中最小字符的出现频率(Compare Strings by Frequency of the Smallest Char)

    这是小川的第 412次更新,第 444篇原创 看题和准备 今天介绍的是 LeetCode算法题中 Easy级别的第 263题(顺位题号是 1170)。在一个非空字符串s上定义一个函…

    Java 2023年6月5日
    067
  • Spring中常见的注解

    1.组件注解 @Controller @Service @Repository @Component —标注一个类为Spring容器的Bean @Configratio…

    Java 2023年6月15日
    062
  • 请你说说Spring

    一. Spring是什么? 是一个轻量级的开源容器框架,用来装JavaBean,可以把其他的一些框架进行整合使用,使得开发更快,更简洁。 轻量级:占用空间小,非入侵式的(Sprin…

    Java 2023年6月7日
    071
  • Monitor(管程/监视器)详解

    说明 Monitor,直译为”监视器”,而操作系统领域一般翻译为”管程”。管程是指管理共享变量以及对共享变量操作的过程,让它们支持并…

    Java 2023年6月16日
    063
  • 64位虚拟机Guest OS安装错误:0xC0000225

    1, CPU必须支持Intel VT-x/AMD-V。并且在BIOS及虚拟机软件中启用。 2, 虚拟机要启用 IO ACPI。 Original: https://www.cnbl…

    Java 2023年5月30日
    059
  • freemarker

    1.freemarker 介绍 FreeMarker &#x662F;&#x4E00;&#x6B3E; &#x6A21;&#x677F;&a…

    Java 2023年6月9日
    0106
  • 聊聊spring的那些扩展机制

    慎入:本文将会有大量代码出入。 在看一些框架源码的时候,可以看见他们很多都会和Spring去做结合。举个例子dubbo的配置: 很多人其实配置了也就配置了,没有去过多的思考:为什么…

    Java 2023年5月30日
    070
  • 验证一个小小的问题

    在之前的文章提到过一个问题,而且网上很多文章也是这么说的,前几天有人对这个问题提出了一点不同的意见,抱着谨慎的态度做了一个测试。 问题是这样的:COMPACT格式下,NULL值列表…

    Java 2023年6月13日
    085
  • 排序算法详解(java代码实现)

    ​ 排序算法大致分为内部排序和外部排序两种 内部排序:待排序的记录全部放到内存中进行排序,时间复杂度也就等于比较的次数 外部排序:数据量很大,内存无法容纳,需要对外存进行访问再排序…

    Java 2023年6月13日
    081
亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球