JavaWeb学习笔记(十四)—— 使用JDBC处理MySQL大数据

一、什么是大数据

  所谓大数据,就是大的字节数据,或大的字符数据。大数据也称之为LOB(Large Objects),LOB又分为:clob和blob,clob用于存储大文本,blob用于存储二进制数据,例如图像、声音、二进制文等。

  在实际开发中,有时是需要用程序把大文本或二进制数据直接保存到数据库中进行储存的。

  对MySQL而言只有blob,而没有clob,mysql存储大文本数据采用的是Text:

类型

长度

tinytext

28--1B(256B)

text

216-1B(64K)

mediumtext

224-1B(16M)

longtext

232-1B(4G)

  存储二进制大数据blob的类型为:

类型

长度

tinyblob

28--1B(256B)

blob

216-1B(64K)

mediumblob

224-1B(16M)

longblob

232-1B(4G)

二、测试程序

2.1 处理MySQL的大文本

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

PreparedStatement.setCharacterStream(index, reader, length);//注意length长度须设置,并且设置为int型

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

reader = resultSet. getCharacterStream(String columnLabel);
string s = resultSet.getString(String columnLabel);

 【编写SQL测试脚本】

create database jdbcstudy;
use jdbcstudy;
create table testclob
(
         id int primary key auto_increment,
         resume text
);

【编写测试代码】

/**
 * 使用JDBC操作MySQL的大文本
 */
public class JdbcOperaClob {
    /**
     * 向数据库中插入大文本数据
     */
    @Test
    public void add() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        Reader reader;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "insert into testclob(resume) values(?)";
            pstmt = conn.prepareStatement(sql);
            // 这种方式获取的路径,如果路径中带有中文字符,会出现乱码,导致找不到路径
            String path = this.getClass().getClassLoader().getResource("data.txt").getPath();
            // 解决获取文件路径出现乱码的问题
            path = java.net.URLDecoder.decode(path, "utf-8");
            File file = new File(path);
            reader = new FileReader(file);
            pstmt.setCharacterStream(1, reader, (int) file.length());
            int num = pstmt.executeUpdate();
            if (num > 0) {
                System.out.println("插入成功");
            }
            // 关闭流
            reader.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }

    /**
     * 读取数据库中的大文本数据
     */
    @Test
    public void read() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select resume from testclob where id=2";
            pstmt = conn.prepareStatement(sql);
            rs = pstmt.executeQuery();

            String contentStr = "";
            String content = "";
            if (rs.next()) {
                //使用resultSet.getString("字段名")获取大文本数据的内容
                content = rs.getString("resume");
                //使用resultSet.getCharacterStream("字段名")获取大文本数据的内容
                Reader reader = rs.getCharacterStream("resume");
                char[] buffer = new char[1024];
                int len = 0;
                FileWriter out = new FileWriter("D:\\1.txt");
                while ((len = reader.read(buffer)) > 0) {
                    contentStr += new String(buffer);
                    out.write(buffer, 0, len);
                }
                out.close();
                reader.close();
            }
            System.out.println(content);
            System.out.println("-------------------");
            System.out.println(contentStr);
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }
}

2.2 处理MySQL的二进制数据

【编写SQL测试脚本】

create table testblob
(
      id int primary key auto_increment,
      image longblob
);

【方法一】

  向数据库插入二进制数据需要使用PreparedStatement为原setBinaryStream(int, InputSteam)方法来完成。

PreparedStatement.setBinaryStream(i, inputStream, length);

  读取二进制数据,需要在查询后使用ResultSet类的getBinaryStream()方法来获取输入流对象。也就是说,PreparedStatement有setXXX(),那么ResultSet就有getXXX()。

InputStream in  = resultSet.getBinaryStream(String columnLabel);

  代码如下:

/**
 * 使用JDBC操作MySQL的二进制数据(例如图像、声音、二进制文件)
 */
public class JdbcOperaBlob {
    @Test
    public void add() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "insert into testblob(image) values(?)";
            pstmt = conn.prepareStatement(sql);
            // 这种方式获取的路径,如果路径中带有中文字符,会出现乱码,导致找不到路径
            String path = this.getClass().getClassLoader().getResource("a.jpg").getPath();
            // 解决获取文件路径出现乱码的问题
            path = java.net.URLDecoder.decode(path, "utf-8");
            File file = new File(path);
            FileInputStream fis = new FileInputStream(file);
            pstmt.setBinaryStream(1, fis, (int) file.length());
            int num = pstmt.executeUpdate();
            if (num > 0) {
                System.out.println("插入成功");
            }
            fis.close();
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }

    /**
     * 读取数据库中的二进制数据
     */
    @Test
    public void read() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select image from testblob where id=?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, 1);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                InputStream in = rs.getBinaryStream("image");
                int len = 0;
                byte[] bytes = new byte[1024];
                FileOutputStream out = new FileOutputStream("D:\\1.jpg");
                while ((len = in.read(bytes)) > 0) {
                    out.write(bytes, 0, len);
                }
                in.close();
                out.close();
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }
}

【方法二】:

  把要存储的数据包装成Blob类型,然后调用PreparedStatement的setBlob()方法来设置数据:

PreparedStatement.setBlob (int parameterIndex, Blob x)

  获取数据时,再调用如下方法:

InputStream in  = resultSet.getBlob(String columnLabel).getBinaryStream(); 

  测试代码如下:

/**
 * 使用JDBC操作MySQL的二进制数据(例如图像、声音、二进制文件)
 */
public class JdbcOperaBlob {
    @Test
    public void add() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "insert into testblob(image) values(?)";
            pstmt = conn.prepareStatement(sql);
            // 这种方式获取的路径,如果路径中带有中文字符,会出现乱码,导致找不到路径
            String path = this.getClass().getClassLoader().getResource("a.jpg").getPath();
            // 解决获取文件路径出现乱码的问题
            path = java.net.URLDecoder.decode(path, "utf-8");
            File file = new File(path);
            FileInputStream fis = new FileInputStream(file);

            /**
             * 需要得到Blob
             * 1.我们有的是文件,目标是Blob
             * 2.先把文件变成byte[]
             * 3.再使用byte[]创建Blob
             */
            // 把文件转换成byte[]
            // IOUtils是org.apache.commons.io下的一个工具类
            byte[] bytes = IOUtils.toByteArray(fis);
            // 使用byte[]创建Blob
            Blob blob = new SerialBlob(bytes);
            // 设置参数
            pstmt.setBlob(1, blob);
            pstmt.executeUpdate();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }

    /**
     * 读取数据库中的二进制数据
     */
    @Test
    public void read() {
        Connection conn = null;
        PreparedStatement pstmt = null;
        ResultSet rs = null;
        try {
            conn = JdbcUtils.getConnection();
            String sql = "select image from testblob where id=?";
            pstmt = conn.prepareStatement(sql);
            pstmt.setInt(1, 2);
            rs = pstmt.executeQuery();
            if (rs.next()) {
                Blob blob = rs.getBlob("image");
                /**
                 * 把Blob变成硬盘上的文件
                 */
                /**
                 * 1.通过Blob得到输入流对象
                 * 2.自己创建输出流对象
                 * 3.把输入流的数据写入到输出流中
                 */
                InputStream in = blob.getBinaryStream();
                OutputStream out = new FileOutputStream("D:/2.jpg");
                IOUtils.copy(in, out);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn, pstmt, rs);
        }
    }
}

 

参考:https://www.cnblogs.com/xdp-gacl/p/3982581.html

posted @ 2019-03-10 14:05  yi0123  阅读(257)  评论(0编辑  收藏  举报