如何通过现有JPA Specification加载Blaze-Persistence Entity View
实现方案
前提依赖
你需要先注入Blaze-Persistence提供的两个核心实例:
CriteriaBuilderFactory:用于构建兼容JPA规范的增强查询EntityViewManager:用于处理Entity View与实体的映射、查询自动优化
具体实现代码
你可以直接复用已有的JPA Specification,不需要修改原有逻辑,示例代码如下(支持传入任意对应实体的Entity View类作为参数):
import com.blazebit.persistence.CriteriaBuilder; import com.blazebit.persistence.CriteriaBuilderFactory; import com.blazebit.persistence.view.EntityViewManager; import com.blazebit.persistence.view.EntityViewSetting; import org.springframework.data.jpa.domain.Specification; import javax.persistence.EntityManager; import java.util.List; // 泛型方法,T为Entity View类型,E为实体类型 public <T, E> List<T> listBySpecAndView(Specification<E> spec, Class<E> entityClass, Class<T> viewClass) { // 1. 构造Blaze增强CriteriaBuilder CriteriaBuilder<E> cb = criteriaBuilderFactory.create(entityManager, entityClass); // 2. 复用已有Specification生成Where条件,完全兼容原生JPA接口 javax.persistence.criteria.CriteriaQuery<E> jpaQuery = cb.getCriteriaQuery(); javax.persistence.criteria.Root<E> root = cb.getRoot(); javax.persistence.criteria.Predicate predicate = spec.toPredicate(root, jpaQuery, cb.getCriteriaBuilder()); cb.where(predicate); // 3. 绑定Entity View直接生成结果,无需Entity Graph、无需手动转投影 return entityViewManager.applySetting( EntityViewSetting.create(viewClass), cb ).getResultList(); }
实现说明
- 原有
Specification的逻辑可以100%复用,Blaze-Persistence的查询相关接口完全兼容原生JPA的CriteriaBuilder、Root、Predicate等定义 - 自动替代原有
Entity Graph的作用:Entity View会根据自身定义的字段自动生成最优的fetch策略,避免N+1查询问题 - 自动替代手动投影转换:查询直接返回Entity View实例,不需要先查完整实体再做DTO转换,仅会查询Entity View定义的必要字段,性能更优
可选优化(Spring环境)
如果你集成了Spring Data Blaze Persistence扩展,不需要手动编写上述工具方法,直接在Repository层继承对应接口即可直接使用:
import org.springframework.data.jpa.repository.JpaRepository; import com.blazebit.persistence.spring.data.repository.EntityViewSpecificationExecutor; // 三个泛型依次为:实体类型、Entity View类型、主键类型 public interface YourEntityRepository extends JpaRepository<YourEntity, Long>, EntityViewSpecificationExecutor<YourEntityView, Long> { } // 调用时直接传入spec和目标View类即可 List<YourEntityView> result = yourEntityRepository.findAll(spec, EntityViewSetting.create(YourEntityView.class));
内容的提问来源于stack exchange,提问作者user2630579
相关产品推荐
相关产品推荐

