Mybatis中Blob类型乱码问题

Posted by 石玉军 on 2018-07-26

智享网站的博客在数据库中的存储其实使用的就是longblob类型,这个类型在查询出来的时候如果不进行处理的话就会出现乱码问题。一个简单的处理方式就是在Mybatis查询数据库的时候增加一个拦截器,给这个类型的字段改变一下编码方式。

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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
public class BlobTypeHandler extends BaseTypeHandler<String> {
private static final String DEFAULT_CHARSET = "utf-8";

@Override
public void setNonNullParameter(PreparedStatement ps, int i,
String parameter, JdbcType jdbcType) throws SQLException {
ByteArrayInputStream bis;
try {
bis = new ByteArrayInputStream(parameter.getBytes(DEFAULT_CHARSET));
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
ps.setBinaryStream(i, bis, parameter.length());
}

@Override
public String getNullableResult(ResultSet rs, String columnName)
throws SQLException {
Blob blob = rs.getBlob(columnName);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}

@Override
public String getNullableResult(CallableStatement cs, int columnIndex)
throws SQLException {
Blob blob = cs.getBlob(columnIndex);
byte[] returnValue = null;
if (null != blob) {
returnValue = blob.getBytes(1, (int) blob.length());
}
try {
return new String(returnValue, DEFAULT_CHARSET);
} catch (UnsupportedEncodingException e) {
throw new RuntimeException("Blob Encoding Error!");
}
}

@Override
public String getNullableResult(ResultSet arg0, int arg1)
throws SQLException {
// TODO Auto-generated method stub
return null;
}
}

这个就是我们使用的拦截器了,以getNullableResult方法为例简单说一下。这个方法的两个参数见名思意,rs为返回结果集,columnName就是我们需要处理的字段名。当我们根据字段名在返回结果集中找出的这个字段就是longblob类型的数据了。在这里我们给他改一下编码就ok了。

这个类的使用方式也简单,在我们的mapper文件中需要拦截的resultMap中的字段中增加一个typeHandler类型拦截器,这个typeHandler的值就是我们BlobTypeHandler类的地址。

1
`<result property="blogsUrl" column="blogsUrl" typeHandler="com.syj.utils.blogUtils.BlobTypeHandler"/>

举一反三,如果我们数据库存储了long类型的时间戳我们是不是也可以加一个类型拦截器把他改成Date、String等类型呢?