JPA查询部分字段的最佳实践

最近在接手一个项目,用的是JPA,以前没使用过。在开发新的需求过程中,发现有查询部分字段的情况,网上逛了半天,发现都是抄来抄去的"古文"。于是用英文搜索了下,总结了以下几点。

版本信息:Spring Boot 2.3.7

  1. 不需要新建Entity,但是需要一个所有部分字段的构造函数。当然如果你觉得返回的Entity中包含大量null值字段,以及多一个所有部分字段的构造函数不妥,也可以新建一个子集Entity。

  2. 不使用findAll,而是使用EntityManager来执行CriteriaQuery.multiselect的查询。

  3. 没有用@Query,因为我的查询是动态的。

  4. 也可以支持分页。

示例代码,用模糊查询Merchant的部分字段,并要求分页。

(不过,总觉得这些代码有些冗余,不知道有没有其它更优的写法)

复制代码
public Page<Merchant> listMerchant(String name, Pageable pageable) {
	CriteriaBuilder totalRowsCb = this.entityManager.getCriteriaBuilder();
	CriteriaQuery<Long> totalRowsQuery = totalRowsCb.createQuery(Long.class);
	Root<Merchant> totalRowsRoot = totalRowsQuery.from(Merchant.class);
	totalRowsQuery.where(totalRowsCb.like(totalRowsRoot.get("name"), "%" + name + "%"));
	totalRowsQuery.select(totalRowsCb.count(totalRowsRoot));
	Long totalRows = entityManager.createQuery(totalRowsQuery).getSingleResult();

	CriteriaBuilder listCb = this.entityManager.getCriteriaBuilder();
	CriteriaQuery<Merchant> listQuery = listCb.createQuery(Merchant.class);
	Root<Merchant> listRoot = listQuery.from(Merchant.class);
	List<Order> orderList = QueryUtils.toOrders(pageable.getSort(), listRoot, listCb);

	listQuery .multiselect(
			listRoot.get("mid").alias("mid"),
			listRoot.get("name").alias("name"),
			listRoot.get("businessName").alias("businessName"),
			listRoot.get("contactEmail").alias("contactEmail"),
			listRoot.get("status").alias("status"),
			listRoot.get("accountStatus").alias("accountStatus")
	).where(listCb.like(listRoot.get("name"), "%" + name + "%")).orderBy(orderList);

	List<Merchant> merchantList = entityManager
			.createQuery(listQuery)
			.setMaxResults(pageable.getPageSize())
			.setFirstResult((int)pageable.getOffset())

			.getResultList();

	return new PageImpl<>(merchantList, pageable, totalRows);
}
相关推荐
weixin_440784112 小时前
【HandlerThread实现原理】
android·java·开发语言
天空'之城2 小时前
C 语言工业级通用组件手写 24:互补滤波
c语言·开发语言·互补滤波·嵌入式算法·工业级组件
leoZ2312 小时前
本地跑大模型实战(七):llama.cpp 性能调优,让推理更快更省
java·人工智能·spring·生成对抗网络·语言模型·自然语言处理·llama
XR1234567882 小时前
工厂车间无线网络方案对比:AGV漫游哪家强?
开发语言·php
傻啦嘿哟3 小时前
某短视频平台视频爬虫实战:抓取推荐流视频信息,绕过反爬的3种技巧
开发语言·爬虫·python
現実君4 小时前
【硬件进阶】AD22上位替换JLEDA教程
开发语言·php
mubei-1234 小时前
SpringDAO的用法
java·开发语言·数据库
happymagic4 小时前
java spring boot做的jar包程序,如何实现自动运行启动
java·运维·服务器·spring boot·jar
格林威6 小时前
多相机微秒级对齐:硬件触发 vs PTP(IEEE 1588)方案实战对比
开发语言·人工智能·数码相机·机器学习·计算机视觉·视觉检测·机器视觉
都叫我大帅哥6 小时前
给 Java 程序员的 CSRF 攻击详解:从原理到防御实战
java