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);
}
相关推荐
Jonathan Star1 分钟前
MediaPipe 在Python中实现人体运动识别,最常用且高效的方案是结合**姿态估计**(提取人体关键点)和**动作分类**(识别具体运动)
开发语言·python·分类
滨HI014 分钟前
C++ opencv拟合直线
开发语言·c++·opencv
沐浴露z24 分钟前
详解JDK21新特性【虚拟线程】
java·开发语言·jvm
艾莉丝努力练剑36 分钟前
【C++:红黑树】深入理解红黑树的平衡之道:从原理、变色、旋转到完整实现代码
大数据·开发语言·c++·人工智能·红黑树
No0d1es44 分钟前
电子学会青少年软件编程(C/C++)1级等级考试真题试卷(2025年9月)
java·c语言·c++·青少年编程·电子学会·真题·一级
l1t1 小时前
利用DeepSeek优化SQLite求解数独SQL用于DuckDB
开发语言·数据库·sql·sqlite·duckdb
_OP_CHEN1 小时前
C++进阶:(七)红黑树深度解析与 C++ 实现
开发语言·数据结构·c++·stl·红黑树·红黑树的旋转·红黑树的平衡调整
9号达人1 小时前
普通公司对账系统的现实困境与解决方案
java·后端·面试
硅农深芯1 小时前
如何使用ptqt5实现进度条的动态显示
开发语言·python·qt
超级苦力怕1 小时前
Java 为何 long a = 999999999 能过;long a = 9999999999 报错?一文讲透“宽化转换”
java