java巧用@Convert實(shí)現(xiàn)表字段自動(dòng)轉(zhuǎn)entity
1.背景
本人自入職以來(lái),接了一堆歷史包(shi)袱(shan),其中有個(gè)服務(wù)是基于MongoDB實(shí)現(xiàn)的,而公司要搞信創(chuàng)化,去掉MongoDB是遲早的事,于是便開(kāi)始分析底層數(shù)據(jù)結(jié)構(gòu),計(jì)劃用pg替換MongoDB。
2.難點(diǎn)
2.1 數(shù)據(jù)結(jié)構(gòu)不同
MongoDB是文檔型數(shù)據(jù)庫(kù),而pg是關(guān)系型數(shù)據(jù)庫(kù),原項(xiàng)目MongoDB的collection中某些字段類型為L(zhǎng)ist或者entity,存在一對(duì)多的情況,如果采用新建關(guān)聯(lián)表的方式,會(huì)增加數(shù)據(jù)結(jié)構(gòu)復(fù)雜性,且底層數(shù)據(jù)幾乎不會(huì)變,因此,覺(jué)得直接用VARCHAR類型存儲(chǔ)List類型的json串。
2.2 數(shù)據(jù)類型轉(zhuǎn)換
服務(wù)的數(shù)據(jù)庫(kù)持久化使用的是jpa,原來(lái)MongoDB類型會(huì)自動(dòng)轉(zhuǎn)成List,如下列的options屬性
@Data @Document(collection = "input_item") public class InputItem implements Comparable<InputItem> { @Id private String itemCode; private String title; private String description; private int itemType; private List<InputItemOption> options; private String defaultOptionNum; private String unit; private boolean whetherActive; }
轉(zhuǎn)成pg后,options字段在數(shù)據(jù)庫(kù)中是String類型,需要轉(zhuǎn)成List。經(jīng)過(guò)調(diào)研,可以采用自定義Converter+注解@Convert來(lái)實(shí)現(xiàn)。
2.2.1 List類型
1)自定義Converter
import com.alibaba.fastjson.JSON; import javax.persistence.AttributeConverter; /** * @ClassName JpaConverterListJson * @Description jpa list轉(zhuǎn)換為String 相互轉(zhuǎn)換工具類 * @Author ygt * @Date 2021/3/3 14:49 * @Version V1.0 */ public class JpaConverterListJson implements AttributeConverter<Object, String> { @Override public String convertToDatabaseColumn(Object o) { return JSON.toJSONString(o); } @Override public Object convertToEntityAttribute(String s) { return JSON.parseArray(s); } }
2)@Convert注解
import java.util.List; import com.fasterxml.jackson.annotation.JsonInclude; import io.swagger.annotations.ApiModel; import lombok.AllArgsConstructor; import lombok.Builder; import lombok.NoArgsConstructor; import lombok.Data; import javax.persistence.*; /** * * @Description 輸入項(xiàng)實(shí)體類 * */ @ApiModel("") @JsonInclude(value = JsonInclude.Include.NON_NULL) @Table(name = "input_item") @Builder @AllArgsConstructor @NoArgsConstructor @Data @Entity public class InputItem implements Comparable<InputItem> { @GeneratedValue @Column(name = "id") @Id private String itemCode; @Column(name = "title") private String title; @Column(name = "description") private String description; @Column(name = "itemtype") private int itemType; @Convert(converter = JpaConverterListJson.class) private List<InputItemOption> options; @Column(name = "defaultoptionnum") private String defaultOptionNum; @Column(name = "unit") private String unit; @Column(name = "whetheractive") private Boolean whetherActive; @Override public int compareTo(InputItem o) { int index1 = Integer.parseInt(this.itemCode.substring(this.itemCode.lastIndexOf('_') + 1)); int index2 = Integer.parseInt(o.itemCode.substring(o.itemCode.lastIndexOf('_') + 1)); if (index1 < index2) { return -1; } else { return 1; } } }
2.2.2 entity類型
1)自定義Converter
import com.alibaba.fastjson.JSON; import com.fasterxml.jackson.databind.ObjectMapper; import com.test.src.domain.index.interest.InterestCreditScoreSection; import javax.persistence.AttributeConverter; import java.lang.reflect.ParameterizedType; /** * @ClassName JpaConverterListJson * @Description jpa 泛型T轉(zhuǎn)換為String 相互轉(zhuǎn)換工具類 * @Author ygt * @Date 2021/3/3 14:49 * @Version V1.0 */ public class JpaConverterObjectJson<T> implements AttributeConverter<T, String> { private static final ObjectMapper objectMapper = new ObjectMapper(); @Override public String convertToDatabaseColumn(T o) { try { return objectMapper.writeValueAsString(o); } catch (Exception e) { throw new RuntimeException("Failed to convert object to string", e); } } @Override public T convertToEntityAttribute(String s) { try { return objectMapper.readValue(s, (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0]); } catch (Exception e) { throw new RuntimeException("Failed to convert string to object", e); } } }
import com.test.src.domain.index.interest.InterestCreditScoreSection; public class InterestCreditScoreSectionConverter extends JpaConverterObjectJson<InterestCreditScoreSection>{ }
2)@Convert注解
import com.fasterxml.jackson.annotation.JsonInclude; import com.test.src.utils.InterestCreditScoreSectionConverter; import io.swagger.annotations.ApiModel; import lombok.NoArgsConstructor; import lombok.*; import javax.persistence.*; /** * * @Description 利率授信實(shí)體類 */ @ApiModel("") @JsonInclude(value = JsonInclude.Include.NON_NULL) @Table(name = "interest_credit") @Builder @AllArgsConstructor @NoArgsConstructor @Data @Entity public class InterestCredit { @Id @GeneratedValue @Column(name = "id") private String itemNo; @Column(name = "recommendinterestformula") private String recommendInterestFormula; //推薦執(zhí)行利率計(jì)算公式; @Convert(converter = InterestCreditScoreSectionConverter.class) @Column(name = "interestcreditscoresection") private InterestCreditScoreSection interestCreditScoreSection; }
3.總結(jié)
針對(duì)不好處理的json string類型,可通過(guò)自定義converter+@Convert的方式實(shí)現(xiàn)自動(dòng)轉(zhuǎn)換,另外,可在自定義converter類上加@Convert(autoApply = true)實(shí)現(xiàn)全局自動(dòng)轉(zhuǎn)換。
到此這篇關(guān)于java巧用@Convert實(shí)現(xiàn)表字段自動(dòng)轉(zhuǎn)entity的文章就介紹到這了,更多相關(guān)java 表字段自動(dòng)轉(zhuǎn)entity內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
- Java中IdentityHashMap與HashMap區(qū)別詳解
- Java集合中的WeakHashMap、IdentityHashMap、EnumMap詳解
- Java8中關(guān)于Function.identity()的使用
- Java后端中dto、vo、entity的區(qū)別淺析
- Java中的javaBean、vo、entity、domain和pojo
- Java中Json與List、Map、entity的互相轉(zhuǎn)化
- Java詳解entity轉(zhuǎn)換到vo過(guò)程
- java 后臺(tái)開(kāi)發(fā)中model與entity(實(shí)體類)的區(qū)別說(shuō)明
- Java實(shí)體類(entity)作用說(shuō)明
相關(guān)文章
SpringBoot實(shí)現(xiàn)異步任務(wù)的項(xiàng)目實(shí)踐
本文將使用SpringBoot 去實(shí)現(xiàn)異步之間的調(diào)用,提高系統(tǒng)的并發(fā)性能、用戶體驗(yàn),具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10SpringBoot中實(shí)現(xiàn)接收文件和對(duì)象
這篇文章主要介紹了SpringBoot實(shí)現(xiàn)接收文件和對(duì)象,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-07-07SpringBoot整合Redis并且用Redis實(shí)現(xiàn)限流的方法 附Redis解壓包
這篇文章主要介紹了SpringBoot整合Redis并且用Redis實(shí)現(xiàn)限流的方法 附Redis解壓包,本文給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧2024-06-06Java消息隊(duì)列RabbitMQ之消息回調(diào)詳解
這篇文章主要介紹了Java消息隊(duì)列RabbitMQ之消息回調(diào)詳解,消息回調(diào),其實(shí)就是消息確認(rèn)(生產(chǎn)者推送消息成功,消費(fèi)者接收消息成功) , 對(duì)于程序來(lái)說(shuō),發(fā)送者沒(méi)法確認(rèn)是否發(fā)送成功,需要的朋友可以參考下2023-07-07淺談讓@Value更方便的Spring自定義轉(zhuǎn)換類
Spring為大家內(nèi)置了不少開(kāi)箱即用的轉(zhuǎn)換類,如字符串轉(zhuǎn)數(shù)字、字符串轉(zhuǎn)時(shí)間等,但有時(shí)候需要使用自定義的屬性,則需要自定義轉(zhuǎn)換類了2021-06-06