将json对象中的元素数组保存到不同的行中

问题描述 投票:1回答:1

在保存包含多个jsons的json对象时,json对象将保存为单个数组而不是多个行。

样品json:

[
    {
     "id"   : 1, -- this is not a primary key and not unique but cannot be null
     "name" : "John Doe",
     "phone" : [
       { "type" : "home", "ref" : "111-111-1234"},
       { "type" : "work", "ref" : "222-222-2222"}
     ]
   },
   {
    "id"   : 2, -- this is not a primary key and not unique but cannot be null
    "name" : "Jane Doe",
    "phone" : [
      { "type" : "home", "ref" : "111-111-1234"},
      { "type" : "work", "ref" : "222-222-2222"}
    ]
  }
]

这是保存在数据库后我需要的

id   name         phone    
1    John Doe     { "type" : "home", "ref" : "111-111-1234"}
1    John Doe     { "type" : "work", "ref" : "222-222-2222"}
2    Jane Doe     { "type" : "home", "ref" : "111-111-1234"}
2    Jane Doe     { "type" : "work", "ref" : "222-222-2222"}

这就是我得到的

id   name         phone    
1    John Doe     [{ "type" : "home", "ref" : "111-111-1234"},{ "type" : "work", "ref" : "222-222-2222"}]
2    Jane Doe    [{ "type" : "home", "ref" : "111-111-1234"},{ "type" : "work", "ref" : "222-222-2222"}]

这是我如何将json对象解析为pojo并保存到db

@Entity
@Table(name="person")
public class person{
    private Integer id;
    private String name;
    private String phone;
    @Transient 
    JsonNode phoneJson;

    private static OhjectMapper mapper = new ObjectMapper();

    getter/setter

    @Transient
    public JsonNode getPhoneJson(){
        return phoneJson;
    }

    public void setPhoneJson(JsonNode phoneJson){
        this.phoneJson = phoneJson;
    }

    @JsonIgnore
    @Column(name="phone")
    public String getPhone() throws Exception{
        return mapper.writeValueAsString(phoneJson);
    }

    public void setPhone(String phone) throws Exception{
        this.phone = mapper.readTree(phone);
    }
}

dao-save

personRepository.save(person)

任何帮助,将不胜感激。

UPDATE

多个jSON列

[
    {
     "id"   : 1, -- this primary key and not unique but cannot be null
     "name" : { --this element can be empty/null
        "first" : "John",
        "last" : "Doe" 
      },
     "phone" : [
       { "type" : "home", "ref" : 1111111234},
       { "type" : "work", "ref" : 2222222222}
     ]
   },
   {
    "id"   : 2, -- this primary key and not unique but cannot be null
    "name" : {
        "first" : "Jane",
        "last" : "Doe" 
      },
    "phone" : [
      { "type" : "home", "ref" : 1111111234},
      { "type" : "work", "ref" : 2222222222}
    ]
  }
]

我如何得到如下结果

id   name                   phone    
1    [{John},{Doe}]     { "type" : "home", "ref" : "111-111-1234"}
1    [{John},{Doe}]     { "type" : "work", "ref" : "222-222-2222"}
2    [{Jane},{Doe}]     { "type" : "home", "ref" : "111-111-1234"}
2    [{Jane},{Doe}]     { "type" : "work", "ref" : "222-222-2222"}
json spring-boot spring-data-jpa spring-data spring-data-rest
1个回答
2
投票

