• Java 之 JDBC:(四)操作 BLOB 类型字段


    一、MySQL 的 BLOB 类型

      MySQL 中,BLOB 是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。

      插入 BLOB 类型的数据必须使用 PreparedStatement,因为 BLOB 类型的数据无法使用字符串拼接写的。

      MySQL 的四种BLOB类型(除了在存储的最大信息量不同外,他们是等同的)

        

      实际使用中根据需要存入的数据大小定义不同的 BLOB 类型。

      需要注意的是:如果存储的文件过大,数据库的性能会下降。

      如果在指定了相关的 BLOB 类型以后,还报错:xxx  too large,那么在MySQL的安装目录下,找 my.ini 文件加上如下的配置参数:

    max_allowed_packet=16M
    

        同时注意:修改了 my.ini 文件之后,需要重新启动 mysql 服务。

    二、向表中插入大数据类型

      代码测试:

     1     @Test
     2     public void testInsert1(){
     3         Connection conn = null;
     4         PreparedStatement ps = null;
     5         FileInputStream fis = null;
     6         try {
     7             //获取连接
     8             conn = JDBCUtils.getConnection();
     9 
    10             String sql = "insert into customers(name, email, birth, photo) values(?, ?, ?, ?);";
    11             ps = conn.prepareStatement(sql);
    12 
    13 
    14             //填充占位符
    15             ps.setString(1, "张三");
    16             ps.setString(2, "zhangsan@126.com");
    17             ps.setDate(3, new Date(new java.util.Date().getDay()));
    18 
    19             //操作 blob 类型的变量
    20             fis = new FileInputStream(new File("a.png"));
    21             //ps.setBlob(4, fis);
    22             ps.setBinaryStream(4, fis);
    23 
    24             //执行
    25             int i = ps.executeUpdate();
    26             if (i > 0) {
    27                 System.out.println("执行成功");
    28             }
    29         } catch (Exception e) {
    30             e.printStackTrace();
    31         } finally {
    32 
    33             try {
    34                 if (fis != null) {
    35                     fis.close();
    36                 }
    37             } catch (IOException e) {
    38                 e.printStackTrace();
    39             }
    40             JDBCUtils.closeResource(conn, ps);
    41         }
    42 
    43     }

      执行结果:

      PreparedStatement 对象提供了两种方法来设置 BLOB 类型:

    void setBlob(int parameterIndex, InputStream inputStream)  throws SQLException;
    
    void setBinaryStream(int parameterIndex, java.io.InputStream x)  throws SQLException;
    

       可以使用者两种方法来设置 BLOB 类型。

    三、修改数据表中的Blob类型字段

      修改的操作和插入的操作基本类似,代码示例如下:

     1     @Test
     2     public void testUpdate(){
     3         Connection conn = null;
     4         PreparedStatement ps = null;
     5         FileInputStream fis = null;
     6         try {
     7             //获取连接
     8             conn = JDBCUtils.getConnection();
     9 
    10             String sql = "update customers set photo = ? where id = ?;";
    11             ps = conn.prepareStatement(sql);
    12 
    13 
    14             //填充占位符
    15             //操作 blob 类型的变量
    16             fis = new FileInputStream(new File("d.png"));
    17             ps.setBlob(1, fis);
    18 
    19             ps.setInt(2, 20);
    20 
    21             //执行
    22             boolean execute = ps.execute();
    23             System.out.println("execute = " + execute);
    24             if (execute) {
    25                 System.out.println("执行成功");
    26             }
    27         } catch (Exception e) {
    28             e.printStackTrace();
    29         } finally {
    30 
    31             try {
    32                 if (fis != null) {
    33                     fis.close();
    34                 }
    35             } catch (IOException e) {
    36                 e.printStackTrace();
    37             }
    38             JDBCUtils.closeResource(conn, ps);
    39         }
    40 
    41     }

    四、从数据表中读取大数据类型

      从数据库中读取 BLOB 类型数据:

     1     @Test
     2     public void testQuery(){
     3         Connection conn = null;
     4         PreparedStatement ps = null;
     5         InputStream is = null;
     6         FileOutputStream fos = null;
     7         ResultSet rs = null;
     8         try {
     9             conn = JDBCUtils.getConnection();
    10             String sql = "select id, name, email, birth, photo from customers where id = ?";
    11             ps = conn.prepareStatement(sql);
    12             ps.setInt(1, 20);
    13             rs = ps.executeQuery();
    14             if(rs.next()){
    15                 //方式一:
    16                 //int id = rs.getInt(1);
    17                 //String name = rs.getString(2);
    18                 //String email = rs.getString(3);
    19                 //Date birth = rs.getDate(4);
    20 
    21                 //方式二:
    22                 int id = rs.getInt("id");
    23                 String name = rs.getString("name");
    24                 String email = rs.getString("email");
    25                 Date birth = rs.getDate("birth");
    26 
    27                 Customer cust = new Customer(id, name, email, birth);
    28                 System.out.println(cust);
    29 
    30                 //将Blob类型的字段下载下来,以文件的方式保存在本地
    31                 //Blob photo = rs.getBlob("photo");
    32                 //is = photo.getBinaryStream();
    33 
    34                 is = rs.getBinaryStream("photo");
    35                 fos = new FileOutputStream("b1.jpg");
    36                 byte[] buffer = new byte[1024];
    37                 int len;
    38                 while((len = is.read(buffer)) != -1){
    39                     fos.write(buffer, 0, len);
    40                 }
    41 
    42             }
    43         } catch (Exception e) {
    44             e.printStackTrace();
    45         }finally{
    46 
    47             try {
    48                 if(is != null)
    49                     is.close();
    50             } catch (IOException e) {
    51                 e.printStackTrace();
    52             }
    53 
    54             try {
    55                 if(fos != null)
    56                     fos.close();
    57             } catch (IOException e) {
    58                 e.printStackTrace();
    59             }
    60 
    61             JDBCUtils.closeResource(conn, ps, rs);
    62         }
    63 
    64     }

       PreparedStatement 对象提供了两种方法来获取 BLOB 数据:

    Blob getBlob(String columnLabel) throws SQLException;
    
    java.io.InputStream getBinaryStream(String columnLabel)  throws SQLException;
    

      

    五、可能遇到的问题

      当我们插入的图片过大时,可能会报下面的错误,这个时候我们就需要服务器端的 my.ini 配置文件中设置 max_allowed_packet = 16,然后需要重启服务。

  • 相关阅读:
    go语言基本语法
    go语言学习
    Dockerfile简单实战
    Dockerfile构建命令
    docker安装prometheus grafana监控
    docker kali安装及复现永恒之蓝漏洞
    Windows系统实用快捷键
    python pip修改国内源
    网络基础——子网掩码及网络划分
    OSI七层模型简单概念及相关面试题
  • 原文地址:https://www.cnblogs.com/niujifei/p/15004005.html
Copyright © 2020-2023  润新知