- 使用场景
需求为:前端传的某个字段为数组类型,但mysql中不支持直接存储数组,只能转为字符串存储,取出时又得转回数组,这样无论是在前端转换还是后端转换都是费时费力的。
我们可以利用 mybatis 的BaseTypeHandler类帮我们完成自动转换。
- 实现步骤
1. 实体类(数组/集合属性的元素类型该是什么就是什么)
2. 创建一个继承了 BaseTypeHandler 的自定义转换器
public class MysqlTypeHandler<T extends Object> extends BaseTypeHandler<T> {
private Class<T> clazz;
/**
* 设置非空参数
* @param ps
* @param i
* @param parameter
* @param jdbcType
* @throws SQLException
*/
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
ps.setString(i, JSON.toJSONString(parameter));
}
/**
* 根据列名,获取可以为空的结果
* @param rs
* @param columnName
* @return
* @throws SQLException
*/
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
String sqlJson = rs.getString(columnName);
if (null != sqlJson){
return JSON.parseObject(sqlJson, clazz);
}
return null;
}
/**
* 根据列索引,获取可以为空的结果
* @param rs
* @param columnIndex
* @return
* @throws SQLException
*/
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
String sqlJson = rs.getString(columnIndex);
if (null != sqlJson){
return JSON.parseObject(sqlJson, clazz);
}
return null;
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
String sqlJson = cs.getString(columnIndex);
if (null != sqlJson){
return JSON.parseObject(sqlJson, clazz);
}
return null;
}
}
3. mapper.xml 文件的映射配置
4. 另外需要注意的是: 无论你实体类的字段是什么类型, MySQL中的字段类型都是varchar, 因为底层是将数组/集合转换为字符串存进数据库的
5. 最终测试---
先看存储结果
然后查询返回给前端的样式
这样的数据前端可以直接使用的, 以此类推, 可以存储一个完整的对象进某个字段, 这样可以省去联查封装的步骤, 根据自己的业务使用场景进行灵活使用!