当前位置: 首页 > 面试题库 >

真正动态的JPA CriteriaBuilder

颛孙飞
2023-03-14
问题内容

我需要创建一个“真实的”动态JPA CriteriaBuilder。我得到Map<String, String>的陈述。看起来像:

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)
}

我试图构建一个big
Predicate,其中包含所有其他谓词,并将其添加到中query.where(),但这些谓词再次覆盖旧值。似乎没有可能添加Predicate而不是更改谓词:-(

实际的项目更加复杂,因为有些对需要使用,equal而另一些需要使用like。但这还不够:可能有一个额外的声明,or如like type : 1;4;7。在这里,值必须拆分并创建如下语句:

<rest of statement> AND (type = 1 OR type = 4 OR type = 7)

UPDATE和SOLUTION 得到两个列表,第一个AND列表很好用。第二个列表包含预期的OR语句:

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();

问题答案:

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

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);

如果需要在and和之间进行区分or,请使用两个列表。



 类似资料:
  • 我需要创建一个“真正的”动态JPA。我得到一个语句。看起来像: 更新和解决方案得到了两个列表,第一个列表为和工作良好。第二个列表包含或语句,如exspected:

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

  • 如今体检车数字化系统这个大CASE摆在面前,那DAP看来也不过尔尔,想到这里,绝影心中反倒充满了大无畏精神:反正DAP是让我做死了,一人做事一人当,大不了就是扣我奖金罚我加班,让我把这体检车数字化系统搞出来,什么指纹识别、照片认证,能加上去的高级技术都加上去,那还不领先个同类产品三五年,到时候,我绝影就牛B了!让暴风雨来得更猛烈些吧! 绝影做好了引颈就戮的准备,周总却说:“DAP的事情我们先放一放

  • 感知一个物体有形的部分可以帮助我们理解如何去控制它。观察一个物理的运动可以告诉我们它轻还是重,柔性还是刚性,小还是大。在 material design 设计规范中,动作不止是呈现着它美丽的一面,它还意味着在空间中的关系、功能以及在整个系统中的趋势。 体积和重量(Mass and Weight) 物理世界中物体拥有质量,所以只有当施加给它们力量的时候才会移动,因此物体没法在瞬间开始或者结束动作。动

  • 问题内容: 据我了解,JSONP只能使用GET动词来实现。假设我认为这是对的,那么这将排除对真正的REST的核心合规性,在其中,您应出于不同和特定的目的而使用不同的动词,例如GET,PUT,POST,DELETE等。 我的问题是,如果我说允许使用使用get请求的JSONP服务更新和删除资源,我可能会遇到哪种障碍。 提供JSON服务并声明用户需要服务器端代理才能使用JavaScript XDomai

  • 自己做的东西,就是怎么看怎么满意,绝影和张厂长都觉得自己写的程序好,周总肯定要用自己的。 周总还是决定用张厂长的程序。绝影用汇编做的,公司以前没尝试过,他还是不想冒这个险,毕竟C语言才是入门语言,大部分程序都懂,以后万一出了什么问题要临时维护也不愁找不到人。 这个决定后来在很长一段时间里让绝影一直耿耿于怀。现在单位里特别是国有单位,年轻人往往对年长的领导腹绯很多,而上了年纪的领导又对这些年轻人意见