当前位置: 首页 > 面试题库 >

将Hibernate查询结果映射到自定义类?

微生青青
2023-03-14
问题内容

有人可以向我展示如何在Hibernate中编写以下SQL并正确获取结果的示例吗?

SQL:

select firstName, lastName
from Employee

如果可能的话,我想做的就是将结果放入自己的基类中:

class Results {
    private firstName;
    private lastName;
    // getters and setters
}

我相信在JPA(使用EntityManager)中是可能的,但是我还没有弄清楚如何在Hibernate(使用SessionFactorySession)中做到这一点。

我试图更好地学习Hibernate,即使这个“简单”查询也令人困惑,无法知道Hibernate以哪种形式返回结果,以及如何将结果映射到我自己的(基)类中。因此,在DAO例程结束时,我将执行以下操作:

List<Results> list = query.list();

返回Listof Results(my base class)。


问题答案:
select firstName, lastName from Employee

query.setResultTransformer(Transformers.aliasToBean(MyResults.class));

由于异常,你不能将以上代码与Hibernate 5和Hibernate 4(至少Hibernate 4.3.6.Final)一起使用。

java.lang.ClassCastException: com.github.fluent.hibernate.request.persistent.UserDto cannot be cast to java.util.Map
    at org.hibernate.property.access.internal.PropertyAccessMapImpl$SetterImpl.set(PropertyAccessMapImpl.java:102)

问题在于,Hibernate将列名的别名转换为大写- firstName变为FIRSTNAME。它试图找到名字一个getter getFIRSTNAME(),和setter setFIRSTNAME()在DTO使用这种策略

    PropertyAccessStrategyChainedImpl propertyAccessStrategy = new PropertyAccessStrategyChainedImpl(
            PropertyAccessStrategyBasicImpl.INSTANCE,
            PropertyAccessStrategyFieldImpl.INSTANCE,
            PropertyAccessStrategyMapImpl.INSTANCE
    );

PropertyAccessStrategyMapImpl.INSTANCEHibernate认为,仅适合使用。因此,在此之后,它尝试进行转换(Map)MyResults。

public void set(Object target, Object value, SessionFactoryImplementor factory) {
    ( (Map) target ).put( propertyName, value );
}

不知道,这是错误或功能。

怎么解决

使用带引号的别名

public class Results {

    private String firstName;

    private String lastName;

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

}

String sql = "select firstName as \"firstName\", 
    lastName as \"lastName\" from Employee";

List<Results> employees = session.createSQLQuery(sql).setResultTransformer(
    Transformers.aliasToBean(Results.class)).list(); 

使用自定义结果转换器

另一种方式来解决这个问题-使用忽略方法名的情况下(结果转换getFirstName()getFIRSTNAME())。你可以编写自己的代码或使用FluentHibernateResultTransformer。你将不需要使用引号和别名(如果你的列名称等于DTO名称)。

只需从项目页面下载该库(不需要其他jar):fluent-hibernate。

String sql = "select firstName, lastName from Employee";
List<Results> employees = session.createSQLQuery(sql)
        .setResultTransformer(new FluentHibernateResultTransformer(Results.class))
        .list();


 类似资料:
  • 我需要使用本机查询对2-3个表执行联合操作,并需要将结果映射到自定义对象中。由于JPA不支持UNION子句,所以JPA不可能实现同样的事情。 我听说过SqlResultSetMap,它在这种情况下有用吗? 如何以及在哪里使用这个,任何链接或其他东西?没有在谷歌上获得太多信息。

  • 我需要通过连接3个不同的表来获取6列。我在entity类的顶部将它们声明为NamedNativequery,并且使用了create named query method form JPA。当我尝试fo获取结果集时,我得到的是数组对象列表,而不是POJO类型的对象列表。为了将结果集映射到外部POJO,我应该定义任何外部映射吗?

  • 我想进行一个复杂的查询,并将结果映射到DTO中。DTO如下所示: 我的存储库接口是从 。这抛出了一个 ,因为 本身不是实体。 存储库是: 查询从其他实体获取数据以构建DTO。有没有办法将每个列映射到DTO?我试图用下面的查询映射它,但它仍然得到<code>而不是托管类。

  • 现在,问题是,虽然我可以获得存储过程返回的结果,但该结果没有转换为Java类(TNapraviNalog),所以我必须手动执行此操作。我可以用TNapraviNalog的实例(stmt.SetObject(1,ParamValues.get(0));)成功调用Oracle过程,但无法将结果转换为TNapraviNalog。我真的很想有一个 但是,这一行会导致异常(java.lang.ClassCa

  • 例如,我有以下接口映射器: 在代码中,您可以看到映射和一些默认方法,其中包含其他映射。如何在Mapstruct映射中使用这些方法,以便Mapstruct使用这些方法在字段中填充值?

  • 我有EntityA和EntityB,它们具有一个从EntityA->EntityB的OneToMany关系。我想将EntityB作为属性包含到EntityA中。 另一种解决方法是在方法中获取并设置该属性,但我的目标是在entity类中找到一个解决方案。有人有主意吗?谢谢