弹簧数据 JPA。在中查找
Posted
技术标签:
【中文标题】弹簧数据 JPA。在中查找【英文标题】:Spring data JPA. Find by in 【发布时间】:2017-11-07 07:02:54 【问题描述】:我的 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 处理此请求?如果是的话,我可以举个例子吗?
【问题讨论】:
你试过findByOriginalIdInOrOriginalIdInOrOriginalIdIn(...)
??但老实说,我认为 crietria api 使用起来会更简单直接
查看this问题
【参考方案1】:
为了不创建自定义存储库,我建议使用 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。
【讨论】:
【参考方案2】:尝试使用具有以下限制的条件:
Criteria criteria = session.createCriteria(Event.class)
.add(Restrictions.in("id", values));
【讨论】:
【参考方案3】:我建议将 QueryDSL 与 Spring JPA 一起使用,以简化您的实现。
使用 QueryDSL,您可以轻松地构造谓词(除了条件)并在查询中使用它。在你的情况下,它可能会像下面这样。请参考链接: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 可以很容易地实现不同的标准(从简单到复杂)。使用方法请参考以上链接。
希望这会有所帮助。
【讨论】:
以上是关于弹簧数据 JPA。在中查找的主要内容,如果未能解决你的问题,请参考以下文章