当前位置: 首页 > 知识库问答 >
问题:

真正动态JPA准则

乐正穆冉
2023-03-14

我需要创建一个“真正的”动态JPACriteriaBuilder。我得到一个映射 语句。看起来像:

name : John
surname : Smith
email : email@email.de

...more pairs possible
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<User> query = cb.createQuery(User.class);
Root<User> userRoot = query.from(User.class);
query.select(userRoot);

List<Predicate> predicates = new ArrayList<Predicate>();
Iterator<String> column = statements.keySet().iterator();
while (column.hasNext()) {

    // get the pairs
    String colIndex = column.next();
    String colValue = statements.get(colIndex);

    // create the statement
    Predicate pAnd = cb.conjunction();
    pAnd = cb.and(pAnd, cb.equal(userRoot.get(colIndex), colValue));
    predicates.add(pAnd);
}

// doesn't work, i don't know how many predicates i have -> can not address them
query.where(predicates.get(0), predicates.get(1), ...);

// doesn't work, because it is a list of predicates
query.where(predicates);

// doesn't work, because the actual predicate overwrites the old predicate
for (Predicate pre : predicates) {
     query.where(pre)
}

<语句的其余部分>和(type=1或type=4或type=7)

更新和解决方案得到了两个列表,第一个列表为和工作良好。第二个列表包含或语句,如exspected:

final List<Predicate> andPredicates = new ArrayList<Predicate>();
final List<Predicate> orPredicates = new ArrayList<Predicate>();
for (final Entry<String, String> entry : statements.entrySet()) {
    final String colIndex = entry.getKey();
    final String colValue = entry.getValue();
    if (colIndex != null && colValue != null) {

        if (!colValue.contains(";")) {
            if (equals) {
                andPredicates.add(cb.equal(userRoot.get(colIndex), colValue));
            } else {
                andPredicates.add(cb.like(userRoot.<String> get(colIndex), "%" + colValue + "%"));
            }
        } else {
            String[] values = colValue.split(";");
            for (String value : values) {
                orPredicates.add(cb.or(cb.equal(userRoot.get(colIndex), value)));
            }
        }       
    }
}

// Here goes the magic to combine both lists
if (andPredicates.size() > 0 && orPredicates.size() == 0) {
    // no need to make new predicate, it is already a conjunction
    query.where(andPredicates.toArray(new Predicate[andPredicates.size()]));
} else if (andPredicates.size() == 0 && orPredicates.size() > 0) {
    // make a disjunction, this part is missing above
    Predicate p = cb.disjunction();
    p = cb.or(orPredicates.toArray(new Predicate[orPredicates.size()]));
    query.where(p);
} else {
    // both types of statements combined
    Predicate o = cb.and(andPredicates.toArray(new Predicate[andPredicates.size()]));
    Predicate p = cb.or(orPredicates.toArray(new Predicate[orPredicates.size()]));
    query.where(o, p);
}

query.where(predicates.toArray(new Predicate[predicates.size()]));
users = em.createQuery(query).getResultList();

共有1个答案

孙永思
2023-03-14

您可以将谓词数组传递给criteriabuilder,然后决定equallike。为此,构建一个列表,并将列表的内容打包到一个语句中的数组中。像这样:

final List<Predicate> predicates = new ArrayList<Predicate>();

for (final Entry<String, String> e : myPredicateMap.entrySet()) {

    final String key = e.getKey();
    final String value = e.getValue();

    if ((key != null) && (value != null)) {

        if (value.contains("%")) {
            predicates.add(criteriaBuilder.like(root.<String> get(key), value));
        } else {
            predicates.add(criteriaBuilder.equal(root.get(key), value));
        }
    }
}

query.where(criteriaBuilder.and(predicates.toArray(new Predicate[predicates.size()])));
query.select(count);

如果需要在之间保持距离,请使用两个列表。

 类似资料:
  • 问题内容: 我需要创建一个“真实的”动态JPA 。我得到的陈述。看起来像: 这是我实现的: 我试图构建一个big ,其中包含所有其他谓词,并将其添加到中,但这些谓词再次覆盖旧值。似乎没有可能添加而不是更改谓词:-( 实际的项目更加复杂,因为有些对需要使用,而另一些需要使用。但这还不够:可能有一个额外的声明,如like 。在这里,值必须拆分并创建如下语句: UPDATE和SOLUTION 得到两个列

  • 问题内容: 通常,我是Hibernate用户,对于我的新项目,我们使用JPA 2.0。 我的DAO收到一个带有泛型的容器。 以下行将无法编译: 因为我必须这样指定类型: 但是我不想那样做!因为我在容器中使用了泛型!你有主意吗 问题答案: 只要您是(这是必填项),您就可以执行以下操作:

  • 我将与一起使用,并希望执行一些动态搜索。 player_team.java 对于每个域名,我都有这样的存储库:

  • 问题内容: 我有一个使用JPA 2的相当标准的Java EE6 Web应用程序,并且具有依赖关系注入连接到MySQL数据库,并且一切正常。我现在想做的是让该应用程序与我们在客户端站点上安装的其他应用程序的数据库交互- 本质上充当我们其他应用程序安装的一个控制点。 我正在努力的是如何最好地与其他数据库进行交互。理想情况下,我想为每个安装创建一个EntityManager并使用JPA进行交互,但是我看

  • 问题内容: 正如可以使用type(name,base-classes,namespace-dict)创建动态类一样,可以创建动态函数吗? 我尝试按照以下方式做一些事情: 好吧,所以我会很聪明,但是: Python是否以允许动态类的相同方式 专门 阻止动态函数的创建? 编辑:注意,我将禁止使用exec。由于我的问题是Python语言本身是否允许这样做。 提前致谢。 问题答案: 还有,你可以用它来动态

  • 假设我有一个生成的实体,如下所示: 我的输入值是字段名称(“可用性”、“生日”、“CVID”...)和一个字符串值,我应该使用它对所有字段执行“like”。 我想从以下字段名开始构建一个查询: null 我试图使用PathBuilder,但似乎要使用“getString或getBoolean”之类的方法,就必须知道要提取的字段的类型。在我的例子中,由于我只是从字段名开始,所以我不能使用这些方法,也