原文: https://stackoverflow.com/questions/46466562/how-to-save-and-query-dynamic-fields-in-spring-data-mongodb

MongoDB 的一大特点就是所有的记录都是文档形式,无所谓数据库字段,每一条数据都是独立的。在使用Spring Data MongoDB 时,如果直接用关系型数据库的用法去套,那会发现很难发挥MongoDB的特性。

我在搜索如何解决问题的时候,发现了一篇问答正好能解决我的问题,所以我用自己浅薄的英语做个简单的翻译。

这是一篇 Stack Overflow 上的问答

有人提了个问题,在使用 Spring Boot 1.4.x 和 Spring Data MongoDB 时,想要动态存储实体的字段,而不是直接用一个已经定义好的实体的固定字段存储。

虽然可以在实体类内部创建一个Map属性来存动态字段,但提问者想要的是所有的字段都处于MongoDB文档的顶层,不想要在字段里面还存在额外的数据结构。

提问者尝试后发现,直接将实体类继承自HashMap是不行的

Error creating bean with name 'entryRepository': Invocation of init method failed; nested exception is org.springframework.data.mapping.model.MappingException: Could not lookup mapping metadata for domain class java.util.HashMap!

问题的优质回答:

先讲结论:

  • 不能直接使用或者继承java集合类作为实体类
  • Spring Data MongoDB 的 Repositories 不能实现上面的需求
  • 使用 DBObject 类配合 MongoTemplate 才能实现

分析;

Spring Data Repositories 是MongoDB用在设计好的数据结构中的持久层,为了配合面向对象设计使用。Spring Data 在分析检查类的时候,会将集合和Map类型的类剔除出去。

Repository 的查询方法虽然也可以实现动态字段查询,但不是主流的用法。

public interface EntryRepository extends MongoRepository<Entry, String> {
@Query("{ ?0 : ?1 }")
Entry findByDynamicField(String field, Object value);
}

这个方法不提供任何类型安全检查,只是简陋地为字段提供一个别名。

最好使用 DBObject 配合 MongoTemplate 的Query方法使用。

List<DBObject> result = template.find(new Query(Criteria.where("your_dynamic_field").is(theQueryValue)), DBObject.class);

DBObject 能在不定义数据结构的情况下,直接映射MongoDB文档的结果。可以直接使用 DBObject 类结合 MongoTemplate 进行增删改查的操作。

我个人的尝试

应该是 Spring Data MongoDB 相关团队了解到了这个需求,目前的spring-data-mongodb 3.1.6 版本中,MongoTemplate 类的insert和save方法都可以直接操作Map数据,甚至对于任意实体类都能随意操作,只要指定 collection 名称就行。

HashMap object = new HashMap();
object.put("file_name", "object");
object.put("md5", "1827391");
HashMap aa = template.save(object, "file"); Student student = new Student("小明", "希望小学");
Student bb = template.save(student, "file");

以上代码均能正常执行,数据能准确存入数据库。

