弹簧数据 JPA.如何仅从 findAll() 方法中获取 ID 列表 [英] Spring Data JPA. How to get only a list of IDs from findAll() method
问题描述
我有一个非常复杂的模型.实体有很多关系等等.
I have a very complicated model. Entity has a lot relationship and so on.
我尝试使用 Spring Data JPA 并准备了一个存储库.
I try to use Spring Data JPA and I prepared a repository.
但是当我调用带有对象规范的方法 findAll() 时,会出现性能问题,因为对象非常大.我知道这是因为当我调用这样的方法时:
but when I invoke a method findAll() with specification for the object a have a performance issue because objects are very big. I know that because when I invoke a method like this:
@Query(value = "select id, name from Customer ")
List<Object[]> myFindCustomerIds();
我没有任何性能问题.
但是当我调用
List<Customer> findAll();
我在性能方面遇到了很大的问题.
I had a big problem with performance.
问题是我需要调用带有客户规范的 findAll 方法,这就是为什么我不能使用返回对象数组列表的方法.
The problem is that I need to invoke findAll method with Specifications for Customer that is why I cannot use method which returns a list of arrays of objects.
如何编写一种方法来查找具有 Customer 实体规范但仅返回 ID 的所有客户.
How to write a method to finding all customers with specifications for Customer entity but which returns only an IDs.
像这样:
List<Long> findAll(Specification<Customer> spec);
- 在这种情况下我不能使用分页.
请帮忙.
推荐答案
我解决了这个问题.
(因此我们将有一个只有 id 和 name 的稀疏 Customer 对象)
(As a result we will have a sparse Customer object only with id and name)
public interface SparseCustomerRepository {
List<Customer> findAllWithNameOnly(Specification<Customer> spec);
}
还有一个实现(记住后缀 - Impl 作为默认)
@Service
public class SparseCustomerRepositoryImpl implements SparseCustomerRepository {
private final EntityManager entityManager;
@Autowired
public SparseCustomerRepositoryImpl(EntityManager entityManager) {
this.entityManager = entityManager;
}
@Override
public List<Customer> findAllWithNameOnly(Specification<Customer> spec) {
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<Tuple> tupleQuery = criteriaBuilder.createTupleQuery();
Root<Customer> root = tupleQuery.from(Customer.class);
tupleQuery.multiselect(getSelection(root, Customer_.id),
getSelection(root, Customer_.name));
if (spec != null) {
tupleQuery.where(spec.toPredicate(root, tupleQuery, criteriaBuilder));
}
List<Tuple> CustomerNames = entityManager.createQuery(tupleQuery).getResultList();
return createEntitiesFromTuples(CustomerNames);
}
private Selection<?> getSelection(Root<Customer> root,
SingularAttribute<Customer, ?> attribute) {
return root.get(attribute).alias(attribute.getName());
}
private List<Customer> createEntitiesFromTuples(List<Tuple> CustomerNames) {
List<Customer> customers = new ArrayList<>();
for (Tuple customer : CustomerNames) {
Customer c = new Customer();
c.setId(customer.get(Customer_.id.getName(), Long.class));
c.setName(customer.get(Customer_.name.getName(), String.class));
c.add(customer);
}
return customers;
}
}
这篇关于弹簧数据 JPA.如何仅从 findAll() 方法中获取 ID 列表的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!