深入分析JavaWeb Item29 -- 使用JDBC处理大数据(MySql + Oracle)

对于MySQL中的BLOB类型,可调用如下方法设置:

PreparedStatement. setBinaryStream(i, inputStream, length);

对MySQL中的BLOB类型,可调用如下方法获取:

 InputStream in  = resultSet.getBinaryStream(String columnLabel);
 InputStream in  = resultSet.getBlob(String columnLabel).getBinaryStream(); 
4.1、 测试范例

1、编写SQL测试脚本

 create table testblob
 (
 id int primary key auto\_increment,
 image longblob
 );

2、编写测试代码如下:

package me.gacl.demo;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import me.gacl.utils.JdbcUtils;
import org.junit.Test;

/\*\*
\* @ClassName: JdbcOperaClob
\* @Description: 使用JDBC操作MySQL的二进制数据(例如图像、声音、二进制文)
\* @author: 孤傲苍狼
\* @date: 2014-9-19 下午10:10:04
\*
\*/ 
public class JdbcOperaBlob {

    /\*\*
 \* @Method: add
 \* @Description:向数据库中插入二进制数据
 \* @Anthor:孤傲苍狼
 \*
 \*/ 
    @Test
    public void add(){
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try{
            conn = JdbcUtils.getConnection();
            String sql = "insert into testblob(image) values(?)";
            st = conn.prepareStatement(sql);
            //这种方式获取的路径,其中的空格会被使用“%20”代替
            String path = JdbcOperaBlob.class.getClassLoader().getResource("01.jpg").getPath();
            //将“%20”替换会空格
            path = path.replaceAll("%20", " ");
            File file = new File(path);
            FileInputStream fis = new FileInputStream(file);//生成的流
            st.setBinaryStream(1, fis,(int) file.length());
            int num = st.executeUpdate();
            if(num>0){
                System.out.println("插入成功!!");
            }
            fis.close();
        }catch (Exception e) {
            e.printStackTrace();
        }finally{
            JdbcUtils.release(conn, st, rs);
        }
    }

    /\*\*
 \* @Method: read
 \* @Description: 读取数据库中的二进制数据
 \* @Anthor:孤傲苍狼
 \*
 \*/ 
    @Test
    public void read() {
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select image from testblob where id=?";
            st = conn.prepareStatement(sql);
            st.setInt(1, 1);
            rs = st.executeQuery();
            if (rs.next()) {
                //InputStream in = rs.getBlob("image").getBinaryStream();//这种方法也可以
                InputStream in = rs.getBinaryStream("image");
                int len = 0;
                byte buffer[] = new byte[1024];

                FileOutputStream out = new FileOutputStream("D:\\1.jpg");
                while ((len = in.read(buffer)) > 0) {
                    out.write(buffer, 0, len);
                }
                in.close();
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn, st, rs);
        }
    }
}

关于使用JDBC处理MySQL大数据的内容就总结这么多!

五、Oracle中大数据处理

在Oracle中,LOB(Large Object,大型对象)类型的字段现在用得越来越多了。因为这种类型的字段,容量大(最多能容纳4GB的数据),且一个表中可以有多个这种类型的字段,很灵活,适用于数据 量非常大的业务领域(如图象、档案等)。

LOB类型分为BLOB和CLOB两种:BLOB即二进制大型对象(Binary Large Object),适用于存贮非文本的字节流数据(如程序、图象、影音等)。而CLOB,即字符型大型对象(Character Large Object),则与字符集相关,适于存贮文本型的数据(如历史档案、大部头著作等)。

六、搭建测试环境

6.1、建立两个测试用的数据库表

建表SQL语句为:

 CREATE TABLE TEST\_CLOB ( ID NUMBER(3), CLOBCOL CLOB)
 CREATE TABLE TEST\_BLOB ( ID NUMBER(3), BLOBCOL BLOB)
6.2、搭建测试项目架构

这里写图片描述

