【问题标题】:Update Query with annotation using Spring and MongoRepository使用 Spring 和 MongoRepository 使用注释更新查询
【发布时间】:2017-05-05 18:19:55
【问题描述】:

我正在使用最新版本的 Spring Boot 和 Spring Data MongoRepository。我写了一个自定义的存储库接口

    public interface CompanyRepository extends MongoRepository<Company, String>{

    @Query(value = "{ 'employer.userId' : ?0 }")
    Company findByCompanyUserUserId(String userId);
}

以同样的方式,我想使用 @Query 注释来更新特定字段。有人可以推荐我吗?

【问题讨论】:

  • 使用 MongoTemplate 进行更新操作。查询用于查询。
  • 是的 Sagar,我已经在使用 MongoTemplate,但我想使用注解来减少编写大量代码,有更好的解决方案吗?
  • 就像我说的查询意味着只读操作。没有更新,也不可能。
  • spring data mongo中没有@update实现。

标签: mongodb spring-boot spring-data-mongodb spring-repositories


【解决方案1】:

像这样创建注释:

@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.METHOD})
public @interface MongoUpdate {

String find() default "{}";

String update() default "{}";

String collection();

boolean multi() default false;
}

还有这样的一个方面:

@Aspect
@Component
@SuppressWarnings("unchecked")
public class MongoUpdateAspect {

private static final Logger logger = LoggerFactory.getLogger(MongoUpdateAspect.class);

@Autowired
private MongoTemplate mongoTemplate;

@Pointcut("@annotation(com.ofb.commons.aop.common.MongoUpdate)")
public void pointCut() {
}

@Around("com.ofb.commons.aspect.MongoUpdateAspect.pointCut() && @annotation(mongoUpdate)")
public Object applyQueryUpdate(ProceedingJoinPoint joinPoint, MongoUpdate mongoUpdate) throws Throwable {
    Object[] args = joinPoint.getArgs();

    String findQuery = mongoUpdate.find();
    String updateQuery = mongoUpdate.update();
    String collection = mongoUpdate.collection();
    boolean multiUpdate = mongoUpdate.multi();

    for (int i = 0; i < args.length; i++) {
        if (args[i] instanceof Collection) {
            Collection collection1 = (Collection) args[i];
            String replaceStr = (String) collection1.stream().map(object -> {
                if (object instanceof Number) {
                    return object.toString();
                } else {
                    return String.format("\"%s\"", object.toString());
                }
            }).collect(Collectors.joining(","));
            findQuery = findQuery.replace(String.format("?%s", i), replaceStr);
            updateQuery = updateQuery.replace(String.format("?%s", i), replaceStr);
        } else if (args[i] instanceof Object[]) {
            Object[] objects = (Object[]) args[i];
            String replaceStr = Arrays.stream(objects).map(object -> {
                if (object instanceof Number) {
                    return object.toString();
                } else {
                    return String.format("\"%s\"", object.toString());
                }
            }).collect(Collectors.joining(","));
            findQuery = findQuery.replace(String.format("?%s", i), replaceStr);
            updateQuery = updateQuery.replace(String.format("?%s", i), replaceStr);
        } else {
            if (args[i] instanceof Number) {
                findQuery = findQuery.replace(String.format("?%s", i), args[i].toString());
                updateQuery.replace(String.format("?%s", i), args[i].toString());
            } else {
                findQuery = findQuery.replace(String.format("?%s", i), String.format("\"%s\"", args[i].toString()));
                updateQuery =
                    updateQuery.replace(String.format("?%s", i), String.format("\"%s\"", args[i].toString()));
            }
        }
    }

    Query query = new BasicQuery(findQuery);
    Update update = new BasicUpdate(updateQuery);

    if (multiUpdate) {
        mongoTemplate.updateMulti(query, update, collection);
    } else {
        mongoTemplate.updateFirst(query, update, collection);
    }
    return null;
   }
}

这在 MongoRepository 实现的接口中不起作用,但您可以在服务层中创建一个空的主体方法

@MongoUpdate(find = {}, update = "{$push : {'offFeatures' : ?0}}", collection = "userPreference", multi = true)
public void offFeatures(String feature) {

}

【讨论】:

  • 这是抽象出底层复杂实现并向用户呈现易于使用的用户界面的一个很好的例子。如果这被 Spring Data 采用,那就太好了。
【解决方案2】:

这是一个合理的问题。假设你正在使用 org.springframework.data.mongodb.repository.MongoRepository 类,你能不能简单地使用 insert(..) 或 save(..) 方法来满足你的需要?

API docs

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-09-04
    • 2011-04-08
    • 2018-10-05
    • 2018-07-13
    • 2013-07-20
    • 2016-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多