为啥要使用 Hibernate Query addScalar 方法?
Posted
技术标签:
【中文标题】为啥要使用 Hibernate Query addScalar 方法?【英文标题】:Why to use the Hibernate Query addScalar method?为什么要使用 Hibernate Query addScalar 方法? 【发布时间】:2015-06-22 03:19:22 【问题描述】:我在本机 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有什么好处呢?
问候 周杰伦
【问题讨论】:
如果您正在处理大量数据,它会提高性能。两者都返回 Object 数组。 你帮助你从对象转换为我们指定的类型.. 【参考方案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 属性。
当您需要添加标量时
假设您有一个具有 JSON properties
属性的 Book
实体:
@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
开源项目提供。
现在,当执行获取 JSON properties
列的本机 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
列转换为 JsonNode
Java 对象,因为它缺少 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();
那么查询就可以正常运行了!
【讨论】:
这也可以使用addentity来完成,但是addscalar有什么优势呢? 解析参数类型只有一点优势。但优势只是微不足道的,因为实际上 setParameter 的效果也一样好。以上是关于为啥要使用 Hibernate Query addScalar 方法?的主要内容,如果未能解决你的问题,请参考以下文章