我有一个存储库
public interface PersonRepository extends JpaRepository<Person, Long> {}
实体如下所示:
@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Person {
@Id
private Long id;
@NotBlank
private String name;
}
我想要一种方法来按id检查数据库表中是否存在所有"人员",这是我到目前为止所拥有的:
void checkIfAllPersonsExist(List<Long> personIds) {
var persons = personRepository.findAllById(personIds);
if (personIds.size() != persons.size()) {
personIds.removeAll(persons.stream().map(Persons::getId).collect(toList()));
throw new NotFoundException("Persons with id's [id:%s] does not exist", personIds);
}
}
我想知道Spring JPA存储库是否可以提供更优雅的东西?就像返回不存在的 id 的特定命名查询一样?
如果你只想知道有一些 id 不存在,你可以计算它们
@Query("select COUNT(p.id) from Person p where p.id in :ids")
Long countIds(List<Long> ids);
或基于以下条件的等效项
long countByIdIn(Collection<Long> ids);
或返回存在的 id 列表
@Query("select p.id from Person p where p.id in :ids")
List<Long> getExistenIds(List<Long> ids);
然后过滤掉您需要的内容。
personIds.removeAll(personRepository.getExistenIds(personIds));
if (!personIds.isEmpty()) {
throw new NotFoundException("Persons with id's [id:%s] does not exist", personIds);
}
首先,您的存储库应该扩展JpaRepository<Person, Long>
而不是JpaRepository<Person, String >
,因为您的实体的 id 类型是Long
。
In
和NotIn
关键字可以帮助您实现目标。请在此文档中查看它们: 查询创建 - Spring 数据 JPA - 参考文档
我稍微修改了一下您的代码,它对我有用。
存储库类:
public interface PersonRepository extends JpaRepository<Person, Long> {
List<Person> findByIdIn(Collection<Long> ids);
}
和示例片段:
@Component
public class Bootstrap implements CommandLineRunner {
@Autowired
private PersonRepository repository;
@Override
public void run(String... args) throws Exception {
savePersons();
testFindMethod();
}
private void savePersons() {
Person person1 = Person.builder().id(1L).name("Name 1").build();
Person person2 = Person.builder().id(2L).name("Name 2").build();
Person person3 = Person.builder().id(3L).name("Name 3").build();
Person person4 = Person.builder().id(4L).name("Name 4").build();
repository.save(person1);
repository.save(person2);
repository.save(person3);
repository.save(person4);
}
private void testFindMethod() {
List<Long> toFind = new ArrayList<>();
toFind.add(1L);
toFind.add(2L);
toFind.add(3L);
checkIfAllPersonsExist(toFind);
toFind.add(7L);
checkIfAllPersonsExist(toFind);
}
void checkIfAllPersonsExist(List<Long> personIds) {
List<Person> persons = repository.findByIdIn(personIds);
if (personIds.size() != persons.size()) {
System.out.println("Sizes are different");
} else {
System.out.println("Sizes are same!");
}
}
}
这是控制台输出:
Sizes are same!
Sizes are different
我希望这对你有帮助。
使用此 JPA 存储库方法,您可以获取 ids 不存在的元素:
List<Person> findByIdNotIn(List<Long> personIds);
如果要像示例中一样删除它们,可以使用以下方法:
List<Person> deleteByIdNotIn(List<Long> personIds);
我希望它有所帮助!