1.背景
本人自入职以来,接了一堆历史包(shi)袱(shan),其中有个服务是基于mongodb实现的,而公司要搞信创化,去掉mongodb是迟早的事,于是便开始分析底层数据结构,计划用pg替换mongodb。
2.难点
2.1 数据结构不同
mongodb是文档型数据库,而pg是关系型数据库,原项目mongodb的collection中某些字段类型为list或者entity,存在一对多的情况,如果采用新建关联表的方式,会增加数据结构复杂性,且底层数据几乎不会变,因此,觉得直接用varchar类型存储list类型的json串。
2.2 数据类型转换
服务的数据库持久化使用的是jpa,原来mongodb类型会自动转成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;
}转成pg后,options字段在数据库中是string类型,需要转成list。经过调研,可以采用自定义converter+注解@convert来实现。
2.2.1 list类型
1)自定义converter
import com.alibaba.fastjson.json;
import javax.persistence.attributeconverter;
/**
* @classname jpaconverterlistjson
* @description jpa list转换为string 相互转换工具类
* @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 输入项实体类
*
*/
@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转换为string 相互转换工具类
* @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 利率授信实体类
*/
@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; //推荐执行利率计算公式;
@convert(converter = interestcreditscoresectionconverter.class)
@column(name = "interestcreditscoresection")
private interestcreditscoresection interestcreditscoresection;
}3.总结
针对不好处理的json string类型,可通过自定义converter+@convert的方式实现自动转换,另外,可在自定义converter类上加@convert(autoapply = true)实现全局自动转换。
到此这篇关于java巧用@convert实现表字段自动转entity的文章就介绍到这了,更多相关java 表字段自动转entity内容请搜索代码网以前的文章或继续浏览下面的相关文章希望大家以后多多支持代码网!
发表评论