MySQL的Blob类型
在MySQL
中Blob
是一个二进制类型对象,是一个可以存储大量数据的容器,它能容纳不同大小的数据。
插入Blob
类型的数据必须使用PreparedStatement
,因为Blob
类型的数据无法使用字符串拼接写的。
MySQL
的四种Blob
类型(除了在存储的最大信息量上不同,没有区别)
类型 | 大小(单位字节) |
---|---|
TinyBlob | 最大255 |
Blob | 最大65k |
MediumBlob | 最大16M |
LongBlob | 最大4G |
实际使用中根据需要存入的数据大小定义不同的Blob
类型。
需要注意的是:如果存储的文件过大,数据库的性能会下降。
如果在指定了相关的Blob类型以后,还报错:xxx too large
,那么在mysql的安装目录下,找到配置文件my.ini
加上参数max_allowed_packet=16M
,同时注意在修改了my.ini
配置文件后,需要重新启动mysql服务。
向数据表中插入Blob类型的数据
// 向数据表customers中插入Blob类型的字段
@Test
public void testInsert() {
Connection conn = null;
PreparedStatement ps = null;
FileInputStream fis = null;
try {
conn = JDBCUtils.getConnection();
String sql = "insert into customers(name,email,birth,photo) values(?,?,?,?)";
ps = conn.prepareStatement(sql);
ps.setObject(1, "冯宝宝");
ps.setObject(2, "fengbaobao@sleep.com");
ps.setObject(3, "2002-02-20");
fis = new FileInputStream("src/20210411150841Aicy.png");
ps.setObject(4, fis);
ps.execute();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResouse(conn, ps);
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
修改数据表中Blob类型数据
@Test
public void testUpdate() {
Connection conn = null;
PreparedStatement ps = null;
FileInputStream fis = null;
try {
conn = JDBCUtils.getConnection();
String sql = "update customers set photo = ? where id = ?";
ps = conn.prepareStatement(sql);
fis = new FileInputStream("src/DSC_2574_ys.jpg");
// ps.setObject(1, fis) // 和setObject()效果一致
ps.setBlob(1, fis);
ps.setObject(2, 20);
ps.execute();
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResouse(conn, ps);
if (fis != null) {
try {
fis.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
查询数据表中Blob类型的字段
// 查询数据表customers中Blob类型的字段
@Test
public void testQuery() {
Connection conn = null;
PreparedStatement ps = null;
ResultSet rs = null;
InputStream is = null;
FileOutputStream fos = null;
try {
conn = JDBCUtils.getConnection();
String sql = "select id,name,email,birth,photo from customers where id = ?";
ps = conn.prepareStatement(sql);
ps.setObject(1, 20);
rs = ps.executeQuery();
if (rs.next()) {
// 方式一:
// int id = rs.getInt(1);
// String name = rs.getString(2);
// String email = rs.getString(3);
// Date birth = rs.getDate(4);
// 方式二:
int id = rs.getInt("id");
String name = rs.getString("name");
String email = rs.getString("email");
Date birth = rs.getDate("birth");
Customer customer = new Customer(id, name, email, birth);
System.out.println(customer);
// 将Bolo类型的字段下载下来,以文件的方式保存在本地
Blob photo = rs.getBlob("photo");
is = photo.getBinaryStream();
fos = new FileOutputStream("src/fengbaobao.png");
byte[] buffer = new byte[1024];
int len;
while ((len = is.read(buffer)) != -1) {
fos.write(buffer, 0, len);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
JDBCUtils.closeResouse(conn, ps, rs);
if (is != null) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (fos != null) {
try {
fos.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
实际开发中,很少会将图片直接存入数据库,一般都是将图片的路径保存在数据库中。