Spring 数据 JPA。查找方式

Spring data JPA. Find by in

我的 spring 项目中有一个常用的 Spring Data JPA 存储库。

@Repository
public interface EventRepository extends CrudRepository<Event, Long> {
  List<Event> findByOriginalIdIn(Collection<String> originalEventIds);
  ...

我以前用过方法findByOriginalIdIn,效果很好。但是情况发生了变化,我需要使用成对集合来查找和过滤正确的事件来处理相同的请求。

我的替代方法应该处理下一个逻辑: find by (originalId1 AND originalCalendarId1) OR (originalId2 AND originalCalendarId2) OR (originalId..N AND originalCalendarId..N) OR

是否可以使用 Selectively exposing CRUD methods 处理此请求?如果是,请给我一个例子好吗?

尝试使用具有以下限制的条件:

Criteria criteria = session.createCriteria(Event.class)
                    .add(Restrictions.in("id", values));

为了不创建自定义存储库,我建议使用 Spring Data JPA 规范。 这是一个草稿示例。

       class Specification1 implements Specification<Event> {            
            private final List<Pair<String, String>> pairs;

            public Specification1(List<Pair<String, String>> pairs) {
                this.paris = pairs;
            }

            @Override
            public Predicate toPredicate(Root<Event> root, CriteriaQuery<?> query, CriteriaBuilder cb) {


                Predicate[] as = pairs.stream().map(pair -> {
                    return cb.and(cb.equal(root.get("originalId2"), pair.getKey())),cb.equal(root.get("originalCalendarId2"), pair.getKey());
                }).toArray(Predicate[]::new);

                return cb.or(as);
            }
        }


        userRepository.findAll(new Specification1(...));

此外,您的存储库必须扩展 JpaSpecificationExecutor。

我建议将 QueryDSL 与 Spring JPA 结合使用,以简化您的实施。

使用 QueryDSL,您可以轻松构建谓词(仅是条件)并在查询中使用它。在您的情况下,它可能类似于以下内容。请参阅 link: Spring Data JPA Tutorial: Creating Database Queries With Querydsl 了解如何将 QueryDSL 与 Spring Data JPA 一起使用。

在你的情况下,对于给定的条件,

find by (originalId1 AND originalCalendarId1) OR (originalId2 AND originalCalendarId2) OR (originalId..N AND originalCalendarId..N) OR

我不明白,例如originalId1/originalCalendarId1 应该等于任何值。比方说,为了简单和解释,它们应该等于某个值。

import com.mysema.query.BooleanBuilder;
import com.mysema.query.types.Predicate;

public class EventPredicates {

    public static Predicate getAllEventsByOrginalIds(String[] originalIds, String[] originalCalendarIds) {
        QEvent event = QEventEntity.event;

        BooleanBuilder builder = new BooleanBuilder();

        //assuming both arrays are of same size.
        for (int idx = 0; idx < originalIds.length; idx++) {
            builder.or(event.originalIds[0].eq.(someValue)).and(event.originalCalendarIds[0].eq.(someCalValue));
        }
        return builder;
    }
}

但是,您的存储库接口应该扩展 QueryDslPredicateExecutor<Event> 以使用 QueryDSL 功能。

在您的服务方法中,假设 EventRepository 声明如下:您可以进行如下调用:

@Autowired
EventRepository eventRepository;

public void someMethod(){

    ...
    List<Events> events = eventRepository.findAll(EventPredicates.getAllEventsByOrginalIds(originalIdsArr, originalCalendarIdsArr));
    ...

}

顺便说一句,QueryDSL 使得实现不同的标准(从简单到复杂)变得非常容易。使用方法参考上面link

希望对您有所帮助。