我可以通过 ID 列表而不是 Spring Data JPA 中的经典 findById() 找到吗?
Can I find by a list of IDs instead the classic findById() in Spring Data JPA?
我正在使用 Spring Data JPA 开发一个 Spring 引导项目,我想知道是否存在针对以下用例的漂亮而优雅的解决方案。
原来我有这样的服务方式(效果很好):
@Override
public Page<LogDTO> findAll(Integer logType, LocalDateTime startDate, LocalDateTime endDate, Pageable pageable) throws NotFoundException {
if(startDate == null) startDate = LocalDateTime.of(1900,1,1,0,0,0);
if(endDate == null) endDate = LocalDateTime.now();
Page<EventLog> eventLogs = null;
if(logType != null) {
Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
logTypeEntity.orElseThrow( () -> new NotFoundException(String.format("Log type doesn't exists with id: ", Integer.toString(logType))));
eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
} else {
eventLogs = logRepository.findByTimestampBetween(startDate,endDate,pageable);
}
return eventLogs.map(m -> conversionService.convert(m, LogDTO.class));
}
正如您在这个旧方法中看到的那样,采用这个 Integer logType 输入参数表示单个日志类型的 ID。然后通过以下方式检索相关的 LogType 对象:
Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
并使用此 logTypeEntity 实例来检索与此特定单个检索 LogType 相关的所有 EventLog 对象,通过这一行:
eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
现在我正在重构这个方法,以尝试获取与多个 LogType 相关的日志。所以我把原来的服务方式改成这样:
@Override
public Page<LogDTO> findAll(List<Integer> logTypesList,
LocalDateTime startDate,
LocalDateTime endDate,
Pageable pageable) throws NotFoundException {
if(startDate == null) startDate = LocalDateTime.of(1900,1,1,0,0,0);
if(endDate == null) endDate = LocalDateTime.now();
Page<EventLog> eventLogs = null;
if(logTypesList != null & logTypesList.size() > 0) {
Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
logTypeEntity.orElseThrow( () -> new NotFoundException(String.format("Log type doesn't exists with id: ", Integer.toString(logType))));
eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
} else {
eventLogs = logRepository.findByTimestampBetween(startDate,endDate,pageable);
}
return eventLogs.map(m -> conversionService.convert(m, LogDTO.class));
}
如您所见,我的服务方法现在采用 List logTypesList 参数而不是单个 Integer logType)。然后在我的代码中我检查这个列表是否包含元素。
现在我想知道 Spring Data JPA 中是否存在替换此行的智能方法:
Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
为了检索属于我的 List logTypesList 中包含的所有 ID 的 LogType 的集合。我知道我可以简单地对该集合进行交互并将检索到的对象添加到结果列表中,但我想知道我是否可以以更智能的方式实现此行为。
关于如何以巧妙而优雅的方式替换这一行的类似疑问:
eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
是否存在传递 LogType 对象集合以检索所有返回的 LogEvent 对象的方法?
请看session.byMultipleIds multiLoad
https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/Session.html
它将是这样的:
List<LogType> logTypes = session.byMultipleIds( LogType.class ).multiLoad( 1L, 2L, 3L );
这个 (findAllById) 应该可以工作
List<T> findAllById(Iterable<ID> var1);
我正在使用 Spring Data JPA 开发一个 Spring 引导项目,我想知道是否存在针对以下用例的漂亮而优雅的解决方案。
原来我有这样的服务方式(效果很好):
@Override
public Page<LogDTO> findAll(Integer logType, LocalDateTime startDate, LocalDateTime endDate, Pageable pageable) throws NotFoundException {
if(startDate == null) startDate = LocalDateTime.of(1900,1,1,0,0,0);
if(endDate == null) endDate = LocalDateTime.now();
Page<EventLog> eventLogs = null;
if(logType != null) {
Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
logTypeEntity.orElseThrow( () -> new NotFoundException(String.format("Log type doesn't exists with id: ", Integer.toString(logType))));
eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
} else {
eventLogs = logRepository.findByTimestampBetween(startDate,endDate,pageable);
}
return eventLogs.map(m -> conversionService.convert(m, LogDTO.class));
}
正如您在这个旧方法中看到的那样,采用这个 Integer logType 输入参数表示单个日志类型的 ID。然后通过以下方式检索相关的 LogType 对象:
Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
并使用此 logTypeEntity 实例来检索与此特定单个检索 LogType 相关的所有 EventLog 对象,通过这一行:
eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
现在我正在重构这个方法,以尝试获取与多个 LogType 相关的日志。所以我把原来的服务方式改成这样:
@Override
public Page<LogDTO> findAll(List<Integer> logTypesList,
LocalDateTime startDate,
LocalDateTime endDate,
Pageable pageable) throws NotFoundException {
if(startDate == null) startDate = LocalDateTime.of(1900,1,1,0,0,0);
if(endDate == null) endDate = LocalDateTime.now();
Page<EventLog> eventLogs = null;
if(logTypesList != null & logTypesList.size() > 0) {
Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
logTypeEntity.orElseThrow( () -> new NotFoundException(String.format("Log type doesn't exists with id: ", Integer.toString(logType))));
eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
} else {
eventLogs = logRepository.findByTimestampBetween(startDate,endDate,pageable);
}
return eventLogs.map(m -> conversionService.convert(m, LogDTO.class));
}
如您所见,我的服务方法现在采用 List logTypesList 参数而不是单个 Integer logType)。然后在我的代码中我检查这个列表是否包含元素。
现在我想知道 Spring Data JPA 中是否存在替换此行的智能方法:
Optional<LogType> logTypeEntity = logTypeRepository.findById(logType);
为了检索属于我的 List logTypesList 中包含的所有 ID 的 LogType 的集合。我知道我可以简单地对该集合进行交互并将检索到的对象添加到结果列表中,但我想知道我是否可以以更智能的方式实现此行为。
关于如何以巧妙而优雅的方式替换这一行的类似疑问:
eventLogs = logRepository.findByLogTypeAndTimestampBetween(logTypeEntity.get(),startDate,endDate, pageable);
是否存在传递 LogType 对象集合以检索所有返回的 LogEvent 对象的方法?
请看session.byMultipleIds multiLoad
https://docs.jboss.org/hibernate/orm/5.2/javadocs/org/hibernate/Session.html
它将是这样的:
List<LogType> logTypes = session.byMultipleIds( LogType.class ).multiLoad( 1L, 2L, 3L );
这个 (findAllById) 应该可以工作
List<T> findAllById(Iterable<ID> var1);