jdbc学习:操作Oracle的CLOB和BLOB数据

一.首先介绍一下CLOB和BLOB
BLOB(Binary Large Object)用于存储二进制数据的大字段类型:例如图片
CLOB(Character Large Object)用于存储字符型数据的大字段类型:例如XML文件
在mysql中已经有VARCHAR和VARBINARY这两种数据类型来分别存储字符型数据和二进制数据。但是以上两种数据有自己的局限性,他们的大小都是有限制的。所以当数据量过大时,需要用大字段类型进行存储。
而在Oracle中只有VARCHAR和BINARY,并没有VARBINARY。在Oracle中一般二进制数据类型就用BLOB表示。(这里再插一句,BINARY(N)和VARBINARY(N)中的N指的是字节长度,而CHAR(N)和VARCHAR(N)中N指的是的字符长度。对于BINARY(10),其可存储的字节固定为10,而对于CHAR(10),其可存储的字节视字符集的情况而定。具体通过后续的实验给出结果,先暂时给出结论)。
二.如何在Oracle中操作CLOB,BLOB
CLOB,BLOB这两种数据库类型在Oracle数据库中的处理比较特殊:oracle中Blob/Clob字段访问的独特方式 oracle中Blob/Clob字段本身就拥有一个游标(cursor),JDBC必须通过游标对该字段进行操作。 在字段创建之前,我们无法获取游标句柄,这意味着,我们必须首先先创建一个空的字段再从这个空的字段中获取游标,写入我们期望保存的数据。(摘自深入浅出Hibernate)
下面来看具体操作代码,先定义一个实体类:

package Blob;

import java.io.Serializable;
import java.sql.Blob;
import java.sql.Clob;

public class UserBlob implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 1L;

    public UserBlob() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Blob getImage() {
        return image;
    }

    public void setImage(Blob image) {
        this.image = image;
    }

    public Clob getResume() {
        return resume;
    }

    public void setResume(Clob resume) {
        this.resume = resume;
    }

    private Integer id;
    private String name;
    private Blob image;
    private Clob resume;

}

再给出操作数据的代码

package Blob;

import java.io.BufferedReader;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.Reader;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;

import oracle.sql.BLOB;
import oracle.sql.CLOB;

import org.junit.Test;

import util.DbHelper;

/**
 * @ClassName: BlobTest
 * @Description: TODO(这里用一句话描述这个类的作用)
 * @author wangcc
 * @date 2016-11-25 下午2:55:11
 * 
 */
public class BlobTest {
    public static void main(String[] args) {
        insertClob();
    }

    /**
     * @Title: insertClob
     * @Description: TODO 摘自深入浅出hibernate 问题在于oracle中Blob/Clob字段访问的独特方式 oracle中
     *               Blob/Clob字段本身就拥有一个游标(cursor),JDBC必须通过游标对该字段进行操作
     *               在字段创建之前,我们无法获取游标句柄,这意味着,我们必须首先先创建一个空的字段
     *               再从这个空的字段中获取游标,写入我们期望保存的数据。
     * 
     * @param 设定文件
     * @return void 返回类型
     * @throws
     */
    /**
     * @Title: insertClob
     * @Description: TODO(这里用一句话描述这个方法的作用)
     * @param 设定文件
     * @return void 返回类型
     * @throws
     */
    public static void insertClob() {
        Connection conn = null;
        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            conn = DbHelper.getConnection();
            conn.setAutoCommit(false);
            String sql = "insert into user_blob(id,name,image,resume) values(?,?,?,?)";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, 1);
            ps.setString(2, "james");
            ps.setBlob(3, BLOB.empty_lob());
            ps.setClob(4, CLOB.empty_lob());
            ps.executeUpdate();
            ps.close();
            String sql1 = "select image,resume from user_blob where id=?  for update";
            ps = conn.prepareStatement(sql1);
            ps.setInt(1, 1);
            rs = ps.executeQuery();
            rs.next();
            BLOB blob = (BLOB) rs.getBlob(1);
            CLOB clob = (CLOB) rs.getClob(2);
            FileInputStream in = new FileInputStream("F:\\CLobTest\\test.txt");
            OutputStream out = blob.getBinaryOutputStream();
            byte[] buf = new byte[10240];
            int len;
            while ((len = in.read(buf)) != -1) {
                out.write(buf, 0, len);
            }
            in.close();
            out.close();

            clob.putString(1, "This is my clob");
            String sql2 = "update user_blob set image=? and resume=? where id=?";
            ps = conn.prepareStatement(sql2);
            ps.setBlob(1, blob);
            ps.setClob(2, clob);
            ps.setInt(3, 1);
            ps.executeUpdate();
            System.out.println("DONE!");
            conn.commit();
            System.out.println("DONE!");
        } catch (Exception e) {
            // TODO: handle exception
        } finally {
            DbHelper.free(rs, ps, conn);
        }
    }

    @Test
    public void query() {
        Connection conn = null;
        ResultSet rs = null;
        PreparedStatement ps = null;
        UserBlob userBlob = new UserBlob();
        try {
            conn = DbHelper.getConnection();
            String sql = "select id,name,image,resume from user_blob where id=?";
            ps = conn.prepareStatement(sql);
            ps.setInt(1, 1);
            rs = ps.executeQuery();
            while (rs.next()) {
                userBlob.setId(rs.getInt(1));
                userBlob.setName(rs.getString(2));
                userBlob.setImage(rs.getBlob(3));
                userBlob.setResume(rs.getClob(4));
            }
        } catch (Exception e) {
            // TODO: handle exception
        }
        Clob clob = userBlob.getResume();
        Reader reader = null;
        System.out.println("Dddd");
        try {
            reader = clob.getCharacterStream();
            BufferedReader br = new BufferedReader(reader);
            String s = null;
            while ((s = br.readLine()) != null) {
                System.out.println(s);
            }
        } catch (Exception e) {
            // TODO Auto-generated catch block
            if (e instanceof IOException) {
                System.out.println("流转化错误");
            }
            System.out.println("数据库读取错误");
            e.printStackTrace();
        } finally {
            DbHelper.free(rs, ps, conn);
        }
        // Blob blob = userBlob.getImage();
        // InputStream in;
        // try {
        // in = blob.getBinaryStream();
        // int b = 0;
        // while ((b = in.read()) != -1) {
        // System.out.print((char) b);
        // }
        // } catch (Exception e) {
        // // TODO Auto-generated catch block
        // if (e instanceof SQLException) {
        // System.out.println("数据库操作错误");
        // } else {
        // System.out.println("读取文件错误");
        // }
        // e.printStackTrace();
        // }
    }
}

但是这里还有一个问题,这里的主键是自增长的,也就是说insert into的时候本是不需要指定id的,如何使得操作CLOB和BLOB时也不需要插入ID呢,下次再讨论这个问题。

create table user_blob(
id number(10),
name varchar2(20),
image Blob,
resume Clob,
primary key(id)
);

create sequence blob_seq
minvalue 1 maxvalue 99999
start with 1
increment by 1
nocache
nocycle

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值