将 json 对象中的元素数组保存到不同的行中
Posted
技术标签:
【中文标题】将 json 对象中的元素数组保存到不同的行中【英文标题】:Saving arrays of elements in the json object into different rows 【发布时间】:2019-08-31 23:30:57 【问题描述】:在保存包含多个 json 的 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);
道-保存
personRepository.save(person)
任何帮助将不胜感激。
更新
多个 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"
【问题讨论】:
【参考方案1】:您需要复制Person
对象n
次,其中n
的大小为phone
数组。为了清楚起见,我建议创建两个单独的模型,我们可以分别使用它们来解析 JSON
并保存在 DB
中。您可以在下面找到简单的示例:
-
将
JSON
解析为List<JsonPerson>
将List<JsonPerson>
转换为List<Person>
打印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
上面的代码打印:
Personid=1, name='John Doe', phone='"type":"home","ref":"111-111-1234"'
Personid=1, name='John Doe', phone='"type":"work","ref":"222-222-2222"'
Personid=2, name='Jane Doe', phone='"type":"home","ref":"111-111-1234"'
Personid=2, name='Jane Doe', phone='"type":"work","ref":"222-222-2222"'
以上代码将解析JSON
与其他部分分开。另外,不要在每个POJO
中创建ObjectMapper
。 POJO
应该对 ObjectMapper
和 Jackson
一无所知。
更新
因为name
是JSON Object
,您可以使用first
和last
属性创建新的POJO
- Name
,或者将其与phone
类似地处理并反序列化为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
上面的代码修改后应该打印出来:
Personid=1, name='["John","Doe"]', phone='"type":"home","ref":1111111234'
Personid=1, name='["John","Doe"]', phone='"type":"work","ref":2222222222'
Personid=2, name='["Jane","Doe"]', phone='"type":"home","ref":1111111234'
Personid=2, name='["Jane","Doe"]', phone='"type":"work","ref":2222222222'
getNameAsString
方法被简化,您需要处理所有极端情况并为null
、empty
和semi-empty
节点创建更好的String
表示。
【讨论】:
谢谢 Michal,我已经更新了我的问题,因为我有多个 json 列,但只有 phone 列需要保存在不同的行中。此外,在读取值 ListPOJO
类或*Node
类。更新后看看我的答案。以上是关于将 json 对象中的元素数组保存到不同的行中的主要内容,如果未能解决你的问题,请参考以下文章
Python - 如何将 python36 命令行中的行保存到 .py 文件中?
Python - 如何将python36命令行中的行保存到.py文件中?