JPA Expression连接两列以上

时间:2015-11-25 12:03:11

标签: jpa eclipselink jpa-2.0 criteria criteria-api

我有以下语句来连接两个效果很好的列

Expression<String> stringConcat = 
            cb.concat(cb.concat(root.get(Employee_.userId), " # "), 
                                   joinDept.get(Employee_.empName));

和SQL

select emp.user_id|| ' # '|| dept.emp_name from ..       

我想连接一个列,SQL是

select emp.user_id|| ' # '|| dept.emp_name|| ' # '|| hist.user_name from ..       

不确定如何使用CriteriaBuilder和Expression

在JPA API中添加其他列

修改1

我正在寻找使用多个列的连接,并且标记为重复的答案没有帮助解决问题,最重要的是这个问题被标记并寻求解决方案以解决与JPA Criteria API相关的连接问题,当然不是JPQL。

2 个答案:

答案 0 :(得分:2)

您基本上可以将concat(...)相互包装,或者使用如下方法(假设您希望在列之间使用相同的分隔符字符串):

private CriteriaBuilder criteriaBuilder = /* ... */

// notice the three dots before "expressions", they are no decoration ;-)
private Expression<String> concat(String delimiter, Expression<String> ... expressions) {
    Expression<String> result = null;
    for (int i = 0; i < expressions.length; i++) {
        final boolean first = i == 0, last = i == (expressions.length - 1);
        final Expression<String> expression = expressions[i];
        if (first && last) {
            result = expression;
        } else if (first) {
            result = criteriaBuilder.concat(expression, delimiter);
        } else {
            result = criteriaBuilder.concat(result, expression);
            if (!last) {
                result = criteriaBuilder.concat(result, delimiter);
            }
        }
    }
    return result;
}

Expression<String> userId = root.get(Employee_.userId);
Expression<String> empName = joinDept.get(Employee_.empName);
Expression<String> userName = hist.get(User_.name); // or whatever

Expression<String> stringConcat = concat(" # ", userId, empName, userName);

答案 1 :(得分:0)

这是比jabu.10245提供的多concat函数更简单的实现。

public static Expression<String> concat(CriteriaBuilder cb, String separator,
        Expression<String>... expressions) {
    // Returns an empty string if no expression is provided
    if (expressions.length == 0) {
        return cb.literal("");
    }
    // Start with the first expression
    Expression<String> result = expressions[0];
    // Then concat subsequent expressions (starting from the second one)
    for (int i = 1; i < expressions.length; i++) {
        result = cb.concat(result, cb.concat(separator, expressions[i]));
    }
    return result;
}

奖金:当在参数中不带任何表达式的情况下,它将返回一个空字符串表达式,而不是纯null。在这种情况下,它可以返回cb.nullLiteral(String.class)