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,然后需要重启服务。

原文地址:https://www.cnblogs.com/niujifei/p/15004005.html