9. 操作BLOB类型字段

9. 操作BLOB类型字段

前言

在上一章节,我们使用PreparedStatement实现CRUD操作,那么在CRUD的操作中,对于一些特别的数据库字段操作,会有一些特别的处理。例如:BLOB类型的字段,常用来存储图片的二进制数据。

下面我们来看看如何操作 BLOB 类型字段。

操作BLOB类型字段

1. MySQL BLOB类型

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

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

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

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

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

  • 如果在指定了相关的Blob类型以后,还报错:xxx too large,那么在mysql的安装目录下,找my.ini文件加上如下的配置参数:max_allowed_packet=16M。同时注意:修改了my.ini文件之后,需要重新启动mysql服务。

2. 准备数据以及图片

准备访问 customer 的表,可以看到存在 photo 字段,如下:

image-20201021075450257

在项目中准备一个图片,准备下面操作:

image-20201021075535738

3. 向数据表中插入大数据类型

实现代码

//向数据表中插入大数据类型
@Test
public void testInsert() throws Exception {
    //获取连接
    Connection conn = JDBCUtils.getConnection();

    String sql = "insert into customers(name,email,birth,photo)values(?,?,?,?)";
    PreparedStatement ps = conn.prepareStatement(sql);

    // 填充占位符
    ps.setString(1, "Jack");
    ps.setString(2, "jack@126.com");
    ps.setObject(3, new Date(new Date().getTime()));

    // 操作Blob类型的变量
    FileInputStream fis = new FileInputStream("timg.jpg");
    ps.setBlob(4, fis);
    //执行
    ps.execute();

    //关闭资源
    fis.close();
    JDBCUtils.closeResource(conn, ps);
}

测试执行

image-20201021080314040

4. 修改数据表中的Blob类型字段

实现代码

//修改数据表中的Blob类型字段
@Test
public void testUpdate() throws Exception {
    //获取连接
    Connection conn = JDBCUtils.getConnection();

    //预编译sql
    String sql = "update customers set photo = ? where id = ?";
    PreparedStatement ps = conn.prepareStatement(sql);

    // 填充占位符
    ps.setString(2, "1"); // id
    // 操作Blob类型的变量
    FileInputStream fis = new FileInputStream("timg.jpg");
    ps.setBlob(1, fis); // photo

    //执行
    int update = ps.executeUpdate();
    if (update > 0){
        System.out.println("更新成功");
    }else {
        System.out.println("更行失败");
    }

    //关闭资源
    fis.close();
    JDBCUtils.closeResource(conn, ps);
}

测试执行

image-20201021080831401

5. 从数据表中读取大数据类型

实现代码

    //从数据表中读取大数据类型
    @Test
    public void testQuery() throws Exception {

        //1. 使用JDBCUtils获取连接
        Connection conn = JDBCUtils.getConnection();

        //2.预编译sql语句,返回PreparedStatement的实例
        String sql = "SELECT id, name, email, birth, photo FROM customers WHERE id = ?";
        PreparedStatement ps = conn.prepareStatement(sql);
        //设置占位符
        ps.setInt(1, 16); // 查询id=16

        //3.执行,并返回结果集
        ResultSet resultSet = ps.executeQuery();

        //5.处理结果集
        //next():判断结果集的下一条是否有数据,
        // 如果有数据返回true,并指针下移;
        // 如果返回false,指针不会下移。
        if (resultSet.next()) {
            //方式一: 根据查询的位置查询
//            int id = resultSet.getInt(1);
//            String name = resultSet.getString(2);
//            String email = resultSet.getString(3);
//            Date birth = resultSet.getDate(4);

            //方式二: 根据字段查询别名
            int id = resultSet.getInt("id");
            String name = resultSet.getString("name");
            String email = resultSet.getString("email");
            java.sql.Date birth = resultSet.getDate("birth");

            //保存基本信息
            Customer customer = new Customer(id, name, email, birth);
            System.out.println(customer);

            //将Blob类型的字段下载下来,以文件的方式保存在本地
            Blob photo = resultSet.getBlob("photo");
            //获取二进制数据流
            InputStream binaryStream = photo.getBinaryStream();
            //设置文件流,指定写入的文件路径
            FileOutputStream fileOutputStream = new FileOutputStream("blob.jpg");
            //将二进制数据写入文件
            byte[] buffer = new byte[1024];
            int len;
            while((len = binaryStream.read(buffer)) != -1){
                fileOutputStream.write(buffer, 0, len);
            }

            //关闭资源
            fileOutputStream.close();
            binaryStream.close();

            JDBCUtils.closeResource(conn, ps, resultSet);
        }

    }

测试执行

image-20201021090311551