Mybatis——数据库json字段映射实体类
场景:数据库varchar字段存放json格式字符串数据,Mybatis查询解析json数据映射到实体类属性变量。
相关依赖:
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.74</version>
</dependency>
<dependency>
<groupId>cn.hutool</groupId>
<artifactId>hutool-all</artifactId>
<version>4.6.10</version>
</dependency>
Json解析工具类:
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.sf.nwms.core.util.lang.DateUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.util.TypeUtil;
/**
* @Title: JsonUtil
* @Description: Json工具类,暂时内部使用fastjson实现
* @version V1.0
*/
public class JsonUtil {
private JsonUtil() {}
public static String obj2json(Object obj) {
return obj2json(obj, DateUtil.DATE_TIME_PATTERN);
}
/**
*
* @Description:
* @param obj
* @param beIgnoreNull 是否忽略null值
* @param beFormat 是否格式化
* @param dataFormat 指定日期格式化
* @return
*/
public static String obj2json2(Object obj, boolean beIgnoreNull, boolean beFormat, String dataFormat) {
List<SerializerFeature> features = new ArrayList<>();
if (!beIgnoreNull) {
features.add(SerializerFeature.WriteMapNullValue);
features.add(SerializerFeature.DisableCircularReferenceDetect);
features.add(SerializerFeature.WriteNullStringAsEmpty);
features.add(SerializerFeature.WriteNullListAsEmpty);
features.add(SerializerFeature.WriteDateUseDateFormat);
}
if (beFormat) {
features.add(SerializerFeature.PrettyFormat);
}
features.add(SerializerFeature.WriteDateUseDateFormat);
return obj2json2(obj, dataFormat, features.toArray(new SerializerFeature[] {}));
}
public static String obj2json2(Object obj, boolean beIgnoreNull, boolean beFormat) {
return obj2json2(obj, beIgnoreNull, beFormat, DateUtil.DATE_TIME_PATTERN);
}
public static String obj2json2(Object obj, boolean beIgnoreNull) {
return obj2json2(obj, beIgnoreNull, false);
}
public static String obj2json2(Object obj) {
return obj2json2(obj, false);
}
/**
*
* @Description: 对象转json
* @param obj
* 对象
* @param beFormat
* 是否格式化
* @return json字符串
*/
public static String obj2json(Object obj, boolean beFormat) {
return obj2json2(obj, false, beFormat);
}
/**
*
* @Description: 对象转json
* @param obj
* @param dataFormat 日期格式
* @return
*
* 如果java bean的Date类型属性需要特殊处理,使用注解
* @com.alibaba.fastjson.annotation.JSONField
*/
public static String obj2json(Object obj, String dataFormat) {
return obj2json2(obj, false, false, dataFormat);
}
private static String obj2json2(Object obj, String dataFormat, SerializerFeature... feature) {
String defaultFormat = JSONObject.DEFFAULT_DATE_FORMAT;
JSONObject.DEFFAULT_DATE_FORMAT = dataFormat;
String json = JSON.toJSONString(obj, feature);
JSONObject.DEFFAULT_DATE_FORMAT = defaultFormat;
return json;
}
/**
*
* @Description: xml转json
* @param xml
* @return json字符串
*/
public static String xml2json(String xml) {
return cn.hutool.json.JSONUtil.xmlToJson(xml).toJSONString(0);
}
/**
*
* @Description: json转对象
* @param jsonString
* @param beanClass
* @return 实体类对象
*/
public static <T> T json2Obj(String jsonString, Class<T> beanClass) {
return JSON.parseObject(jsonString, beanClass);
}
/**
*
* @Description JSON字符串转为实体类对象,转换异常将被抛出
*
* @param <T>
* Bean类型
* @param jsonString
* JSON字符串
* @param typeReference
* {@link TypeReference}类型参考子类,可以获取其泛型参数中的Type类型
* @param ignoreError
* 是否忽略错误
* @return 实体类对象
*/
public static <T> T json2Obj(String jsonString, com.sf.nwms.core.util.lang.TypeReference<T> typeReference,
boolean ignoreError) {
/* return cn.hutool.json.JSONUtil.toBean(jsonString, TypeUtil.getTypeArgument(typeReference.getClass()),
ignoreError);*/
return json2Obj(jsonString, typeReference);
}
/**
*
* @Description:
* @param <T>
* @param jsonString
* @param typeReference
* @return
*
* eg: JsonUtil.json2Obj(jsonString, new com.sf.nwms.core.util.lang.TypeReference<List<JavaBean>())
*/
public static <T> T json2Obj(String jsonString, com.sf.nwms.core.util.lang.TypeReference<T> typeReference) {
return JSON.parseObject(jsonString, TypeUtil.getTypeArgument(typeReference.getClass()));
}
/**
*
* @Description: json转对象
* @param jsonString
* json字符串
* @param beanType
* 实体类对象类型
* @param ignoreError
* 是否忽略错误
* @return 实体类对象
*/
public static <T> T json2Obj(String jsonString, Type beanType, boolean ignoreError) {
return JSON.parseObject(jsonString, beanType);
}
}
mysql存储json的字段类型转换抽象类:
import java.sql.CallableStatement;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.type.BaseTypeHandler;
import org.apache.ibatis.type.JdbcType;
import com.alibaba.fastjson.JSON;
/**
* @Title: AbstractObjectTypeHandler
* @Description: mysql存储json的字段类型转换抽象类
*/
// @Slf4j
// @MappedJdbcTypes(JdbcType.VARCHAR)
public abstract class AbstractObjectTypeHandler<T> extends BaseTypeHandler<T> {
@Override
public void setNonNullParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException {
if (null != parameter) {
ps.setString(i, JsonUtil.obj2json(parameter));
}
}
@Override
public T getNullableResult(ResultSet rs, String columnName) throws SQLException {
return deserialize(rs.getString(columnName));
}
@Override
public T getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
return deserialize(rs.getString(columnIndex));
}
@Override
public T getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
return deserialize(cs.getString(columnIndex));
}
/**
* @Description: json反序列化
* @param data
* @return
*/
private T deserialize(String data) {
return StringUtils.isBlank(data) ? null : string2Obj(data);
}
// 重点,解析方法,子类可重写json解析
@SuppressWarnings("unchecked")
protected T string2Obj(String jsonString) {
Class<T> clazz = (Class<T>)getRawType();
return JSON.parseObject(jsonString, clazz);
}
}
解析实体
数据库表test:
字段名 | 类别 | 参考值 |
---|---|---|
id | bigint | 1 |
json_value | varchar | {name:“张三”,age:14} |
… |
正常Mybatis映射实体类:
@Data
public class Test{
private Long id;
private String jsonValue;
}
Json内容实体类:
@Data
public class Person{
private String name;
private int age;
}
Mybatis映射实体类时,解析json字段数据到变量,改造Test实体类:
@Data
public class Test{
private Long id;
@ColumnType(jdbcType = JdbcType.VARCHAR, typeHandler = PersonTypeHandler.class)
private Person jsonValue;
}
添加Json解析转换器:
import com.alibaba.fastjson.JSON;
/**
* @Description: Person类型转换器
*/
public class PersonTypeHandler extends AbstractObjectTypeHandler<Person> {}
Mybatis xml映射
<resultMap type="com.test.model.Test" id="TestMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result typeHandler="com.test.typehandler.PersonTypeHandler" property="jsonValue" column="json_value" jdbcType="VARCHAR"/>
</resultMap>
查询test数据时,使用以上resultMap接收,在映射实体类时自动解析json字段。
解析List
数据库表test:
字段名 | 类别 | 参考值 |
---|---|---|
id | bigint | 1 |
json_list_value | varchar | [{name:“张三”,age:14},{name:“李四”,age:15}] |
… |
正常Mybatis映射实体类:
@Data
public class Test{
private Long id;
private String jsonListValue;
}
Json内容实体类:
@Data
public class Person{
private String name;
private int age;
}
Mybatis映射实体类时,解析json字段数据到变量,改造Test实体类:
@Data
public class Test{
private Long id;
// 映射成List<Person>
@ColumnType(jdbcType = JdbcType.VARCHAR, typeHandler = ListPersonTypeHandler.class)
private List<Person> jsonValue;
}
添加Json解析转换器:
import com.alibaba.fastjson.JSON;
/**
* @Description: List<Person>类型转换器
*/
public class ListPersonTypeHandler extends AbstractObjectTypeHandler<List<Person>> {
@Override
protected List<Person> string2Obj(String jsonString) {
return JSON.parseArray(jsonString, Person.class);
}
}
Mybatis xml映射
<resultMap type="com.test.model.Test" id="TestMap">
<result property="id" column="id" jdbcType="INTEGER"/>
<result typeHandler="com.test.typehandler.ListPersonTypeHandler" property="jsonListValue" column="json_list_value" jdbcType="VARCHAR"/>
</resultMap>
查询test数据时,使用以上resultMap接收,在映射实体类时自动解析json集合字段。
相关文章
暂无评论...