在postgresql中,存储二进制数据的类型有标准的bytea(等同于SQL中的blob)
在网上查了很多,说读取blob字段需要添加很多东西。最后发现其实根本不需要,只需要给该字段匹配一个byte[]类型的java字段就可以了,Mybatis会自动转换,因为数据库中blob就是以二进制形式存储的
resource = fields.Binary('附件')
resource_name = fields.Char('附件名称')
<field name="resource" filename="resource_name"/>
<field name="resource_name" invisible="1"/>
public class Resource {
//附件名
String resource_name;
//附件
byte[] resource;
public String getResource_name() {
return resource_name;
}
public void setResource_name(String resource_name) {
this.resource_name = resource_name;
}
public byte[] getResource() {
return resource;
}
public void setResource(byte[] resource) {
this.resource = resource;
}
}
//Mapper接口
Resource getResource(@Param("announce_id")String announce_id);
//具体的Mapper查询
<resultMap id="resourceResult" type="com.sc.springboot.bean.Resource">
<result property="resource_name" column="resource_name"/>
<result property="resource" column="resource"/>
</resultMap>
<select id="getResource" resultMap="resourceResult">
SELECT resource_name,resource FROM sc_announce_bid_sheet where announce_id =#{announce_id}
</select>
//接口
void getResource(HttpServletResponse response, String announce_id);
//实现,Transactional是事务管理,具有原子性,要么全部执行,要么就都不执行
@Transactional(propagation = Propagation.REQUIRED,isolation = Isolation.READ_COMMITTED,rollbackFor = {Error.class,Exception.class})
public void getResource( HttpServletResponse response, String announce_id){
//base64编码与解码使用
final Base64.Decoder decoder = Base64.getDecoder();
final Base64.Encoder encoder = Base64.getEncoder();
//定义InputStream是读取数据库传来的字节流
InputStream in = null;
//向前端输出字节流
ServletOutputStream out = null;
try {
//此处做个查询
Resource resource = bidMapper.getResource(announce_id);
//添加返回头,让浏览器知道这是一个文件,并设置文件名
//这里的文件名在postman和swagger中中文会乱码,但在浏览器中下载就没啥问题,ajax也可以下载
response.addHeader("Content-Disposition", "attachment; filename="+ URLEncoder.encode(resource.getResource_name(), "UTF-8"));//这里的filename需要带后缀的文件名,必须和上传的文件后缀一致
//在不确定文件类型时,直接用application/octet-stream就行
response.addHeader("content-Type","application/octet-stream;charset=UTF-8");
//把数据库中字节base64解码,读入InputStream流
in = new ByteArrayInputStream(decoder.decode(resource.getResource()));
//下面为固定形式的向前端输出流
out = response.getOutputStream();
byte[] bs = new byte[10];
int len = -1;
while ((len=in.read(bs))!=-1){
out.write(bs,0,len);
}
//用完一定要关闭流
out.close();
in.close();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
} catch (IOException ex) {
ex.printStackTrace();
}finally{
if(out != null ){
try {
out.close();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
if(in != null){
try{
in.close();
}catch (IOException e){
e.printStackTrace();
}
}
}
}