use*_*654 27 spring specifications criteria-api spring-data-jpa
我有一个非常复杂的模型.实体有很多关系,等等.
我尝试使用Spring Data JPA并准备了一个存储库.
但是当我调用metod findAll()时,对象a的规范有一个性能问题,因为对象非常大.我知道,因为当我调用这样的方法时:
@Query(value = "select id, name from Customer ")
List<Object[]> myFindCustomerIds();
Run Code Online (Sandbox Code Playgroud)
我的表现没有任何问题.
但是当我调用时
List<Customer> findAll();
Run Code Online (Sandbox Code Playgroud)
我的表现存在很大问题.
问题是我需要使用Specifications for Customer调用findAll方法,这就是为什么我不能使用返回对象数组列表的方法.
如何编写方法来查找具有Customer实体规范但仅返回ID的所有客户.
像这样:
List<Long> findAll(Specification<Customer> spec);
Run Code Online (Sandbox Code Playgroud)
请帮忙.
eav*_*eav 30
为什么不使用@Query注释?
id
我看到的唯一缺点是当属性@Query发生变化时,但由于这是一个非常常见的名称而且不太可能改变(id =主键),这应该没问题.
Ond*_*zek 18
Spring Data使用Projections现在支持这一点:
interface SparseCustomer {
String getId();
String getName();
}
Run Code Online (Sandbox Code Playgroud)
比在您的Customer存储库中
List<SparseCustomer> findAll(Specification<Customer> spec);
Run Code Online (Sandbox Code Playgroud)
编辑:
正如Radouane ROUFID预测的那样,规格目前不适用于bug.
但是你可以使用规范与投影库来解决这个Spring Data Jpa缺陷.
我解决了这个问题.
(因此我们将只有一个带有id和名称的稀疏Customer对象)
public interface SparseCustomerRepository {
List<Customer> findAllWithNameOnly(Specification<Customer> spec);
}
Run Code Online (Sandbox Code Playgroud)
@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;
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
51808 次 |
| 最近记录: |