如何使用hibernate条件查询将两个属性连接到一个属性

Ami*_*and 5 java hibernate

例如,有2个属性门牌号和密码,我想要一个属性作为地址,如门牌号是10,pincode是110064和组合地址属性是10,110064这是我的代码

  final Criteria criteria= getDatabaseSession().createCriteria(Application.class, "application");
 final ProjectionList projectionList=Projections.projectionList();
 criteria.setProjection(projectionList);

projectionList.add(Projections.property("address.street"), "street");
 projectionList.add(Projections.property("address.postcode"), "postcode");
 projectionList.add(Projections.property("address.houseNumber"), "houseNumber");

 criteria.createAlias("application.applicationCase", "applicationCase", JoinType.INNER_JOIN);
 criteria.createAlias("applicationCase.property", "property");
 criteria.createAlias("property.address", "address");
 criteria.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
 return (Map<String, Object>) criteria.uniqueResult(); 
Run Code Online (Sandbox Code Playgroud)

我想做这样的事情

   projectionList.add(Projections.property("address.street"+"address.houseNumber"+"address.postcode"),"address");
Run Code Online (Sandbox Code Playgroud)

有人可以帮忙吗

v.l*_*nev 12

使用HQL

您可以使用concat表达式,但它只能用于HQL

select concat(address.street, address.houseNumber, address.postcode) as fullAddress from ...
Run Code Online (Sandbox Code Playgroud)

使用@Formula

如果你想使用Criteria,你可以使用@Formula.需要向持久性添加其他属性

@Formula(value = "concat(f_street, f_houseNumber, f_postcode)")
private String fullAddress;
Run Code Online (Sandbox Code Playgroud)

您需要指定列名(而不是属性名),因为Hibernate会将它们按原样添加到SQL中.使用连接时不太方便 - 您需要在公式中指定由Hibernate生成的别名.

你可以参考fullAddress一下Projection

projectionList.add(Projections.property("fullAddress"), "fullAddress");
Run Code Online (Sandbox Code Playgroud)

我用MySQl测试了它.对于Oracle,您可以尝试使用

@Formula(value = "f_street || f_houseNumber || f_postcode")
private String fullAddress;
Run Code Online (Sandbox Code Playgroud)

扩展Hibernate

我试图扩展Projection到添加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 };
    }

}
Run Code Online (Sandbox Code Playgroud)

运用

projectionList.add(
    new ConcatProjection("address.street", 
        "address.houseNumber",  "address.postcode"), "fullAddress");
Run Code Online (Sandbox Code Playgroud)