3

我在本机 sql 中有一个查询,例如:

SQLQuery query = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee");

查询结果可用于设置员工对象。在类似的行上,我有相同的查询附加了 addscalar(entity_colname)。

query = session.createSQLQuery("select emp_id, emp_name, emp_salary from Employee")
        .addScalar("emp_id", new LongType())
        .addScalar("emp_name", new StringType())
        .addScalar("emp_salary", new DoubleType());

这里我们也必须以类似的方式获得结果,那么使用 addscalar 有什么好处?

问候杰伊

4

1 回答 1

1

当你不需要 addScalar

在您的示例中,您实际上并不需要使用addScalar.

如果将响应映射到 DTO,如下所示EmployeeDTO

public class EmployeeDTO {
    private final Long id;
    private final String name;
    private final Double salary;

    public EmployeeDTO(Long id, String name, Double salary) {
        this.id = id;
        this.name = name;
        this.salary = salary;
    }

    public Long getId() {
        return id;
    }

    public String getName() {
        return name;
    }

    public Double getSalary() {
        return salary;
    }
}

然后,以下 SQL 查询可以获取EmployeeDTO就好了:

List<EmployeeDTO> employeeDTOs = entityManager
.createNativeQuery(
    "SELECT " +
    "   emp_id AS id, " +
    "   emp_name AS name, " +
    "   emp_salary AS salary " +
    "FROM employee ")
.getResultList();

请注意,我们使用了列别名,以便 Hibernate 可以匹配我们想要设置的 DTO 属性。

当你需要 addScalar

假设您有一个具有 JSON属性的Book实体:properties

@Entity(name = "Book")
@Table(name = "book")
@TypeDef(typeClass = JsonNodeBinaryType.class, defaultForType = JsonNode.class)
public static class Book {

    @Id
    @GeneratedValue
    private Long id;

    @NaturalId
    private String isbn;

    @Column(columnDefinition = "jsonb")
    private JsonNode properties;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getIsbn() {
        return isbn;
    }

    public void setIsbn(String isbn) {
        this.isbn = isbn;
    }

    public JsonNode getProperties() {
        return properties;
    }

    public void setProperties(JsonNode properties) {
        this.properties = properties;
    }
}

由开源项目JsonNodeBinaryType提供。hibernate-types

现在,当执行获取 JSONproperties列的本机 SQL 查询时:

JsonNode properties = (JsonNode) entityManager
.createNativeQuery(
    "SELECT properties " +
    "FROM book " +
    "WHERE isbn = :isbn")
.setParameter("isbn", "978-9730228236")
.getSingleResult();

Hibernate 抛出以下异常:

org.hibernate.MappingException: No Dialect mapping for JDBC type: 1111

这是因为 Hibernate 不知道如何将jsonb列转换为JsonNodeJava 对象,因为它缺少 Hibernate-native JSON Type

但是如果我们调用addScalar并提供 Hibernate Type

JsonNode properties = (JsonNode) entityManager
.createNativeQuery(
    "SELECT properties " +
    "FROM book " +
    "WHERE isbn = :isbn")
.setParameter("isbn", "978-9730228236")
.unwrap(org.hibernate.query.NativeQuery.class)
.addScalar("properties", JsonNodeBinaryType.INSTANCE)
.getSingleResult();

然后查询将运行得很好!

于 2015-06-22T06:48:15.057 回答