【问题标题】:How I Use spring-data-jpa mongoRepository to query and update?我如何使用 spring-data-jpa mongoRepository 进行查询和更新?
【发布时间】:2020-02-27 10:52:34
【问题描述】:

这是我的实体

@Document(collection = "deviceConfig")
@Data
@Builder
public class DbDeviceConfig {
    private ObjectId _id;

//    @Field("id")
//    @Id
//    private String id;

    private String deviceId;

    private String enterpriseId;


    private Integer state;


    private String cfgKey;


    @JsonSerialize
    private String cfgValue;


    private Long cfgDate;


    private Long reportDate;


    private Integer reportCode;


    private String reportMsg;
}

如您所见,我注意到@Id
因为在我的情况下,每个设备将只有一个特定 cfgKey 的 cfgValue
因此 enterpriseId 和 deviceId 以及 cfgKey 将保持其唯一性
我写了 mongotemplate 更新 sql

Query updateQuery = new Query(Criteria.where("enterpriseId").is(enterpriseId)
                    .and("cfgKey").is(batchAddDeviceConfig.getCfgKey())
                    .and("deviceId").is(deviceId));
            Update update = new Update();
            update.set("cfgDate", System.currentTimeMillis());
            update.set("cfgValue", batchAddDeviceConfig.getCfgValue());
            update.set("state", batchAddDeviceConfig.getState());
            dataMongoTemplate.upsert(updateQuery, update, DbDeviceConfig.class, "deviceConfig");

但我不知道如何编写对应的spring jpa代码
或者我应该添加一个企业 ID?
我真的很困惑,因为 mongodb 已经创建了一个 ObjectId

我也在寻找其他人的解决方案
看来我可以用这种方式

@Modifying
@Query("UPDATE Space c SET c.owner = :name WHERE c.id = :id")
Integer setNameForId(@Param("name") String name, @Param("id")

但这会像很多参数
请帮我QAQ

【问题讨论】:

  • 这里是一些关于使用 MongoDB 和 Spring Data API 的参考信息:Spring Data MongoDB - Reference Documentation。有几种方法可以执行 CRUD 操作 - 使用 MongoRepositoryMongoTemplate API。
  • @prasad_ 谢谢,我会多注意这个文件的:)
  • 您使用的是 Spring Data JPA 还是 Spring Data MongoDb。这是两个不同的东西。

标签: java mongodb spring-data-jpa mongodb-query spring-data-mongodb


【解决方案1】:

如果您使用的是 Spring Data JPA,那么您可以使用从数据库中获取实体 repository.findBy....() 方法,在获取的实体中设置更新的值,然后在其上调用 repository.save(entity)。 Hibernate 会处理这个问题,它会更新你的实体。但是,它将为所有字段生成更新查询。如果您只想更新更改的字段,则可以在您的实体类上使用@DynamicUpdate

【讨论】:

  • 谢谢,我按照你的方法让它工作了。但是如果我保存了很多设备配置,会不会因为每个都需要查找和保存而导致效率低下?你遇到过这种情况吗?情况?但再次感谢你,这让我找到了正确使用 Spring-JPA 的方法:)
  • 如果您想要更高的效率,那么您可以跳过 find 调用并直接按照您在问题中使用的方式进行更新,即在 @Query 中使用 UPDATE。您还可以在单​​个查询中查找多条记录以获得性能,然后对其进行更新。如果您想加快查询执行速度,您还可以为要查询的字段创建索引。
【解决方案2】:

这个线程中的其他答案是有问题的......如果你 findBy 然后保存你实际上是在做一些不是原子的事情。如果您正在寻找一种原子方式来执行此操作,那么您应该记住最简单的方法(我认为唯一的方法)是使用带有更新功能的 mongo 模板......

在我看来,spring 数据存储库选项更方便。

(在此处编辑为对其中一个 cmets 的回答)

假设你想做一个 $inc 操作。此操作读取一个字段,将其递增并以原子方式将其写回 DB。在春季使用 MongoTemplate 这样做非常容易:

    Update update = new Update();
    Query query = new Query();
    query.addCriteria(Criteria.where("_id").is(id));
    update.inc("upvoteCount");
    template.updateFirst(query, update, "post");

查询找到您需要的文档,然后更新对其进行更新。

我搜索了很长时间,但找不到使用 Spring 数据存储库的方法...

我可能是错的......但我认为这种方式甚至不存在......如果存在,我希望有人向我指出它

【讨论】:

  • 您能否通过一些示例进行解释以便更好地理解。
  • 我通过编辑我的答案来回答您的评论,因为评论太长了......
猜你喜欢
  • 2018-10-05
  • 1970-01-01
  • 2017-05-05
  • 2022-07-11
  • 1970-01-01
  • 1970-01-01
  • 2018-01-13
  • 1970-01-01
  • 2015-08-04
相关资源
最近更新 更多