Spring?JPA的實(shí)體屬性類型轉(zhuǎn)換器并反序列化工具類詳解
一、JPA 單體JSON與Map的映射
數(shù)據(jù)庫(kù)中test字段為json類型
{"key": "顏色", "value": "深白色", "key_id": 1, "value_id": 3}
模型中test字段為Map類型
private Map<String,Object> test;
問(wèn)題:如何將數(shù)據(jù)庫(kù)字段的值映射到模型中,要用到JPA的屬性轉(zhuǎn)換
創(chuàng)建一個(gè)轉(zhuǎn)換類
實(shí)現(xiàn)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; // 第一個(gè)泛型類型就是 entity字段的類型 // json沒(méi)有類型,對(duì)應(yīng)在JAVA中就是String類型 // 第二個(gè)泛型類型就是 數(shù)據(jù)庫(kù)字段的類型 @Converter public class MapAndJson implements AttributeConverter<Map<String, Object>, String> { /* ObjectMapper類是Jackson庫(kù)的主要類,它提供一些功能將數(shù)據(jù)集或?qū)ο筠D(zhuǎn)換的實(shí)現(xiàn)。 它將使用JsonParser和JsonGenerator實(shí)例來(lái)實(shí)現(xiàn)JSON的實(shí)際讀/寫(xiě)。 */ @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); } } }
看到接口的方法名,就知道能做什么了。
具體轉(zhuǎn)換需要自己實(shí)現(xiàn),調(diào)用SpringBoot提供的Jackson的內(nèi)置庫(kù)。
ObjectMapper類是Jackson庫(kù)的主要類,它提供一些功能將數(shù)據(jù)集或?qū)ο筠D(zhuǎn)換的實(shí)現(xiàn)。
在類上打上注解@Converter,做為轉(zhuǎn)換類的標(biāo)識(shí)。
只需在模型類上加個(gè)注解就能完成自動(dòng)轉(zhuǎn)換
指明轉(zhuǎn)換類
@Convert(converter = MapAndJson.class) private Map<String,Object> test;
其他類型轉(zhuǎn)換的操作基本一致,只需要修改類型等局部代碼。
二、封裝反序列化工具類
數(shù)據(jù)庫(kù)中specs字段為json類型
[{"key": "顏色", "value": "深白色", "key_id": 1, "value_id": 3}, {"key": "尺寸", "value": "4.3英寸", "key_id": 2, "value_id": 7}]
模型中specs字段為String類型
建立Spec實(shí)體類
@Getter @Setter public class Spec { private Long keyId; private String key; private Long valueId; private String value; }
利用JPA的AttributeConverter接口實(shí)現(xiàn)屬性轉(zhuǎn)換過(guò)于局限
模仿JPA的AttributeConverter接口封裝兩個(gè)方法。
希望轉(zhuǎn)換為實(shí)體類的本類型,因?yàn)槟J(rèn)將json數(shù)據(jù)轉(zhuǎn)換為L(zhǎng)inkHashMap類型。
通用的轉(zhuǎn)換類,轉(zhuǎn)換為本類。
//反序列化工具類 @Component public class GenericAndJson { private static ObjectMapper mapper; //將ObjectMapper注入到方法里,再通過(guò)方法賦值到成員變量上 @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); } } }
如何調(diào)用自定義的轉(zhuǎn)換器
在實(shí)體類中,可以通過(guò)重寫(xiě)getter、setter方法,自己實(shí)現(xiàn)想要轉(zhuǎn)換的數(shù)據(jù)結(jié)構(gòu)(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); }
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
基于Mybatis實(shí)現(xiàn)CRUD操作過(guò)程解析(xml方式)
這篇文章主要介紹了基于Mybatis實(shí)現(xiàn)CRUD操作過(guò)程解析(xml方式),文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-11-11MybatisPlus多數(shù)據(jù)源及事務(wù)解決思路
這篇文章主要介紹了MybatisPlus多數(shù)據(jù)源及事務(wù)解決思路,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-01-01一個(gè)簡(jiǎn)易的Java多頁(yè)面隊(duì)列爬蟲(chóng)程序
這篇文章主要為大家詳細(xì)介紹了一個(gè)多頁(yè)面的java爬蟲(chóng),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-08-08解決定時(shí)任務(wù)@Scheduled沒(méi)有準(zhǔn)時(shí)執(zhí)行的原因及分析
這篇文章主要介紹了解決定時(shí)任務(wù)@Scheduled沒(méi)有準(zhǔn)時(shí)執(zhí)行的原因及分析,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-04-04解讀httpclient的validateAfterInactivity連接池狀態(tài)檢測(cè)
這篇文章主要為大家介紹了httpclient的validateAfterInactivity連接池狀態(tài)檢測(cè)解讀*,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-11-11java動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理示例分享
這篇文章主要介紹了java動(dòng)態(tài)代理和cglib動(dòng)態(tài)代理示例,JDK1.3之后,Java提供了動(dòng)態(tài)代理的技術(shù),允許開(kāi)發(fā)者在運(yùn)行期間創(chuàng)建接口的代理實(shí)例,下面我們使用示例學(xué)習(xí)一下2014-03-03Spring?Boot整合阿里開(kāi)源中間件Canal實(shí)現(xiàn)數(shù)據(jù)增量同步
這篇文章主要為大家介紹了Spring?Boot整合阿里開(kāi)源中間件Canal實(shí)現(xiàn)數(shù)據(jù)增量同步示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06