JPA JSON字符串与List以及对象的转换

百科知识2025-04-261

有时为了方便,我们会吧对象或者List以JSON字符串的形式存放在数据库中。使用JPA就可以通过@Converte的方式实现。

JSON字符与对象的转换,我们比较常用的时jackson,maven依赖如下:

com.fasterxml.jackson.core jackson-databind 2.8.0

JSONObject字符串转换为对象

这里以Order和Metadata为例。

1、首先创建用于转换Metadata对象的转换器。

@Converter(autoApply = true)
public class JSONConverter implements AttributeConverter<Metadata, String> {
private final static Logger LOGGER = LoggerFactory.getLogger(JSONConverter .class);
private final static ObjectMapper objectMapper = new ObjectMapper();

@Override
public String convertToDatabaseColumn(Metadata meta) {
    try {
        return objectMapper.writeValueAsString(meta);
    } catch (JsonProcessingException ex) {
        LOGGER.error("", ex);
        return null;
    }
}

@Override
public Metadata convertToEntityAttribute(String dbData) {
    try {
        return objectMapper.readValue(dbData, Metadata.class);
    } catch (IOException ex) {
        LOGGER.error("", ex);
        return null;
    }
}

}

代码实现了JPA转换器接口AttributeConverter,这个接口提供了两个方法:

  • convertToDatabaseColumn:用于把对象转换为数据库字段存储的值。
  • convertToEntityAttribute:用于把数据库里的字段存储的值转换为对象。

在convertToDatabaseColumn方法中,使用了Jackson的ObjectMapper的writeValuAsString,把对象转换为JSONObject的字符串。

在convertToEntityAttribute方法中,也是用了Jackson的ObjectMapper的readValue方法,把字符串转换为对象。

 

2、在Order对象中添加注解@Convert

@Entity
@Table(name = "order")
public class Order {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@Convert(converter = JSONConverter.class)
private Metadata metadata;

//…get 和set方法

}

JSONArray字符串转换为List

JSONArray与List之间的转换类似于对象的转换,但因为Jackson对List范类型的转换实现不同,所以在字符串转换List实现方式不同。

1、定义转换器

@Converter(autoApply = true)
public class OrderItemsJSONConverter implements AttributeConverter<List, String> {

private final static Logger LOGGER = LoggerFactory.getLogger(ChaptersJSONConverter.class);

private final static ObjectMapper objectMapper = new ObjectMapper();

@Override
public String convertToDatabaseColumn(List<OrderItem> meta) {
    try {
        return objectMapper.writeValueAsString(meta);
    } catch (JsonProcessingException ex) {
        LOGGER.error("", ex);
        return null;
    }
}

@Override
public List<OrderItem> convertToEntityAttribute(String dbData) {
    try {
        if(dbData == null){  //如果dbData为null会导致转换报错,可以根据业务需求对null做处理
            return new ArrayList<>();
        }
        return objectMapper.readValue(dbData, new TypeReference<List<OrderItem>>(){});
    } catch (IOException ex) {
        LOGGER.error("", ex);
        return null;
    }
}

}

在字符串转换List,objectMapper.readValue的类型时TypeReference,这个是与对象转换不同的地方。

2、Order的OrderItem列表添加@Convert注释

import javax.persistence.*;
import java.util.List;

@Entity
@Table(name = "order")
public class Order {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

@Convert(converter = JSONConverter.class)
private Metadata metadata;

@Convert(converter = ItemsJSONArrayConverter.class)
private List<OrderItem> item;

//get set方法

}