6.3、编写db.properties配置文件
 oracleDb_Driver=oracle.jdbc.driver.OracleDriver
 oracleDb_Url=jdbc:oracle:thin:@localhost:1521:GACL
 oracleDb_UserName=GACL_XDP
 oracleDb_Password=P
6.4、编写JdbcUtils工具类
package me.gacl.utils;

import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JdbcUtils {

    private static String oracleDb_Driver = null;
    private static String oracleDb_Url = null;
    private static String oracleDb_UserName = null;
    private static String oracleDb_Password = null;

    static{
        try{
            //读取db.properties文件中的数据库连接信息
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties prop = new Properties();
            prop.load(in);

            //获取数据库连接驱动
            oracleDb_Driver = prop.getProperty("oracleDb\_Driver");
            //获取数据库连接URL地址
            oracleDb_Url = prop.getProperty("oracleDb\_Url");
            //获取数据库连接用户名
            oracleDb_UserName = prop.getProperty("oracleDb\_UserName");
            //获取数据库连接密码
            oracleDb_Password = prop.getProperty("oracleDb\_Password");

            //加载数据库驱动
            Class.forName(oracleDb_Driver);

        }catch (Exception e) {
            throw new ExceptionInInitializerError(e);
        }
    }

    /\*\*
 \* @Method: getOracleConnection
 \* @Description: 获取Oracle数据库连接对象
 \* @Anthor:孤傲苍狼
 \*
 \* @return Connection数据库连接对象
 \* @throws SQLException
 \*/ 
    public static Connection getOracleConnection() throws SQLException{
        return DriverManager.getConnection(oracleDb_Url, oracleDb_UserName,oracleDb_Password);
    }

    /\*\*
 \* @Method: release
 \* @Description: 释放资源,
 \* 要释放的资源包括Connection数据库连接对象,负责执行SQL命令的Statement对象,存储查询结果的ResultSet对象
 \* @Anthor:孤傲苍狼
 \*
 \* @param conn
 \* @param st
 \* @param rs
 \*/ 
    public static void release(Connection conn,Statement st,ResultSet rs){
        if(rs!=null){
            try{
                //关闭存储查询结果的ResultSet对象
                rs.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
            rs = null;
        }
        if(st!=null){
            try{
                //关闭负责执行SQL命令的Statement对象
                st.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }

        if(conn!=null){
            try{
                //关闭Connection数据库连接对象
                conn.close();
            }catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
}

七、JDBC处理Oracle大数据

7.1、JDBC处理CLOB数据
package me.gacl.demo;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.junit.Test;
import me.gacl.utils.JdbcUtils;

/\*\*
\* @ClassName: JdbcOperaOracleClob
\* @Description:Oracle中字符型大型对象(Character Large Object)数据处理
\* @author: 孤傲苍狼
\* @date: 2014-10-7 下午3:53:19
\*
\*/ 
public class JdbcOperaOracleClob {

    /\*\*
 CREATE TABLE TEST\_CLOB ( ID NUMBER(3), CLOBCOL CLOB)
 \*/
    /\*\*
 \* @Method: clobInsert
 \* @Description:往数据库中插入一个新的CLOB对象
 \* @Anthor:孤傲苍狼
 \*
 \* @throws Exception
 \*/ 
    @Test
    public void clobInsert() throws Exception {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        conn = JdbcUtils.getOracleConnection();
        boolean defaultCommit = conn.getAutoCommit();
        /\*开启事务,设定不自动提交 \*/
        conn.setAutoCommit(false);
        try {
            /\* 插入一个空的CLOB对象 \*/
            String sql = "INSERT INTO TEST\_CLOB VALUES (?, EMPTY\_CLOB())";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, 1);
            stmt.executeUpdate();
            /\* 查询此CLOB对象并锁定 \*/
            sql = "SELECT CLOBCOL FROM TEST\_CLOB WHERE ID=? FOR UPDATE";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, 1);
            rs = stmt.executeQuery();
            if (rs.next()) {
                /\* 取出此CLOB对象 \*/
                oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBCOL");
                /\* 向CLOB对象中写入数据 \*/
                BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
                //这种方式获取的路径,其中的空格会被使用“%20”代替
                String path = JdbcOperaClob.class.getClassLoader().getResource("data.txt").getPath();
                //将“%20”替换回空格
                path = path.replaceAll("%20", " ");
                BufferedReader in = new BufferedReader(new FileReader(path));
                int c;
                while ((c = in.read()) != -1) {
                    out.write(c);
                }
                in.close();
                out.close();
            }
            /\* 正式提交 \*/
            conn.commit();
            System.out.println("插入成功");
        } catch (Exception ex) {
            /\* 出错回滚 \*/
            conn.rollback();
            throw ex;
        }finally{
            /\* 恢复原提交状态 \*/
            conn.setAutoCommit(defaultCommit);
            JdbcUtils.release(conn,stmt,rs);
        }

    }

    /\*\*
 \* @Method: clobRead
 \* @Description: CLOB对象读取
 \* @Anthor:孤傲苍狼
 \*
 \* @throws Exception
 \*/
    @Test
    public void clobRead() throws Exception {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        conn = JdbcUtils.getOracleConnection();
        boolean defaultCommit = conn.getAutoCommit();
        conn.setAutoCommit(false);
        try {
            /\* 查询CLOB对象 \*/
            String sql = "SELECT \* FROM TEST\_CLOB WHERE ID=?";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, 1);
            rs = stmt.executeQuery();
            if (rs.next()) {
                /\* 获取CLOB对象 \*/
                oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBCOL");
                /\* 以字符形式输出 \*/
                BufferedReader in = new BufferedReader(clob.getCharacterStream());
                BufferedWriter out = new BufferedWriter(new FileWriter("D:\\2.txt"));
                int c;
                while ((c = in.read()) != -1) {
                    out.write(c);
                }
                out.close();
                in.close();
            }
        } catch (Exception ex) {
            conn.rollback();
            throw ex;
        }finally{
            /\* 恢复原提交状态 \*/
            conn.setAutoCommit(defaultCommit);
            JdbcUtils.release(conn,stmt,rs);
        }
    }

    /\*\*
 \* @Method: clobModify
 \* @Description:修改CLOB对象(是在原CLOB对象基础上进行覆盖式的修改)
 \* @Anthor:孤傲苍狼
 \*
 \* @throws Exception
 \*/ 
    @Test
    public void clobModify() throws Exception {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        conn = JdbcUtils.getOracleConnection();
        boolean defaultCommit = conn.getAutoCommit();
        // 开启事务
        conn.setAutoCommit(false);
        try {
            /\* 查询CLOB对象并锁定 \*/
            String sql = "SELECT CLOBCOL FROM TEST\_CLOB WHERE ID=? FOR UPDATE";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, 1);
            rs = stmt.executeQuery();
            if (rs.next()) {
                /\* 获取此CLOB对象 \*/
                oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBCOL");
                /\* 进行覆盖式修改 \*/
                BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
                // 这种方式获取的路径,其中的空格会被使用“%20”代替
                String path = JdbcOperaClob.class.getClassLoader().getResource("data2.txt").getPath();
                // 将“%20”替换回空格
                path = path.replaceAll("%20", " ");
                BufferedReader in = new BufferedReader(new FileReader(path));
                int c;
                while ((c = in.read()) != -1) {
                    out.write(c);
                }
                in.close();
                out.close();
            }
            /\*提交事务 \*/
            conn.commit();
        } catch (Exception ex) {
            /\*出错回滚事务 \*/
            conn.rollback();
            throw ex;
        }finally{
            /\*恢复原提交状态 \*/
            conn.setAutoCommit(defaultCommit);
            JdbcUtils.release(conn,stmt,rs);
        }
    }

    /\*\*
 \* @Method: clobReplace
 \* @Description:替换CLOB对象(将原CLOB对象清除,换成一个全新的CLOB对象)
 \* @Anthor:孤傲苍狼
 \*
 \* @throws Exception
 \*/ 
    @Test
    public void clobReplace() throws Exception {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        conn = JdbcUtils.getOracleConnection();
        boolean defaultCommit = conn.getAutoCommit();
        // 开启事务
        conn.setAutoCommit(false);
        try {
            /\* 清空原CLOB对象 \*/
            String sql = "UPDATE TEST\_CLOB SET CLOBCOL=EMPTY\_CLOB() WHERE ID=?";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, 1);
            stmt.executeUpdate();

            /\* 查询CLOB对象并锁定 \*/
            sql = "SELECT CLOBCOL FROM TEST\_CLOB WHERE ID=? FOR UPDATE";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, 1);
            rs = stmt.executeQuery();
            if (rs.next()) {
                /\* 获取此CLOB对象 \*/
                oracle.sql.CLOB clob = (oracle.sql.CLOB) rs.getClob("CLOBCOL");
                /\* 更新数据 \*/
                BufferedWriter out = new BufferedWriter(clob.getCharacterOutputStream());
                // 这种方式获取的路径,其中的空格会被使用“%20”代替
                String path = JdbcOperaClob.class.getClassLoader().getResource("db.properties").getPath();
                // 将“%20”替换回空格
                path = path.replaceAll("%20", " ");
                BufferedReader in = new BufferedReader(new FileReader(path));
                int c;
                while ((c = in.read()) != -1) {
                    out.write(c);
                }
                in.close();
                out.close();
            }
            /\* 正式提交 \*/
            conn.commit();
        } catch (Exception ex) {
            /\* 出错回滚 \*/
            conn.rollback();
            throw ex;
        } finally {
            /\* 恢复原提交状态 \*/
            conn.setAutoCommit(defaultCommit);
            JdbcUtils.release(conn, stmt, rs);
        }
    }
}
7.2、JDBC处理BLOB数据

