我是Spring数据和mongodb的新手。我有一个表示JSON模式的JSON对象,我需要使用spring数据将其存储在mongodb中。但JSON模式的问题是JSON Schema的结构是动态的;例如,下面是两个结构完全不同的有效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类,以便我可以将上面的JSON映射到已定义的类并将其存储在mongodb中。或者是否可以在Spring中进行CURD操作而不将其映射到POJO类?
答案 0 :(得分:4)
我建议您使用MongoTemplate并使用Gson / Jackson序列化和取消选择。
Mongo Template有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);
MongoTemplate
mongoTemplate.save(dbObject, "collectionname");
您可以为所有其他CRUD操作执行类似操作。
答案 1 :(得分:2)
请在此处找到必要的代码。
@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;
}
这是我的存储库类
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"
]
}
}
答案 2 :(得分:1)
在我的项目中,我有一个非常动态的模型结构,我使用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 + "]";
}
}
通过使用这一切都很好
答案 3 :(得分:1)
您可以使用@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
}
您需要一些自定义读写转换器
答案 4 :(得分:-1)
FWIW,MongoDB 3.6在数据库级别引入了JSON Schema Validation support。您可以在MongoDB's blog上阅读更多内容。希望有所帮助!