使用HQL
您可以使用concat
表达式,但只能与HQL一起使用
select concat(address.street, address.houseNumber, address.postcode) as fullAddress from ...
使用@Formula
如果你想使用Criteria,
您可以使用@Formula
。需要为持久化添加额外的属性
@Formula(value = "concat(f_street, f_houseNumber, f_postcode)")
private String fullAddress;
您需要指定列名(而不是属性名),因为 Hibernate 将它们按原样添加到 SQL 中。当您使用联接时,这不是很方便——您需要在公式中指定由 Hibernate 生成的别名。
您可以参考fullAddress
in the Projection
projectionList.add(Projections.property("fullAddress"), "fullAddress");
我已经用MySQl测试过了。对于Oracle你可以尝试使用
@Formula(value = "f_street || f_houseNumber || f_postcode")
private String fullAddress;
扩展休眠
我曾尝试延长Projection
to add concat
函数到Criteria
。我测试了最简单的情况。
public class ConcatProjection extends SimpleProjection {
private static final String CONCAT_FUNCTION_NAME = "concat";
private final String[] properties;
public ConcatProjection(String... properties) {
this.properties = properties;
}
@Override
public String toSqlString(Criteria criteria, int loc, CriteriaQuery criteriaQuery)
throws HibernateException {
String result = getFunction(criteriaQuery).render(StringType.INSTANCE,
propertiesToColumns(criteria, criteriaQuery), criteriaQuery.getFactory());
return result + " as y" + loc + '_';
}
private List<String> propertiesToColumns(Criteria criteria, CriteriaQuery criteriaQuery) {
List<String> result = new ArrayList<String>(properties.length);
for (String property : properties) {
result.add(criteriaQuery.getColumn(criteria, property));
}
return result;
}
private SQLFunction getFunction(CriteriaQuery criteriaQuery) {
return criteriaQuery.getFactory().getSqlFunctionRegistry()
.findSQLFunction(CONCAT_FUNCTION_NAME);
}
@Override
public Type[] getTypes(Criteria criteria, CriteriaQuery criteriaQuery)
throws HibernateException {
return new Type[] { StringType.INSTANCE };
}
}
Using
projectionList.add(
new ConcatProjection("address.street",
"address.houseNumber", "address.postcode"), "fullAddress");