Oracle定义了一个BLOB字段用于保存二进制数据,但这个字段并不能存放真正的二进制数据,只能向这个字段存一个指针,然后把数据放到指针所指向的Oracle的LOB段中, LOB段是在数据库内部表的一部分。因而在操作Oracle的Blob之前,必须获得指针(定位器)才能进行Blob数据的读取和写入。
  如何获得表中的Blob指针呢? 可以先使用insert语句向表中插入一个空的blob(调用oracle的函数empty_blob()),这将创建一个blob的指针,然后再把这个empty的blob的指针查询出来,这样就可得到BLOB对象,从而读写blob数据了。

1、插入空blob:insert into testblob(id,image) values(?,empty_blob())
  2、获得blob的cursor:

select image from testblob where id=? for update //注意: 必 须加for update锁定该行,直至该行被修改完毕,保证不产生并发冲突。

Blob b = rs.getBlob("image");

3、利用 io和获取到的cursor往数据库读写数据
  注意:以上操作需开启事务。

BLOB对象的存取范例

package me.gacl.demo;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import org.junit.Test;
import me.gacl.utils.JdbcUtils;

/\*\*
\* @ClassName: JdbcOperaOracleBlob
\* @Description:Oracle中大数据处理
\* @author: 孤傲苍狼
\* @date: 2014-10-7 下午3:53:19
\*
\*/ 
public class JdbcOperaOracleBlob {