您需要复制Person对象n次,其中nphone数组的大小。为了说清楚,我建议创建两个单独的模型,我们可以单独使用它来解析JSON并保存在DB中。您可以在下面找到以下简单示例:

  1. JSON解析为List<JsonPerson>
  2. List<JsonPerson>转换为List<Person>
  3. 打印List<Person>(你可以保存到DB

例:

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.type.CollectionType;

import java.io.File;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

public class JsonApp {

    public static void main(String[] args) throws Exception {
        File jsonFile = new File("./resource/test.json").getAbsoluteFile();

        ObjectMapper mapper = new ObjectMapper();
        CollectionType personsType = mapper.getTypeFactory().constructCollectionType(List.class, JsonPerson.class);

        // parse
        List<JsonPerson> jsonPersons = mapper.readValue(jsonFile, personsType);

        // convert
        List<Person> persons = jsonPersons.stream()
                .map(p -> p.mapTo(mapper))
                .flatMap(List::stream)
                .collect(Collectors.toList());

        persons.forEach(System.out::println);

        // save persons to DB
        // ...
    }
}

class JsonPerson {

    private Integer id;
    private String name;
    private ArrayNode phone;

    public List<Person> mapTo(ObjectMapper mapper) {
        List<Person> persons = new ArrayList<>();
        phone.elements().forEachRemaining(phone -> {
            persons.add(map(mapper, phone));
        });

        return persons;
    }

    private Person map(ObjectMapper mapper, JsonNode p) {
        Person person = new Person();
        person.setId(id);
        person.setName(name);
        try {
            person.setPhone(mapper.writeValueAsString(p));
        } catch (JsonProcessingException e) {
            throw new IllegalStateException(e);
        }

        return person;
    }

    // getters, setters, toString
}

class Person {

    private Integer id;
    private String name;
    private String phone;

    // getters, setters, toString
}

上面的代码打印:

Person{id=1, name='John Doe', phone='{"type":"home","ref":"111-111-1234"}'}
Person{id=1, name='John Doe', phone='{"type":"work","ref":"222-222-2222"}'}
Person{id=2, name='Jane Doe', phone='{"type":"home","ref":"111-111-1234"}'}
Person{id=2, name='Jane Doe', phone='{"type":"work","ref":"222-222-2222"}'}

上面的代码将JSON解析与其他部分分开。另外,不要在每个ObjectMapper中创建POJOPOJO不应该对ObjectMapperJackson有任何了解。

更新

因为nameJSON Object你可以创建新的POJO - Namefirstlast属性或类似于phone和deserialise到JsonNode

class JsonPerson {

    private Integer id;
    private JsonNode name;
    private ArrayNode phone;

    public List<Person> mapTo(ObjectMapper mapper) {
        List<Person> persons = new ArrayList<>();
        phone.elements().forEachRemaining(phone -> {
            persons.add(map(mapper, phone));
        });

        return persons;
    }

    private Person map(ObjectMapper mapper, JsonNode p) {
        Person person = new Person();
        person.setId(id);
        person.setName(getNameAsString());
        try {
            person.setPhone(mapper.writeValueAsString(p));
        } catch (JsonProcessingException e) {
            throw new IllegalStateException(e);
        }

        return person;
    }

    private String getNameAsString() {
        if (name == null) {
            return null;
        }
        StringBuilder builder = new StringBuilder();
        if (name.isObject()) {
            ObjectNode nameObject = (ObjectNode) name;
            builder.append("[");
            builder.append("{").append(nameObject.get("first")).append("}");
            builder.append(",");
            builder.append("{").append(nameObject.get("last")).append("}");
            builder.append("]");
        }
        return builder.toString();
    }

    // getters, setters, toString
}

更改上面的代码后应打印:

Person{id=1, name='[{"John"},{"Doe"}]', phone='{"type":"home","ref":1111111234}'}
Person{id=1, name='[{"John"},{"Doe"}]', phone='{"type":"work","ref":2222222222}'}
Person{id=2, name='[{"Jane"},{"Doe"}]', phone='{"type":"home","ref":1111111234}'}
Person{id=2, name='[{"Jane"},{"Doe"}]', phone='{"type":"work","ref":2222222222}'}

getNameAsString方法被简化,您需要处理所有角落情况并为Stringnullempty节点更好地创建semi-empty表示。

© www.soinside.com 2019 - 2024. All rights reserved.