先看看BaseRepository:
@NoRepositoryBean
public interface BaseRepository<DOMAIN, ID> extends JpaRepository<DOMAIN, ID> {
@NonNull
List<DOMAIN> findAllByIdIn(@NonNull Collection<ID> ids, @NonNull Sort sort);
@NonNull
Page<DOMAIN> findAllByIdIn(@NonNull Collection<ID> ids, @NonNull Pageable pageable);
long deleteByIdIn(@NonNull Collection<ID> ids);
}
关于findAllByIdIn
方法的具体实现:
if (entityInformation.hasCompositeId()) {
List<DOMAIN> results = new ArrayList<>();
ids.forEach(id -> super.findById(id).ifPresent(results::add));
return results;
}
ByIdsSpecification<DOMAIN> specification = new ByIdsSpecification<>(entityInformation);
TypedQuery<DOMAIN> query = super.getQuery(specification, sort);
return query.setParameter(specification.parameter, ids).getResultList();
如上代码所示,为何有复合主键时可以直接一个一个findById
? 然后没有复合主键时,下面的代码又是什么意思?
你可以看看底层SQL日志。复合ID和普通ID的SQL有什么不同。
我猜测一下:
如果是复合ID,就遍历ID参数。挨个的 findById
检索。
如果不是复合ID的话,就直接用 WHERE ID IN (..)
这种方式来检索,省事儿。不用遍历。
1 Like
前辈,就是自己实现基类的时候,这几个类还没有完全搞懂。您能简单的给我讲一下他们的作用嘛?
1、Root
2、CriteriaQuery
3、CriteriaBuilder
4、Path
5、ParameterExpression
6、JpaEntityInformation
比如说下面这段代码:
private static final class ByIdsSpecification<T> implements Specification<T> {
private static final long serialVersionUID = 1L;
private final JpaEntityInformation<T, ?> entityInformation;
@Nullable
ParameterExpression<Collection> parameter;
ByIdsSpecification(JpaEntityInformation<T, ?> entityInformation) {
this.entityInformation = entityInformation;
}
@Override
public Predicate toPredicate(Root<T> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
Path<?> path = root.get(this.entityInformation.getIdAttribute());
this.parameter = cb.parameter(Collection.class);
return path.in(this.parameter);
}
}
Criteria 查询,我也不是很熟。没办法给你讲清楚。我实际上开发,都是用
JPA + QueryDSL
这套组合。一般复杂点儿的查询,我都是用QueryDSL而不用Criteria 。