mysql
数据库中使用blob存储- 使用
base64
加密图片数据
前言
这个方法并不好,因为传输的数据量还是蛮大的,可以存一些诸如头像的小图片,但是如果要存较大的图片会很慢。
不过只是课程作业中简单的功能,这样子简单又快捷,无所谓啦。
详情
数据库
首先设计数据库表,这里使用longblob
A BLOB is a binary large object that can hold a variable amount of data.
The four BLOB types are TINYBLOB, BLOB, MEDIUMBLOB, and LONGBLOB.
These differ only in the maximum length of the values they can hold.
BLOB是存储二进制大对象的。可以用来存储图片、视频、音频等数据。
根据可以存储文件大小的不同,分为TINYBLOB,BLOB,MEDIUMBLOB,LONGBLOB。
类型 | 可存储大小 |
---|---|
TINYBLOB | 0-255Byte |
BLOB | 0-65KB |
MEDIUMBLOB | 0-16MB |
LONGBLOB | 0-4GB |
网络上流传甚广的是上面的表,但是和下面官方文档里有些出入,不过问题不大.大体意思是相似的. | |
mysql不同数据类型的存储空间需求 |
程序
存入数据库
本地图片测试
使用本地图片做测试,确保没有问题。
@Test
void upload() {
/*
加载驱动
*/
try {
Class.forName("com.mysql.cj.jdbc.Driver");
//获取连接
String url = "jdbc:mysql://localhost:3306/findperson?useUnicode=true&characterEncoding=UTF-8&serverTimezone=UTC";
String user = "root";
String password = "pwd";
try {
Connection connection = DriverManager.getConnection(url, user, password);
/*
插入图片
*/
byte[] arr = getImgStr("D:\\Code\\Resource\\img\\comment-avatar\\2.jpg");
Blob blob = connection.createBlob();
blob.setBytes(1, arr);
String sql = "insert into pictures (sid,pic) values(1,?)";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setBlob(1, blob);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException | IOException e) {
e.printStackTrace();
}
}
前后端数据交流
upload-cn#components-upload-demo-avatar
使用antd上传组件,相关代码这里复制,这里就不凑字数了。
前端传来的数据是用MultipartFile接收的。
public void uploadUserAvatar(Integer id,MultipartFile avatar) throws IOException, SQLException {
byte[] bytes = avatar.getBytes();
upload(id,bytes);//函数如下
}
void upload(Integer id, byte[] bytes) {
try {
Class.forName(driver);
//获取连接
String url = durl;
String user = duser;
String password = dpassword;
try {
Connection connection = DriverManager.getConnection(url, user, password);
/*
插入图片
*/
byte[] arr = bytes;
Blob blob = connection.createBlob();
blob.setBytes(1, arr);
String sql = "insert into pictures (sid,pic) values(?,?)";
PreparedStatement ps = connection.prepareStatement(sql);
ps.setInt(1,id);
ps.setBlob(2, blob);
ps.executeUpdate();
} catch (SQLException e) {
e.printStackTrace();
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
从数据库中提出并展示
@Override
public MockMultipartFile getStudentAvatar(Integer sid) throws SQLException, ClassNotFoundException {
byte[] bytes = read(sid);
MockMultipartFile multipartFile = new MockMultipartFile("avatar.png",bytes);
return multipartFile;
}
public static byte[] read(Integer sid) throws ClassNotFoundException, SQLException {
Class.forName(driver);
//获取连接
String url = durl;
String user = duser;
String password = dpassword;
Connection connection = DriverManager.getConnection(url, user, password);
String sql = ("select pic from pictures where sid = ?");//根据需求自己写
PreparedStatement statement = null;
ResultSet resultSet = null;
byte[] bytes = null;
try {
statement = connection.prepareStatement(sql);
statement.setInt(1,sid);
resultSet = statement.executeQuery();
//创建blob接受resultset得到的blob数据
while (resultSet.next()) {
Blob blob = resultSet.getBlob("pic");
bytes = blob.getBytes(1, (int) blob.length());
}
} catch(
SQLException throwables) {
throwables.printStackTrace();
}
return bytes;
}
控制层
@GetMapping(value = "/user-manage/avatar",produces = MediaType.IMAGE_PNG_VALUE)
@ResponseBody
String getStudentAvatar() throws SQLException, ClassNotFoundException, IOException {
MockMultipartFile studentAvatar = userService.getStudentAvatar(currentUser.getId());
byte[] bytes = studentAvatar.getBytes();//图片的字节数组
BASE64Encoder encoder = new BASE64Encoder();
String data = encoder.encode(bytes);
return data;
}
前端获取数据,注意拼接一下
axios.get("http://localhost:8080/user-manage/avatar")
.then(res => {
console.log("获取的头像数据",res)
setImageUrl("data:image/jpeg;base64,"+res.data)
})
直接就可以展示
<img
src={imageUrl}
alt="avatar"
style={{
width: '100%',
}}
/>