Java 11 Criteria API 查询如何仅返回指定字段且不修改 fetch 策略
Criteria API 仅查询指定字段的解决方案
不需要修改实体类原有fetch配置,直接用Criteria API的投影查询功能即可实现只查询你需要的字段,常用的两种实现方式如下:
- 元组(Tuple)查询
显式调用multiselect方法指定需要返回的字段,查询结果将封装为Tuple对象,可通过别名或字段位置取值:
CriteriaBuilder cb = entityManager.getCriteriaBuilder(); // 指定返回类型为Tuple CriteriaQuery<Tuple> query = cb.createTupleQuery(); Root<YourEntity> root = query.from(YourEntity.class); // 仅填写你需要查询的字段,同时指定别名方便后续取值 query.multiselect( root.get("id").alias("id"), root.get("name").alias("name"), root.get("createTime").alias("createTime") ); // 执行查询 List<Tuple> resultList = entityManager.createQuery(query).getResultList(); // 遍历取值 for (Tuple tuple : resultList) { Long id = tuple.get("id", Long.class); String name = tuple.get("name", String.class); // 业务逻辑处理 }
- DTO构造器查询
自定义包含所需字段的DTO类,提供对应全参构造方法后,可直接将查询结果映射为DTO对象,使用起来更符合业务代码习惯:
// 预先定义DTO类 public class YourEntityDTO { private Long id; private String name; private LocalDateTime createTime; // 全参构造方法,参数顺序和类型需要和查询时的字段完全对应 public YourEntityDTO(Long id, String name, LocalDateTime createTime) { this.id = id; this.name = name; this.createTime = createTime; } // 按需添加getter、setter方法 } // Criteria查询逻辑 CriteriaBuilder cb = entityManager.getCriteriaBuilder(); CriteriaQuery<YourEntityDTO> query = cb.createQuery(YourEntityDTO.class); Root<YourEntity> root = query.from(YourEntity.class); // 通过construct方法指定映射的DTO构造器和对应字段 query.select(cb.construct( YourEntityDTO.class, root.get("id"), root.get("name"), root.get("createTime") )); List<YourEntityDTO> resultList = entityManager.createQuery(query).getResultList();
以上两种方案都是在生成SQL阶段就明确指定了查询字段,完全不受实体类原有懒加载、FetchType配置的影响,也不会查询你未显式声明的字段。如果需要避免字符串写字段名的拼写错误,也可以配合JPA静态元模型使用,将
root.get("xxx")替换为root.get(YourEntity_.xxx)即可。
内容的提问来源于stack exchange,提问作者miroana
相关产品推荐
相关产品推荐