    /\*\*
 \* @Method: blobInsert
 \* @Description: 向数据库中插入一个新的BLOB对象
 \* @Anthor:孤傲苍狼
 \* 
 \* @throws Exception
 \*/
    @Test
    public void blobInsert() throws Exception {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        boolean defaultCommit = true;
        try {
            conn = JdbcUtils.getOracleConnection();
            //得到数据库事务处理的默认提交方式
            defaultCommit = conn.getAutoCommit();
            //1、开启事务
            conn.setAutoCommit(false);
            //2、插入一个空的BLOB对象
            String sql = "INSERT INTO TEST\_BLOB VALUES (?, EMPTY\_BLOB())";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, 1);
            stmt.executeUpdate();
            //3、查询此BLOB对象并锁定。注意: 必 须加for update锁定该行,直至该行被修改完毕,保证不产生并发冲突
            sql = "SELECT BLOBCOL FROM TEST\_BLOB WHERE ID=? FOR UPDATE";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, 1);
            rs = stmt.executeQuery();
            if (rs.next()) {
                //4、取出此BLOB对象 ,并强制转换成Oracle的BLOB对象
                oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBCOL");
                //5、使用IO向BLOB对象中写入数据
                BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
                BufferedInputStream in = new BufferedInputStream(JdbcOperaOracleBlob.class.getClassLoader().getResourceAsStream("01.jpg"));
                int c;
                while ((c = in.read()) != -1) {
                    out.write(c);
                }
                in.close();
                out.close();
            }
            //6、提交事务
            conn.commit();
        } catch (Exception ex) {
            //7、出错回滚事务
            conn.rollback();
            throw ex;
        } finally {
            //8、恢复数据库事务处理的默认提交方式
            conn.setAutoCommit(defaultCommit);
            //释放资源
            JdbcUtils.release(conn, stmt, rs);
        }

    }

    /\*\*
 \* @Method: blobModify
 \* @Description:修改BLOB对象(是在原BLOB对象基础上进行覆盖式的修改)
 \* @Anthor:孤傲苍狼
 \* 
 \* @throws Exception
 \*/
    @Test
    public void blobModify() throws Exception {
        Connection conn = null;
        PreparedStatement stmt = null;
        ResultSet rs = null;
        boolean defaultCommit = true;
        try {
            conn = JdbcUtils.getOracleConnection();
            //得到数据库事务处理的默认提交方式
            defaultCommit = conn.getAutoCommit();
            //1、开启事务
            conn.setAutoCommit(false);
            //2、查询此BLOB对象并锁定。注意: 必 须加for update锁定该行,直至该行被修改完毕,保证不产生并发冲突
            String sql = "SELECT BLOBCOL FROM TEST\_BLOB WHERE ID=? FOR UPDATE";
            stmt = conn.prepareStatement(sql);
            stmt.setInt(1, 1);
            rs = stmt.executeQuery();
            if (rs.next()) {
                //3、取出此BLOB对象 ,并强制转换成Oracle的BLOB对象
                oracle.sql.BLOB blob = (oracle.sql.BLOB) rs.getBlob("BLOBCOL");
                //4、使用IO向BLOB对象中写入数据
                BufferedOutputStream out = new BufferedOutputStream(blob.getBinaryOutputStream());
                BufferedInputStream in = new BufferedInputStream(JdbcOperaOracleBlob.class.getClassLoader().getResourceAsStream("02.jpg"));
                int c;
                while ((c = in.read()) != -1) {
                    out.write(c);
                }
                in.close();
                out.close();
            }
            //5、提交事务
            conn.commit();
        } catch (Exception ex) {
            //6、出错回滚事务
            conn.rollback();
            throw ex;
        } finally {
            //8、恢复数据库事务处理的默认提交方式


![img](https://img-blog.csdnimg.cn/img_convert/2504130b6da363b12ce5a3588c822362.png)
![img](https://img-blog.csdnimg.cn/img_convert/33fb36922198459b2ca5f2dfd3410494.png)
![img](https://img-blog.csdnimg.cn/img_convert/a3538fd31c4b39bc286d0ee88972070c.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

                out.write(c);
                }
                in.close();
                out.close();
            }
            //5、提交事务
            conn.commit();
        } catch (Exception ex) {
            //6、出错回滚事务
            conn.rollback();
            throw ex;
        } finally {
            //8、恢复数据库事务处理的默认提交方式


[外链图片转存中...(img-M4JjBzV0-1714523662502)]
[外链图片转存中...(img-yHxiW4Hl-1714523662502)]
[外链图片转存中...(img-HNUO23DJ-1714523662503)]

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上大数据知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[需要这份系统化资料的朋友,可以戳这里获取](https://bbs.csdn.net/topics/618545628)**

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值