【问题标题】:How to persist an entity as Json in MySql?如何在 MySql 中将实体作为 Json 持久化?
【发布时间】:2019-08-04 00:50:41
【问题描述】:

我正在使用springhibernate@Entity 类持久化到mysql 数据库中。

对于一个属性,我想将对象保留为 StringJson 字段,而不是创建一个额外的表并使用 @OneToOne 引用映射或类似的。

以以下为例:

@Entity
public class Customer {

    //@JsonObject
    private List<Address> address;
}

public class Address {
    private String street, number, city, zip, country;
}

问题:我如何告诉休眠自动将该地址保存为字符串/json?当然,在读取 string/json 时应该重新映射到 Address 对象中。

【问题讨论】:

  • 您可以尝试为其编写自定义序列化程序,或将其保存到数据库本身的 json 类型中(答案中有详细信息)

标签: java mysql json spring hibernate


【解决方案1】:

您可以将 json 存储到 mySQL 表中:

CREATE TABLE `book` (
  `id` mediumint(8) unsigned NOT NULL AUTO_INCREMENT,
  `title` varchar(200) NOT NULL,
  `tags` json DEFAULT NULL,
  PRIMARY KEY (`id`)
)

插入查询:

INSERT INTO `book` (`title`, `tags`)
VALUES (
  'ECMAScript 2015: A SitePoint Anthology',
  '["JavaScript", "ES2015", "JSON"]'
);

在 hibernate 中,您应该创建必须实现 org.hibernate.usertype 的类(如“com.test.MyJsonType”)。 UserType 接口,其中 nullSafeGet 方法应将 JSON 反序列化为 java 对象(使用 Jackson),nullSafeSet 将 POJO 序列化为 JSON 和一些其他辅助方法。

【讨论】:

  • 难道没有比实现UserType 接口更简单的方法了吗?需要自己实现大约10 个方法?
  • 您想为该字段实现序列化器和反序列化器,然后将其存储为字符串吗?
  • 在这里找到了一个库:vladmihalcea.com/…
  • 也许,我已经在使用 Jackson (de)serializer 作为 web 服务端点。所以你认为我应该将实体保存为序列化字符串,然后手动反序列化?
【解决方案2】:

目前我可以用AttributesConverter 解决它。很高兴Spring 可以自动将杰克逊映射器注入其中:

@Entity
public class Customer {
    @Convert(converter = AddressConverter.class)
    @Lob
    @Column(columnDefinition = "text")
    private List<Address> address;
}

@Converter
public class AddressConverter implements AttributeConverter<List<Address>, String> {
    private ObjectMapper objectMapper;

    @Autowired //injected by spring
    public AddressConverter(ObjectMapper objectMapper) {
        this.objectMapper = objectMapper;
    }

    @Override
    public String convertToDatabaseColumn(List<AddressConverter> list) {
        try {
            if (!CollectionUtils.isEmpty(list))
                return objectMapper.writeValueAsString(list);
        } catch (final JsonProcessingException e) {
            LOGGER.error(e);
        }

        return null;
    }

    @Override
    public List<Address> convertToEntityAttribute(String json) {
        try {
            if (StringUtils.isNotBlank(json))
                return objectMapper.readValue(json, List.class);
        } catch (final IOException e) {
            LOGGER.error(e);
        }

        return null;
    }
}

【讨论】:

    猜你喜欢
    • 2015-11-15
    • 1970-01-01
    • 2013-06-16
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 2011-11-20
    • 2015-04-15
    相关资源
    最近更新 更多