4

我有一个存储库

public interface PersonRepository extends JpaRepository<Person, Long> {}

实体看起来像这样:

@Data
@Entity
@NoArgsConstructor
@AllArgsConstructor
public class Person {
    @Id
    private Long id;
    @NotBlank
    private String name;
}

我想要一个方法来检查数据库表中是否存在所有“人员”,这是我目前所拥有的:

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 Repository 是否可以提供更优雅的东西?像返回不存在的 id 的特定命名查询一样?

4

3 回答 3

2

如果您只想知道有些 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);
}
于 2019-11-22T09:09:20.730 回答
1

首先,您的存储库应该扩展JpaRepository<Person, Long>而不是JpaRepository<Person, String >,因为您的实体的 id 类型是Long.

In关键字NotIn可以帮助您实现目标。请在本文档中查看它们:查询创建 - Spring Data 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

我希望这能帮到您。

于 2019-11-22T12:31:06.737 回答
0

使用此 JPA 存储库方法,您可以获得 id 不存在的元素:

List<Person> findByIdNotIn(List<Long> personIds);

如果你想像你的例子中那样删除它们,你可以使用这个:

List<Person> deleteByIdNotIn(List<Long> personIds);

我希望它有帮助!

于 2019-11-22T08:20:34.250 回答