Spring Mongo 仅通过新 POJO 的非空字段进行更新
Posted
技术标签:
【中文标题】Spring Mongo 仅通过新 POJO 的非空字段进行更新【英文标题】:Spring Mongo update by only not null fields of new POJO 【发布时间】:2020-09-25 22:37:45 【问题描述】:用户模型:
@Document(collection = "USER")
public class UserModel
private String id;
private String username;
@Indexed(unique = true)
private String email;
private String password;
private String firstName;
private String lastName;
用户存储库:
@Repository
public interface UserRepository extends MongoRepository<UserModel, String>
Optional<UserModel> findByEmail(String email);
Optional<UserModel> findByUsername(String username);
像这样保存用户文档:
@Autowired
UserRepository userRepo;
public someMethod()
UserModel user = new UserModel();
//Set all fields....
userRepo.save(user);
尝试像这样更新:
@Autowired
UserRepository userRepo;
public someMethod()
UserModel user = new UserModel();
user.setId("A valid Id got from database by last insert")
user.setFirstName("New first name");
// Remaining fields are null now
userRepo.save(user);
这里的 null 值将由 MongoRepository 插入。
我可以通过什么设置告诉 MongoRepository 在更新时避免空值?
如果我们通过MongoTemplate updateFirst()
方法执行此操作,我们必须为 POJO 的所有字段添加if
条件。在这种情况下,最好的解决方案是什么?
【问题讨论】:
这能回答你的问题吗? Spring Data MongoDB - ignore empty objects 【参考方案1】:尝试先从数据库中获取用户,然后更新您的数据并保存在数据库中。
UserModel user = userRepo.findById(id); // Fetch from database
user.setFirstName("New first name"); // Update the data
userRepo.save(user); // Save in the database
或使用自定义查询仅更新选定的字段。这里要使其动态化,从UserModel
创建一个Map<String, Object>
并删除空值。
ObjectMapper oMapper = new ObjectMapper();
Map<String, Object> dataMap = oMapper.convertValue(user, Map.class);
map.values().removeIf(Objects::isNull);
现在在Update
中设置地图,然后在数据库中更新。
Update update = new Update();
dataMap.forEach(update::set);
Query query = new Query().addCriteria(where("_id").is(id));
mongoTemplate.update(UserModel.class).matching(query).apply(update).first();
【讨论】:
这需要一个额外的查询。我们的目标是通过一个更新查询和更少的代码来完成。 你使用了 Jackson ObjectMapper。正确的?好吧,以某种方式制作 JSON 是个好主意。让我们看看有没有其他好的方法来做到这一点。 @iamcrypticcoder 是的。如果您更新的节点是动态的,那么我认为这是一个好方法。或者,如果它们已修复,那么只需添加Update
是一个好方法。
@Eklvya 我对此 JSON 转换的意见。基本上我心里有这个。这种转换不需要时间吗?此外,与 GSON 相比,Jackson 不能很好地处理小负载。我的意思是杰克逊需要的时间。
@iamcrypticcoder 取决于您是否使用单例(创建一个 bean),那么它不会花费太多时间。如果您手动创建 Map以上是关于Spring Mongo 仅通过新 POJO 的非空字段进行更新的主要内容,如果未能解决你的问题,请参考以下文章
无法从 Spring Boot REST 中的 Hibernate POJO 返回 JSON
Spring Boot 连接到运行的 mongo 容器的 MongoDB 副本集
如何在 Spring Boot 中将 mongo db update 运算符应用为 $inc