2017-06-06 77 views
2

查找我在我的spring项目中有一个通常的Spring Data JPA存储库。Spring数据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要求?如果是的话,我可以举个例子吗?

+0

你有没有尝试过'findByOriginalIdInOrOriginalIdInOrOriginalIdIn(...)'?但说实话,我认为crietria api会更简单和直接使用 – Antoniossss

+0

检查出[this](https://stackoverflow.com/questions/43780226/spring-data-ignore-parameter-if-it- has-a-null-value/43781418#43781418)的问题 –

回答

1

不创建自定义的库,我建议使用Spring数据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。

0

尝试使用标准具有以下限制:

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

我建议在Spring JPA中使用QueryDSL来简化你的实现。

使用QueryDSL,您可以轻松构建谓词(除标准外),并在查询中使用它。在你的情况下,它可能会像下面这样。请参考链接:Spring Data JPA Tutorial: Creating Database Queries With Querydsl关于如何使用Spring Data JPA的QueryDSL。

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

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使得它很容易实现不同的标准(从简单到复杂)。请参阅上面的链接了解如何使用它。

希望这会有所帮助。