Spring|Spring JPA的实体属性类型转换器并反序列化工具类详解

目录

  • 一、JPA单体JSON与Map的映射
    • 创建一个转换类
    • 只需在模型类上加个注解就能完成自动转换
  • 二、封装反序列化工具类
    • 利用JPA的AttributeConverter接口实现属性转换过于局限
    • 如何调用自定义的转换器

一、JPA 单体JSON与Map的映射 数据库中test字段为json类型
{"key": "颜色", "value": "深白色", "key_id": 1, "value_id": 3}

模型中test字段为Map类型
private Map test;

问题:如何将数据库字段的值映射到模型中,要用到JPA的属性转换

创建一个转换类
实现AttributeConverter接口
import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.lin.missyou.exception.http.ServerErrorException; import org.springframework.beans.factory.annotation.Autowired; import javax.persistence.AttributeConverter; import javax.persistence.Convert; import javax.persistence.Converter; import java.util.HashMap; import java.util.Map; // 第一个泛型类型就是entity字段的类型 // json没有类型,对应在JAVA中就是String类型// 第二个泛型类型就是数据库字段的类型@Converterpublic class MapAndJson implements AttributeConverter {/*ObjectMapper类是Jackson库的主要类,它提供一些功能将数据集或对象转换的实现。它将使用JsonParser和JsonGenerator实例来实现JSON的实际读/写。*/@Autowiredprivate ObjectMapper mapper; @Overridepublic String convertToDatabaseColumn(Map map) {try {return mapper.writeValueAsString(map); } catch (Exception e) {e.printStackTrace(); throw new ServerErrorException(99999); }}@Override@SuppressWarnings("unchecked")public Map convertToEntityAttribute(String s) {try {if (s == null) return null; return mapper.readValue(s, HashMap.class); } catch (Exception e) {e.printStackTrace(); throw new ServerErrorException(9999); }}}

看到接口的方法名,就知道能做什么了。
具体转换需要自己实现,调用SpringBoot提供的Jackson的内置库。
ObjectMapper类是Jackson库的主要类,它提供一些功能将数据集或对象转换的实现。
在类上打上注解@Converter,做为转换类的标识。

只需在模型类上加个注解就能完成自动转换
指明转换类
@Convert(converter = MapAndJson.class)private Map test;

其他类型转换的操作基本一致,只需要修改类型等局部代码。

二、封装反序列化工具类 数据库中specs字段为json类型
[{"key": "颜色", "value": "深白色", "key_id": 1, "value_id": 3}, {"key": "尺寸", "value": "4.3英寸", "key_id": 2, "value_id": 7}]

模型中specs字段为String类型
建立Spec实体类
@Getter@Setterpublic class Spec {private Long keyId; private String key; private Long valueId; private String value; }


利用JPA的AttributeConverter接口实现属性转换过于局限
模仿JPA的AttributeConverter接口封装两个方法。
希望转换为实体类的本类型,因为默认将json数据转换为LinkHashMap类型。
通用的转换类,转换为本类。
//反序列化工具类@Componentpublic class GenericAndJson {private static ObjectMapper mapper; //将ObjectMapper注入到方法里,再通过方法赋值到成员变量上@Autowiredpublic void setMapper(ObjectMapper mapper) {GenericAndJson.mapper = mapper; }public static String objectToJson(T o) {try {return GenericAndJson.mapper.writeValueAsString(o); } catch (Exception e) {e.printStackTrace(); throw new ServerErrorException(99999); }}public static T jsonToObject(String s, TypeReference typeReference) {if (s == null) return null; try {return GenericAndJson.mapper.readValue(s, typeReference); } catch (Exception e) {e.printStackTrace(); throw new ServerErrorException(9999); }}}


如何调用自定义的转换器
在实体类中,可以通过重写getter、setter方法,自己实现想要转换的数据结构(List),本且能够得到本类(Spec)。
private String specs; public List getSpecs() {if (specs == null) return Collections.emptyList(); return GenericAndJson.jsonToObject(this.specs, new TypeReference() {}); }public void setSpecs(List specs) {if (specs.isEmpty()) return; this.specs = GenericAndJson.objectToJson(specs); }

【Spring|Spring JPA的实体属性类型转换器并反序列化工具类详解】以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

    推荐阅读