目录
2. 通过PreparedStatement存储Blob类型数据
前言
本文来讲解JDBC中的Blob类型
个人主页:艺杯羹
系列专栏:JDBC
一、 MySql Blob类型简介
Blob(全称:Binary Large Object 二进制大对象)。在MySql中,Blob是一个二进制的用来存储图片,文件等数据的数据类型。操作Blob类型的数据必须使用PreparedStatement
因为Blob类型的数据无法使用字符串拼接。大多数情况,并不推荐直接把文件存放在 MySQL 数据库中
但如果应用场景是文件与数据高度耦合,或者对文件安全性要求较高的,那么将文件与数据存放在一起,即安全,又方便备份和迁移。
会占用存储数据文件的空间,所以不常用
1. Mysql中的Blob类型
MySql中有四种Blob类型,它们除了在存储的最大容量上不同,其他是一致的
| 类型 | 大小 |
| TinyBlob | 最大255字节 |
| Blob | 最大65K |
| MediumBlob | 最大16M |
| LongBlob | 最大4G |
2. Blob类型使用的注意事项
- 实际使用中根据需要存入的数据大小定义不同的Blob类型。
- 如果存储的文件过大,数据库的性能会下降。
结合文件的综合来考虑
二. 插入Blob类型数据
1. 创建表
create table `movie` (
`movieid` int(11) not null auto_increment,
`moviename` varchar(30) default null,
`poster` mediumblob,
primary key (`movieid`)
) engine=innodb default charset=utf8;
2. 通过PreparedStatement存储Blob类型数据
上面介绍过了,操作Blob类型的数据必须使用PreparedStatement,所以这里用PreparedStatement来实现
public class BlobTest {
// 向Movie表中插入数据
public void insertMovie(String moviename, InputStream is){
// 声明数据库连接对象,用于与数据库建立连接
Connection conn = null;
// 声明预编译语句对象,用于执行 SQL 语句
PreparedStatement ps = null;
try{
// 获取连接
// 调用 JdbcUtils 工具类的 getConnection 方法获取数据库连接
conn = JdbcUtils.getConnection();
// 创建PreparedStatement对象
// 使用预编译的方式创建 SQL 插入语句,避免 SQL 注入风险
ps = conn.prepareStatement("insert into movie values(default,?,?)");
// 绑定参数
// 为 SQL 语句中的第一个占位符绑定电影名称参数
ps.setString(1,moviename);
// 为 SQL 语句中的第二个占位符绑定输入流参数,用于插入二进制数据(如图片)
ps.setBlob(2,is);
// 执行SQL
// 执行插入操作,并返回受影响的行数
ps.executeUpdate();
}catch(Exception e){
// 若发生异常,打印异常堆栈信息,方便调试
e.printStackTrace();
}finally{
// 调用 JdbcUtils 工具类的 closeResource 方法关闭预编译语句和数据库连接,释放资源
JdbcUtils.closeResource(ps,conn);
}
}
public static void main(String[] args) throws FileNotFoundException {
// 创建 BlobTest 类的实例对象
BlobTest bt = new BlobTest();
// 创建读取文件的IO流
// 创建一个文件输入流,用于读取指定路径下的图片文件
InputStream is = new FileInputStream(new File("d:/1.jpg"));
// 调用 insertMovie 方法,插入电影名称和图片数据到数据库
bt.insertMovie("战狼",is);
}
}
三. 解除文件大小限制
虽然MediumBlob允许保存最大值为16M,但MySql中默认支持的容量为4194304即4M。我们可以通过修改Mysql的my.ini文件中max_allowed_packet属性扩大支持的容量,修改完毕后需要重启MySql服务
文件位置
C:\ProgramData\MySQL……

右击使用记事本打开
再使用 快捷键 ctrl + F 输入:max_allowed_packet
来快速定位到这里

这里可以看到,默认是4M的,因此修改这里即可
四、 读取Blob类型数据
public void selectMovieById(int movieid){
// 声明数据库连接对象,用于与数据库建立连接
Connection conn =null;
// 声明预编译语句对象,用于执行 SQL 语句
PreparedStatement ps = null;
// 声明结果集对象,用于存储查询结果
ResultSet rs = null;
try{
// 获取连接
conn =JdbcUtils.getConnection();
// 创建PreparedStatement对象
ps = conn.prepareStatement("select * from movie where movieid = ?");
// 绑定参数
// 为 SQL 语句中的第一个占位符绑定影片 ID 参数
ps.setInt(1,movieid);
// 执行sql
// 执行查询操作,将查询结果存储在 ResultSet 对象中
rs = ps.executeQuery();
// 遍历结果集
while(rs.next()){
// 从结果集中获取 movieid 列的值并赋值给变量 id
int id = rs.getInt("movieid");
// 从结果集中获取 moviename 列的值并赋值给变量 name
String name = rs.getString("moviename");
// 打印影片 ID 和影片名称
System.out.println(id+" "+name);
//获取blob类型的数据
// 从结果集中获取 poster 列的 Blob 类型数据
Blob blob = rs.getBlob("poster");
//获取能够从Blob类型的列中读取数据的IO流
// 从 Blob 对象中获取二进制输入流,用于读取图片数据
InputStream is = blob.getBinaryStream();
// 创建文件输出字节流对象
// 创建一个文件输出流,用于将图片数据写入到本地文件
OutputStream os = new FileOutputStream(id+"_"+name+".jpg");
//操作流完成文件的输出处理
// 定义一个字节数组作为缓冲区,用于存储从输入流读取的数据
byte[] buff = new byte[1024];
// 用于存储每次从输入流读取的字节数
int len;
// 循环从输入流读取数据到缓冲区,直到读取完所有数据
while((len = is.read(buff)) != -1){
// 将缓冲区中的数据写入到输出流
os.write(buff,0,len);
}
// 刷新输出流,确保所有数据都被写入到文件
os.flush();
// 关闭输入流,释放资源
is.close();
// 关闭输出流,释放资源
os.close();
}
}catch(Exception e){
// 若发生异常,打印异常堆栈信息,方便调试
e.printStackTrace();
}finally{
// 调用 JdbcUtils 工具类的 closeResource 方法关闭结果集、预编译语句和数据库连接,释放资源
JdbcUtils.closeResource(rs,ps,conn);
}
}
到此,就讲解完了Blob类型的讲解,希望能够帮助到你😊
508





