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
希望对您有所帮助。
我的 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
希望对您有所帮助。