【问题标题】:Write query in CriteriaBuilder using Optional<T>使用 Optional<T> 在 CriteriaBuilder 中编写查询
【发布时间】:2021-12-05 08:26:49
【问题描述】:
@Query(value = "select usd from UserDetail usd where usd.phoneNumber=:phoneNumber")
Optional<UserDetail> findByPhoneNumber(@Valid @Param("phoneNumber") String phoneNumber);

这是我的 JPQL 查询方法,我在这里使用带有 Optional 的返回类型。请问CriteriaBuilder怎么写?

我是这样写的,但我遇到了一个错误。

@Override
public Optional<UserDetail> findByCreatedDate(String phoneNumber) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<UserDetail> cq = cb.createQuery(UserDetail.class);
    Root<UserDetail> root = cq.from(UserDetail.class);
    cq.where(cb.equal(root.get("phoneNumber"), phoneNumber))
      .orderBy(cb.desc(root.get("phoneNumber")));
    return em.createQuery(cq).getResultList().get(3);
}

【问题讨论】:

    标签: java spring-boot jpa repository optional


    【解决方案1】:

    如果一个电话号码只与一个人相关联,您为什么要尝试获取列表?

    看看这个:

    @Override
            public Optional<UserDetail> findByCreatedDate(String phoneNumber) {
                CriteriaBuilder cb = em.getCriteriaBuilder();
                CriteriaQuery<UserDetail> cq = cb.createQuery(UserDetail.class);
                Root<UserDetail> root = cq.from(UserDetail.class);
                cq.where(cb.equal(root.get("phoneNumber"), phoneNumber)).orderBy(cb.desc(root.get("phoneNumber")));
                UserDetail ud = em.createQuery(cq).getSingleResult();
                return ud == null ? Optional.empty() : Optional.of(ud)
        
            }
    

    问候,

    【讨论】:

    • 我没有收到列表,我想通过电话号码获取该男子的所有信息。
    • 您好,致电getResultList(),您将获得一份清单,请查看javadoc。通过执行em.createQuery(cq) => jpa api 创建一个包含 UserDetail 对象的TypedQuery&lt;UserDetail&gt;。如果您只想选择特定的列,可以使用em.createQuery(cq).multiSelect("column1", "column2"),为此您需要为对象中的选定列提供相应的构造函数。
    【解决方案2】:

    如果方法返回类型是Optional,这正是你必须返回的。

    em.createQuery(cq).getResultList().get(3) 行仅返回UserDetail,因此您需要将其包装到Optional.of

    @Override
    public Optional<UserDetail> findByCreatedDate(String phoneNumber) {
        CriteriaBuilder cb = em.getCriteriaBuilder();
        CriteriaQuery<UserDetail> cq = cb.createQuery(UserDetail.class);
        Root<UserDetail> root = cq.from(UserDetail.class);
        cq.where(cb.equal(root.get("phoneNumber"), phoneNumber))
          .orderBy(cb.desc(root.get("phoneNumber")));
        return Optional.of(em.createQuery(cq).getResultList().get(3));
    }
    

    顺便问一下,你确定硬编码的.get(3) 是你想要的吗?如果列表为空或少于 4 个元素,则会引发运行时异常。

    【讨论】:

    • 我的 UserDetail 表有 4 列,id、created_date、phone_number、text_message。如何编写没有硬代码,我想要的专栏?
    猜你喜欢
    • 2018-04-30
    • 1970-01-01
    • 2019-11-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多