如何在Spring Data MongoDB 中保存和查询动态字段的更多相关文章

  1. spring data mongodb中,如果对象中的属性不想加入到数据库字段中

    spring data mongodb中,如果对象中的属性不想加入到数据库字段中,可加@Transient注解,声明为透明属性 spring data mongodb 官网帮助文档 http://ww ...

  2. 如何在Spring Data JPA中引入Querydsl

    一.环境说明 基础框架采用Spring Boot.Spring Data JPA.Hibernate.在动态查询中,有一种方式是采用Querydsl的方式. 二.具体配置 1.在pom.xml中,引入 ...

  3. Spring data mongodb @CreatedBy@LastModifiedBy@CreatedBy@LastModifiedBy SpringSecurityAuditorAware,只记录用户名

    要在Spring data mongodb 中使用@CreatedBy@LastModifiedBy@CreatedBy@LastModifiedBy  这四个注解 必须实现 SpringSecuri ...

  4. spring data mongodb 配置遇到的几个问题

    一. mongodb 2.2版本以上的配置 spring.data.mongodb.uri = mongodb://newlook:newlook@192.168.0.109:27017/admin ...

  5. 使用Spring访问Mongodb的方法大全——Spring Data MongoDB查询指南

    1.概述 Spring Data MongoDB 是Spring框架访问mongodb的神器,借助它可以非常方便的读写mongo库.本文介绍使用Spring Data MongoDB来访问mongod ...

  6. Spring Data MongoDB 三:基本文档查询(Query、BasicQuery)(一)

    一.简单介绍 Spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一 ...

  7. Spring Data MongoDB 一:入门篇(环境搭建、简单的CRUD操作)

    一.简介 Spring Data  MongoDB 项目提供与MongoDB文档数据库的集成.Spring Data MongoDB POJO的关键功能区域为中心的模型与MongoDB的DBColle ...

  8. Spring Data MongoDB 三:基本文档查询(Query、BasicQuery

    一.简介 spring Data  MongoDB提供了org.springframework.data.mongodb.core.MongoTemplate对MongoDB的CRUD的操作,上一篇我 ...

  9. Spring Data MongoDB 五:进阶文档查询(分页、Morphia)(二)

    Spring Data MongoDB 三:基本文档查询(Query.BasicQuery)(一) 学习MongoDB 六: MongoDB查询(游标操作.游标信息)(三) 一.简单介绍 Spring ...

随机推荐

  1. 运行cmd时提示你可能没有适当的权限访问该项目

    Windows无法访问指定设备.路径或文件.你可能没有适当的权限访问该项目.   方法/步骤   在C:\Windows\System32目录下中找到cmd.exe文件   右键点击 "属性 ...

  2. IE浏览器 AjaxForm文件上传错误:Stream ended unexpectedly

    错误日志: 1 org.springframework.web.multipart.MultipartException: Failed to parse multipart servlet requ ...

  3. Python自动化之封装日志模块(一)

    ------------恢复内容开始------------ 简介: 自己也在训练营学习之中,闲来之余,自己写着玩的,主要还是为了学习,希望和前辈和大佬相互学习共进. 日志模块主要有四大组件:日志器, ...

  4. php加密压缩文件

    前言 近几日,用爬虫采集的了一些数据,存放到硬盘中,随着数据量越来越多,所以想上传到网盘当中,可是不加下密又觉得不放心, 所以开始用PHP的zip模块进行压缩加密. 开始 $zipArc = new ...

  5. Java实验项目三——编程实现Person类,学生类的设计及其继承关系

    Program: 编程实现Person类,学生类的设计及其继承关系 代码如下: 定义抽象类Person 1 /* 2 * Description:建立抽象类 3 * 4 * Written By:Ca ...

  6. buu 刮开有奖

    一.查壳, 二.拖入ida,分析 直接搜字符串完全没头绪,在看了大佬的wp才找到了,关键函数. 明显那个String就是我们要求的flag,要开始分析程序. 字符串长度为8,同时这个函数对字符串进行了 ...

  7. 带实习生学Spring Boot 之 Spring Profiles

    大家好,我是指北君. 最近公司新来了一个实习生,挺上进的,天天追着我问问题.指北君开启了带实习生打怪升级之路.吶,今天问了一个关于 Spring Profiles 的问题. 实习生:指北君,你知道 S ...

  8. 简单DOS命令

    1.nslookup命令 nslookup命令是用来解析域名的,举个例子:我们只知道百度的域名是www.baidu.com 想要知道它的ip的话就要使用nslookup命令了nslookup www. ...

  9. python使用笔记26--多线程、多进程

    1.概念 线程.进程 进程是资源的集合,也就是一个程序 线程是一个程序运行的最小单位 线程是在进程里面的 默认,一个进程就只有一个线程 一个电脑有几核CPU就只能同时运行几个任务,比如4核CPU只能同 ...

  10. 结对开发_石家庄地铁查询web系统

    结对开发:队友田昕可 大二上学期做过只有两号线的地铁查询系统,但是只能在控制台操作.这一次将线路加到了六条,并且要求web实现,下面简述一下设计思路和具体代码实现: 1.数据库建表 于我们自己习惯而言 ...