Spring JPA的實體屬性類型轉換器並反序列化工具類詳解
一、JPA 單體JSON與Map的映射
數據庫中test字段為json類型
{"key": "顏色", "value": "深白色", "key_id": 1, "value_id": 3}
模型中test字段為Map類型
private Map<String,Object> 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類型 // 第二個泛型類型就是 數據庫字段的類型 @Converter public class MapAndJson implements AttributeConverter<Map<String, Object>, String> { /* ObjectMapper類是Jackson庫的主要類,它提供一些功能將數據集或對象轉換的實現。 它將使用JsonParser和JsonGenerator實例來實現JSON的實際讀/寫。 */ @Autowired private ObjectMapper mapper; @Override public String convertToDatabaseColumn(Map<String, Object> map) { try { return mapper.writeValueAsString(map); } catch (Exception e) { e.printStackTrace(); throw new ServerErrorException(99999); } } @Override @SuppressWarnings("unchecked") public Map<String, Object> 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<String,Object> 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 @Setter public class Spec { private Long keyId; private String key; private Long valueId; private String value; }
利用JPA的AttributeConverter接口實現屬性轉換過於局限
模仿JPA的AttributeConverter接口封裝兩個方法。
希望轉換為實體類的本類型,因為默認將json數據轉換為LinkHashMap類型。
通用的轉換類,轉換為本類。
//反序列化工具類 @Component public class GenericAndJson { private static ObjectMapper mapper; //將ObjectMapper註入到方法裡,再通過方法賦值到成員變量上 @Autowired public void setMapper(ObjectMapper mapper) { GenericAndJson.mapper = mapper; } public static <T> String objectToJson(T o) { try { return GenericAndJson.mapper.writeValueAsString(o); } catch (Exception e) { e.printStackTrace(); throw new ServerErrorException(99999); } } public static <T> T jsonToObject(String s, TypeReference<T> 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<Spec> getSpecs() { if (specs == null) return Collections.emptyList(); return GenericAndJson.jsonToObject(this.specs, new TypeReference<List<Spec>>() {}); } public void setSpecs(List<Spec> specs) { if (specs.isEmpty()) return; this.specs = GenericAndJson.objectToJson(specs); }
以上為個人經驗,希望能給大傢一個參考,也希望大傢多多支持WalkonNet。
推薦閱讀:
- 詳解Java-Jackson使用
- springboot響應json null值過濾方式
- Java中常用解析工具jackson及fastjson的使用
- 詳解Jackson的基本用法
- 實例詳解SpringBoot默認的JSON解析方案