使用 spring 在 mongodb 中存储 JSON 模式
Storing a JSON schema in mongodb with spring
我是 Spring 数据和 mongodb 的新手。我有一个 JSON 对象,它表示 JSON 模式,我需要使用 spring 数据将其存储在 mongodb 中。但是 JSON 模式的问题是 JSON 模式的结构是动态的;例如,下面是两个具有完全不同结构的有效 JSON 模式。
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 10
},
"age": {
"type": "integer"
}
},
"required": [
"name",
"age"
]
}
{
"type": "array",
"items": {
"type": "object",
"properties": {
"abc": {
"type": "boolean"
},
"xyz": {
"$ref": "#/definitions/"
},
"asd": {
"type": "null"
}
},
"required": [
"abc",
"xyz"
]
}
}
如何定义一个 JAVA POJO Class 以便我可以将上面的 JSON 映射到定义的 class 并将其存储在 mongodb .或者是否可以在 spring 中执行 CURD 操作而不将其映射到 POJO class?
在我的项目中,我的模型结构非常动态,我使用 java.util.Map
对象
映射它们
我的 mondo 文档模型是这样实现的:
@Document(collection = "e_form_data")
public class FormDataModel extends AbstractModel
{
private static final long serialVersionUID = -1733975205300782871L;
@Field
@Indexed(name = "e_form_id_idx")
private String eFormId;
@Field
private Map<String, Object> eFormData;
public FormDataModel()
{
super();
}
public FormDataModel(String id, String creatoDa, String modificatoDa, Date dataCreazione, Date dataModifica, String eFormId, Map<String, Object> eFormData)
{
super(id, creatoDa, modificatoDa, dataCreazione, dataModifica);
this.eFormData = eFormData;
this.eFormId = eFormId;
}
public FormDataModel(Map<String, Object> eFormData)
{
super();
this.eFormData = eFormData;
}
public Map<String, Object> geteFormData()
{
return eFormData;
}
public void seteFormData(Map<String, Object> eFormData)
{
this.eFormData = eFormData;
}
public String geteFormId()
{
return eFormId;
}
public void seteFormId(String eFormId)
{
this.eFormId = eFormId;
}
public String getDataInserimento()
{
return Utils.formatDateTime(new DateTime(this.dataCreazione.getTime()), "dd/MM/yyyy");
}
@Override
public String toString()
{
return "FormDataModel [eFormId=" + eFormId + ", eFormData=" + eFormData + "]";
}
}
通过使用这个一切都很好
您可以使用 @DBref
映射嵌入式文档
@Document(collection = "first")
public class First {
@Id
private String id;
@DBRef
private Properties properties;
@Field
private List<String> required;
// constructor
// getters and setter
}
public class Properties {
@Id
private String id;
@DBRef
private Name name;
@DBRef
private Age age;
// constructor
// getters and setter
}
public class Name { ... }
public class Age { ... }
http://www.baeldung.com/cascading-with-dbref-and-lifecycle-events-in-spring-data-mongodb
或者按照 Angelo Immediata 的建议
@Document(collection = "first")
public class First {
@Id
private String id;
@Field
private Map<String, Object> properties;
@Field
private List<String> required;
// constructor
// getters and setter
}
并且您将需要一些自定义读写转换器
请在此处找到必要的代码。
@lombok.Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Bounty {
String type;
Map<String, Object> items;
Map<String, Object> properties;
List<Object> required;
}
这是我的存储库 class
public interface BountyRepository extends MongoRepository<Bounty, String> {
}
这是一个控制器片段,您可以用来试用
@GetMapping("/insert/{number}")
public void insert(@PathVariable int number){
bountyRepository.save(getBounty(number));
}
public Bounty getBounty(int number){
ObjectMapper objectMapper = new ObjectMapper();
String jsonString1 = "{\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
" \"name\": {\n" +
" \"type\": \"string\",\n" +
" \"minLength\": 10\n" +
" },\n" +
" \"age\": {\n" +
" \"type\": \"integer\"\n" +
" }\n" +
" },\n" +
" \"required\": [\n" +
" \"name\",\n" +
" \"age\"\n" +
" ]\n" +
"}";
String jsonString2 = "{\n" +
" \"type\": \"array\",\n" +
" \"items\": {\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
" \"abc\": {\n" +
" \"type\": \"boolean\"\n" +
" },\n" +
" \"xyz\": {\n" +
" \"$ref\": \"#/definitions/\"\n" +
" },\n" +
" \"asd\": {\n" +
" \"type\": \"null\"\n" +
" }\n" +
" },\n" +
" \"required\": [\n" +
" \"abc\",\n" +
" \"xyz\"\n" +
" ]\n" +
" }\n" +
"}";
try {
Bounty bounty1 = objectMapper.readValue(jsonString1, Bounty.class);
Bounty bounty2 = objectMapper.readValue(jsonString2, Bounty.class);
if (number == 1) return bounty1;
if (number == 2) return bounty2;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
这是 Mongo 保存后的样子。
/* 1 */
{
"_id" : ObjectId("58da2390fde4f133178499fa"),
"_class" : "pani.kiran.sumne.model.Bounty",
"type" : "object",
"properties" : {
"name" : {
"type" : "string",
"minLength" : 10
},
"age" : {
"type" : "integer"
}
},
"required" : [
"name",
"age"
]
}
/* 2 */
{
"_id" : ObjectId("58da23adfde4f133178499fb"),
"_class" : "pani.kiran.sumne.model.Bounty",
"type" : "array",
"items" : {
"type" : "object",
"properties" : {
"abc" : {
"type" : "boolean"
},
"xyz" : {
"$ref" : "#/definitions/"
},
"asd" : {
"type" : "null"
}
},
"required" : [
"abc",
"xyz"
]
}
}
我建议使用 MongoTemplate and serialize and deserailize using Gson/Jackson。
Mongo 模板有 CRUD 方法,它采用集合名称和 DBObject 实体,这与直接使用 mongo java 驱动程序非常相似。
因此您将拥有 json 有效负载并使用映射器库之一将它们转换为 Map
。
类似
反序列化
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String,Object>> typeRef
= new TypeReference<HashMap<String,Object>>() {};
HashMap<String,Object> map = mapper.readValue(jsonpayload, typeRef);
DBObject
DBObject dbObject = new BasicDBObject(map);
Mongo模板
mongoTemplate.save(dbObject, "collectionname");
您可以对所有其他 CRUD 操作执行类似的操作。
FWIW,MongoDB 引入了 3.6 JSON Schema Validation support at the database level. You can read more on MongoDB's blog。希望能有所帮助!
我是 Spring 数据和 mongodb 的新手。我有一个 JSON 对象,它表示 JSON 模式,我需要使用 spring 数据将其存储在 mongodb 中。但是 JSON 模式的问题是 JSON 模式的结构是动态的;例如,下面是两个具有完全不同结构的有效 JSON 模式。
{
"type": "object",
"properties": {
"name": {
"type": "string",
"minLength": 10
},
"age": {
"type": "integer"
}
},
"required": [
"name",
"age"
]
}
{
"type": "array",
"items": {
"type": "object",
"properties": {
"abc": {
"type": "boolean"
},
"xyz": {
"$ref": "#/definitions/"
},
"asd": {
"type": "null"
}
},
"required": [
"abc",
"xyz"
]
}
}
如何定义一个 JAVA POJO Class 以便我可以将上面的 JSON 映射到定义的 class 并将其存储在 mongodb .或者是否可以在 spring 中执行 CURD 操作而不将其映射到 POJO class?
在我的项目中,我的模型结构非常动态,我使用 java.util.Map
对象
我的 mondo 文档模型是这样实现的:
@Document(collection = "e_form_data")
public class FormDataModel extends AbstractModel
{
private static final long serialVersionUID = -1733975205300782871L;
@Field
@Indexed(name = "e_form_id_idx")
private String eFormId;
@Field
private Map<String, Object> eFormData;
public FormDataModel()
{
super();
}
public FormDataModel(String id, String creatoDa, String modificatoDa, Date dataCreazione, Date dataModifica, String eFormId, Map<String, Object> eFormData)
{
super(id, creatoDa, modificatoDa, dataCreazione, dataModifica);
this.eFormData = eFormData;
this.eFormId = eFormId;
}
public FormDataModel(Map<String, Object> eFormData)
{
super();
this.eFormData = eFormData;
}
public Map<String, Object> geteFormData()
{
return eFormData;
}
public void seteFormData(Map<String, Object> eFormData)
{
this.eFormData = eFormData;
}
public String geteFormId()
{
return eFormId;
}
public void seteFormId(String eFormId)
{
this.eFormId = eFormId;
}
public String getDataInserimento()
{
return Utils.formatDateTime(new DateTime(this.dataCreazione.getTime()), "dd/MM/yyyy");
}
@Override
public String toString()
{
return "FormDataModel [eFormId=" + eFormId + ", eFormData=" + eFormData + "]";
}
}
通过使用这个一切都很好
您可以使用 @DBref
@Document(collection = "first")
public class First {
@Id
private String id;
@DBRef
private Properties properties;
@Field
private List<String> required;
// constructor
// getters and setter
}
public class Properties {
@Id
private String id;
@DBRef
private Name name;
@DBRef
private Age age;
// constructor
// getters and setter
}
public class Name { ... }
public class Age { ... }
http://www.baeldung.com/cascading-with-dbref-and-lifecycle-events-in-spring-data-mongodb
或者按照 Angelo Immediata 的建议
@Document(collection = "first")
public class First {
@Id
private String id;
@Field
private Map<String, Object> properties;
@Field
private List<String> required;
// constructor
// getters and setter
}
并且您将需要一些自定义读写转换器
请在此处找到必要的代码。
@lombok.Data
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
public class Bounty {
String type;
Map<String, Object> items;
Map<String, Object> properties;
List<Object> required;
}
这是我的存储库 class
public interface BountyRepository extends MongoRepository<Bounty, String> {
}
这是一个控制器片段,您可以用来试用
@GetMapping("/insert/{number}")
public void insert(@PathVariable int number){
bountyRepository.save(getBounty(number));
}
public Bounty getBounty(int number){
ObjectMapper objectMapper = new ObjectMapper();
String jsonString1 = "{\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
" \"name\": {\n" +
" \"type\": \"string\",\n" +
" \"minLength\": 10\n" +
" },\n" +
" \"age\": {\n" +
" \"type\": \"integer\"\n" +
" }\n" +
" },\n" +
" \"required\": [\n" +
" \"name\",\n" +
" \"age\"\n" +
" ]\n" +
"}";
String jsonString2 = "{\n" +
" \"type\": \"array\",\n" +
" \"items\": {\n" +
" \"type\": \"object\",\n" +
" \"properties\": {\n" +
" \"abc\": {\n" +
" \"type\": \"boolean\"\n" +
" },\n" +
" \"xyz\": {\n" +
" \"$ref\": \"#/definitions/\"\n" +
" },\n" +
" \"asd\": {\n" +
" \"type\": \"null\"\n" +
" }\n" +
" },\n" +
" \"required\": [\n" +
" \"abc\",\n" +
" \"xyz\"\n" +
" ]\n" +
" }\n" +
"}";
try {
Bounty bounty1 = objectMapper.readValue(jsonString1, Bounty.class);
Bounty bounty2 = objectMapper.readValue(jsonString2, Bounty.class);
if (number == 1) return bounty1;
if (number == 2) return bounty2;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
这是 Mongo 保存后的样子。
/* 1 */
{
"_id" : ObjectId("58da2390fde4f133178499fa"),
"_class" : "pani.kiran.sumne.model.Bounty",
"type" : "object",
"properties" : {
"name" : {
"type" : "string",
"minLength" : 10
},
"age" : {
"type" : "integer"
}
},
"required" : [
"name",
"age"
]
}
/* 2 */
{
"_id" : ObjectId("58da23adfde4f133178499fb"),
"_class" : "pani.kiran.sumne.model.Bounty",
"type" : "array",
"items" : {
"type" : "object",
"properties" : {
"abc" : {
"type" : "boolean"
},
"xyz" : {
"$ref" : "#/definitions/"
},
"asd" : {
"type" : "null"
}
},
"required" : [
"abc",
"xyz"
]
}
}
我建议使用 MongoTemplate and serialize and deserailize using Gson/Jackson。
Mongo 模板有 CRUD 方法,它采用集合名称和 DBObject 实体,这与直接使用 mongo java 驱动程序非常相似。
因此您将拥有 json 有效负载并使用映射器库之一将它们转换为 Map
。
类似
反序列化
ObjectMapper mapper = new ObjectMapper();
TypeReference<HashMap<String,Object>> typeRef
= new TypeReference<HashMap<String,Object>>() {};
HashMap<String,Object> map = mapper.readValue(jsonpayload, typeRef);
DBObject
DBObject dbObject = new BasicDBObject(map);
Mongo模板
mongoTemplate.save(dbObject, "collectionname");
您可以对所有其他 CRUD 操作执行类似的操作。
FWIW,MongoDB 引入了 3.6 JSON Schema Validation support at the database level. You can read more on MongoDB's blog。希望能有所帮助!