如何在Criteria JPA API中实例化含7个以上参数的Wrapper类
可行解决方案
方案1:字段分组封装值对象(最推荐,从结构层面解决多参数问题)
将业务属性关联的字段封装为独立的值对象,可大幅降低构造方法的入参数量,同时优化代码结构可读性,改造示例如下:
- 定义分组值对象
// 姓名相关属性封装 public class UserName { private String name; private String firstname; private String lastname; // 构造方法、Getter 省略 } // 访问时间属性封装 public class VisitRecord { private Date lastvisited; private Date lastModified; private Date firstvisited; // 构造方法、Getter 省略 } // 项目相关属性封装 public class ProjectInfo { private int numberofholidays; private String currentproject; private String lastproject; // 构造方法、Getter 省略 }
- 改造Wrapper类
public class MyWrapper{ private String id; private UserName userName; private VisitRecord visitRecord; private ProjectInfo projectInfo; public MyWrapper(String id, UserName userName, VisitRecord visitRecord, ProjectInfo projectInfo) { this.id = id; this.userName = userName; this.visitRecord = visitRecord; this.projectInfo = projectInfo; // 注意:@PostConstruct仅对Spring管理的Bean生效,自定义构造的对象需要手动调用逻辑方法 doSomelogic(); } public void doSomelogic(){ // 原有自定义逻辑保持不变,通过值对象的Getter取值即可 } // 业务所需Getter 省略 }
- 调整Criteria查询写法
// 构造各值对象的查询映射 Selection<UserName> userNameSel = criteriaBuilder.construct(UserName.class, root.get("name"), root.get("firstname"), root.get("lastname") ); Selection<VisitRecord> visitSel = criteriaBuilder.construct(VisitRecord.class, root.get("lastvisited"), root.get("lastModified"), root.get("firstvisited") ); Selection<ProjectInfo> projectSel = criteriaBuilder.construct(ProjectInfo.class, root.get("numberofholidays"), root.get("currentproject"), root.get("lastproject") ); // 最终构造Wrapper仅需4个入参 criteriaBuilder.construct(MyWrapper.class, root.get("id"), userNameSel, visitSel, projectSel);
方案2:Lombok注解简化代码(适合不想改动现有结构的场景)
如果不需要调整结构,仅想避免手动编写冗长的多参数构造方法,可使用Lombok的@AllArgsConstructor注解自动生成构造方法,代码示例:
import lombok.AllArgsConstructor; @AllArgsConstructor public class MyWrapper{ // 所有字段定义保持不变 private String id; private String name; private String firstname; private String lastname; private Date lastvisited; private Date lastModified; private Date firstvisited; private int numberofholidays; private String currentproject; private String lastproject; // 其他字段省略 // 不需要手动编写10+参数的构造方法,Lombok自动生成 public void doSomelogic(){ // 原有逻辑保持不变 } }
原有Criteria查询的写法不需要做任何改动。
方案3:Tuple映射优化
你之前担心的Tuple循环实例化性能问题,在JDK 8+环境下基本可以忽略:JVM对小对象的创建和Yong GC已经做了深度优化,单次对象创建耗时仅为几纳秒,除非是单次查询返回十万级以上的超大结果集,否则性能损耗远低于维护多参数构造方法的人力成本。
如果确定要使用Tuple方案,可配合Hibernate的TupleTransformer实现自动映射,不需要手动逐个赋值,也能避免长构造方法的问题。
内容的提问来源于stack exchange,提问作者harsha kumar Reddy
相关产品推荐
相关产品推荐

