zoukankan      html  css  js  c++  java
  • 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,然后需要重启服务。

  • 相关阅读:
    Knockout应用开发指南 第八章:简单应用举例(2)
    微软ASP.NET站点部署指南(7):生产环境部署
    Knockout应用开发指南 第七章:Mapping插件
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(6)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(5)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(3)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(9)
    《Microsoft Sql server 2008 Internals》读书笔记第九章Plan Caching and Recompilation(8)
    Microsoft Visual Studio .NET 2003 引导程序插件下载地址(非官方)
    Vs2010在没有安装SQL Server 2005/2008 Express时如何连接MDF数据文件?
  • 原文地址:https://www.cnblogs.com/niujifei/p/15004005.html
Copyright © 2011-2022 走看看