9. 操作BLOB类型字段
9. 操作BLOB类型字段
前言
在上一章节,我们使用PreparedStatement实现CRUD操作,那么在CRUD的操作中,对于一些特别的数据库字段操作,会有一些特别的处理。例如:BLOB类型的字段,常用来存储图片的二进制数据。
下面我们来看看如何操作 BLOB 类型字段。
操作BLOB类型字段
1. MySQL BLOB类型
-
MySQL中,BLOB是一个二进制大型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。
-
插入BLOB类型的数据必须使用PreparedStatement,因为BLOB类型的数据无法使用字符串拼接写的。
-
MySQL的四种BLOB类型(除了在存储的最大信息量上不同外,他们是等同的)
-
实际使用中根据需要存入的数据大小定义不同的BLOB类型。
-
需要注意的是:如果存储的文件过大,数据库的性能会下降。
-
如果在指定了相关的Blob类型以后,还报错:xxx too large,那么在mysql的安装目录下,找my.ini文件加上如下的配置参数:max_allowed_packet=16M。同时注意:修改了my.ini文件之后,需要重新启动mysql服务。
2. 准备数据以及图片
准备访问 customer 的表,可以看到存在 photo 字段,如下:
在项目中准备一个图片,准备下面操作:
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);
}
测试执行
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);
}
测试执行
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);
}
}
测试执行