0%

【拓展】Mybatis操作blob类型数据

如何使用Mybatis操作blob类型的数据方法介绍

一、写入Blob

1.1 操作步骤

  • 获取文件的byte类型数组
  • 直接将此byte[]作为参数插入到数据库即可(前提数据库相应的字段类型要为Blob)

1.2 实例

  • (1)数据库
  • (2)接口 和 实现类(基于SpringBoot搭建的mybatis)
1
2
3
4
5
//接口
@Mapper
public interface FileMapper {
void addFile(@Param("filename") String filename, @Param("image") byte[] image);
}
1
2
3
4
5
6
7
8
9
10
11
//实现类
@Service
public class FileServiceImp implements FileMapper {
@Autowired
FileMapper fileMapper;

@Override
public void addFile(String filename, byte[] image) {
fileMapper.addFile(filename, image);
}
}
  • (3)Mapper映射文件
1
2
3
4
5
6
7
8
9
10
11
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.letere.dao.FileMapper">
<insert id="addFile">
insert into `filetest`(filename, image)
value (#{filename}, #{image})
</insert>
</mapper>
  • (4)测试插入[写入]代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
@SpringBootTest
class CodeTests {
@Autowired
FileServiceImp fileServiceImp;

@Test
void addFileTest() throws Exception {
//创建相应的文件输入流(不要省略创建File对象的过程)
File file = new File("./src/main/java/com/letere/林克.jpg");
FileInputStream fis = new FileInputStream(file);

//获取文件大小,文件名,并创建相应大小的byte[]数组
String filename = file.getName();
long length = file.length();
byte[] image = new byte[(int)length];

//将文件输入流中的数据保存[读入]到byte[]数组中
fis.read(image);

//执行数据库插入操作,将byte[]数组作为参数插入
fileServiceImp.addFile(filename, image);

//关闭流
fis.close();
}
}

二、读取Blob数据

2.1 方法一

  • 将要读取的数据封装为一个JavaBean,Blob数据对应的Java类型为byte[]
  • (1)创建JavaBean
1
2
3
4
5
6
7
8
//使用了lombok注解来快速创建,也可以按照常规创建get, set 和 toString方法
@Data
@AllArgsConstructor
@NoArgsConstructor
public class FileBean {
private String filename;
private byte[] image;
}
  • (2)创建接口 和 实现类
1
2
3
4
5
//接口
@Mapper
public interface FileMapper {
FileBean readFile1(); //需要查询多条数据,用List<FileBean>作为返回类型
}
1
2
3
4
5
6
7
8
9
10
11
//实现类
@Service
public class FileServiceImp implements FileMapper {
@Autowired
FileMapper fileMapper;

@Override
public FileBean readFile1() {
return fileMapper.readFile1();
}
}
  • (3)Mapper映射文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.letere.dao.FileMapper">
<!-- resultType选择封装的JavaBean位置 -->
<select id="readFile1" resultType="com.letere.bean.FileBean">
select *
from `filetest`
limit 1
-- 为了方便测试,暂时只查询一条数据
-- 如果需要查询多条数据,只需在接口和实现方法的返回类型改成List集合来封装即可,resultType不用修改
</select>
</mapper>
  • (4)测试读取Blob代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@SpringBootTest
class CodeTests {
@Autowired
FileServiceImp fileServiceImp;

@Test
public void readFile1() throws Exception{
//读取数据库中的数据
FileBean fileBean = fileServiceImp.readFile1();

//将Bean中的参数提取出来
String filename = fileBean.getFilename();
byte[] image = fileBean.getImage();

//创建文件输出流,将文件存储在本地
FileOutputStream fos = new FileOutputStream("./" + filename);
fos.write(image);

//关闭流
fos.close();
}
}

2.2 方法二

  • 利用resultMap来封装从数据库中读取的数据,不用JavaBean来封装,封装为一个Map集合
  • (1)接口 和 实现类
1
2
3
4
5
//接口
@Mapper
public interface FileMapper {
Map readFile2(); //需要返回多个数据时,返回类型为List<Map>
}
1
2
3
4
5
6
7
8
9
10
11
//实现类
@Service
public class FileServiceImp implements FileMapper {
@Autowired
FileMapper fileMapper;

@Override
public Map readFile2() {
return fileMapper.readFile2();
}
}
  • (2)Mapper映射文件
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">

<mapper namespace="com.letere.dao.FileMapper">
<!--自定义返回数据类型-->
<resultMap id="fileType" type="map"> <!-- type="map":返回一个map集合的数据-->
<result column="filename" property="filename" javaType="String" />
<result column="image" property="image" jdbcType="BLOB" javaType="_byte[]"/>
<!-- 数据库字段名 map的key值 字段的类型 value的类型-->
</resultMap>
<select id="readFile2" resultMap="fileType">
select *
from `filetest`
limit 1
-- 为了方便测试,暂时只查询一条数据
-- 如果需要查询多条数据,只需将接口和实现方法的返回值类型给该成用List封装map的集合,resultType不用修改
</select>
</mapper>
  • (3)测试读取Blob代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
@SpringBootTest
class CodeTests {
@Autowired
FileServiceImp fileServiceImp;

@Test
public void readFile2() throws Exception{
//读取数据库中的数据
Map map = fileServiceImp.readFile2();

//将map中的元素提取出来
String filename = (String) map.get("filename");
byte[] image = (byte[]) map.get("image");

//创建文件输出流,将文件存储在本地
FileOutputStream fos = new FileOutputStream("./" + filename);
fos.write(image);

//关闭流
fos.close();
}
}