You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hibernate Criteria查询结果集如何映射到自定义Java类?

解决Hibernate Criteria投影结果映射到Java类的问题

嘿,我来帮你搞定这个问题!你已经走对了第一步——用Projection指定要获取的字段,接下来只需要把查询结果映射到目标Java类(一般是个DTO,也就是数据传输对象)就行,Hibernate提供了现成的工具来做这件事,下面给你两种常用的方案:

方案一:使用AliasToBeanResultTransformer(或Hibernate 5.2+的Transformers.aliasToBean)

这种方法适合你的目标类有无参构造函数+属性setter,或者属性名能和投影字段的别名对应上的情况。

第一步:创建目标DTO类

先写一个和你要获取的字段对应的Java类,比如叫EmployeeDto:

public class EmployeeDto {
    private String name;
    private LocalDate birthDay;

    // 必须要有无参构造函数(如果用setter映射的话)
    public EmployeeDto() {}

    // 也可以写有参构造,不过用AliasToBean的时候主要靠setter映射
    public EmployeeDto(String name, LocalDate birthDay) {
        this.name = name;
        this.birthDay = birthDay;
    }

    // 别忘了写getter和setter
    public String getName() { return name; }
    public void setName(String name) { this.name = name; }
    public LocalDate getBirthDay() { return birthDay; }
    public void setBirthDay(LocalDate birthDay) { this.birthDay = birthDay; }
}

第二步:修改Criteria代码,添加结果转换器

给每个投影字段起别名,别名要和DTO里的属性名完全一致,然后设置结果转换器:

Criteria criteria = session.createCriteria(EmployeeInfo.class);
Criterion condition1 = Restrictions.eq("employeeTO.id", id);
criteria.add(condition1);

// 给每个字段起别名,对应DTO的属性名
ProjectionList projectionList = Projections.projectionList()
        .add(Projections.property("name"), "name")
        .add(Projections.property("birthDay"), "birthDay");

criteria.setProjection(projectionList);

// Hibernate 5.2之前用这个
// criteria.setResultTransformer(new AliasToBeanResultTransformer(EmployeeDto.class));

// Hibernate 5.2及以后推荐用Transformers.aliasToBean,功能一致
criteria.setResultTransformer(Transformers.aliasToBean(EmployeeDto.class));

// 现在查询就能直接得到EmployeeDto的列表了
List<EmployeeDto> employeeDtos = criteria.list();

方案二:直接用构造函数投影

如果你的目标DTO只有有参构造函数,不想写setter,也可以直接在Projection里指定构造函数,这样连别名都不用写:

修改Projection部分的代码

Criteria criteria = session.createCriteria(EmployeeInfo.class);
Criterion condition1 = Restrictions.eq("employeeTO.id", id);
criteria.add(condition1);

// 直接指定DTO的构造函数,参数顺序要和投影字段的顺序完全一致
ProjectionList projectionList = Projections.projectionList()
        .add(Projections.constructor(EmployeeDto.class,
                Projections.property("name"),
                Projections.property("birthDay")));

criteria.setProjection(projectionList);

// 这里不需要额外设置ResultTransformer,Hibernate会自动用构造函数映射
List<EmployeeDto> employeeDtos = criteria.list();

注意点

  • 用构造函数投影时,构造函数的参数类型要和查询返回的字段类型完全匹配,不然会报错;
  • 参数顺序必须和你添加投影字段的顺序一致。

这两种方法都能完美解决你的问题,选哪种看你的DTO结构就行~

内容的提问来源于stack exchange,提问作者jamal mousavi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:48:27