【问题标题】:JPA CriteriaBuilder and SubstringJPA CriteriaBuilder 和子字符串
【发布时间】:2015-02-21 14:20:48
【问题描述】:

我有一个 CriteriaBuilder,我试图在其中获取从 0 到 10 的字符。但是我无法获得所需的输出。

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Emp> cq = cb.createQuery(Emp.class);
    Root<Emp> c = cq.from(Emp.class);
    cb.substring(c.<String>get("projDesc"), 0, 10);
    cq.orderBy(cb.desc(c.get("salary")));
    Query query = em.createQuery(cq);
    .....

这可能是什么原因?

【问题讨论】:

  • 您不需要将 cb.substring 分配给某些东西吗?否则效果会丢失,就像String.substring
  • @geert3 是对的,如果使用 Substring 运行 SQL 查询,则需要调用该函数并添加到 select 语句中,与 CriteriaBuilder 相同。 projDescEmp.class属性,但不是子串的结果,需要添加到CriteriaBuilder的select语句中。

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


【解决方案1】:

来自javadoc

为子字符串提取创建一个表达式。提取子串 从指定位置开始的给定长度。第一个位置是 1。

试试cb.substring(c.&lt;String&gt;get("projDesc"), 1, 10);


我想你忘记选择Expression&lt;E&gt;

试试cq.select(cb.substring(c.&lt;String&gt;get("projDesc"), 1, 10)) 它将返回List&lt;String&gt;,如果您需要返回Emp,您可以使用

cb.construct(Emp.class, e.get("prop1"), e.get("prop2"), cb.substring(c.&lt;String&gt;get("projDesc"), 1, 10)));

【讨论】:

  • 将位置从 0 更改为 1 并没有解决问题。
  • 那我需要澄清一下,实际输出和预期输出是什么?
  • 实际 - Manage to finish project within stipulated time, however due to other hindrances project was prolonged for an year and incidents beyond jurisdiction. 预期 Manage to。谢谢
  • 根据您的评论编辑。
  • 感谢您的帮助。
【解决方案2】:

我也遇到了同样的问题,我必须对前三个字符进行子串化并从数字 107 开始获取所有帐户。为此,我使用了 CriteriaBuildersubstring 方法,如下所示。

Predicate accountNumber = criteriaBuilder.equal(criteriaBuilder.substring(from.get("accountNumber").as(String.class), 0, 3), cwipAcc);

但不幸的是,它不适用于 CriteriaBuildersubstring。所以我使用 like query 通过下面给出的代码解决了这个问题。

Predicate accountNumber = criteriaBuilder.like(from.get("accountNumber").as(String.class), String.valueOf(cwipAcc) + "%");

这里,我刚刚获取了从 107 开始的所有记录,以此类推。

例子:

public List<GLCharts> findAccountForCWIP(Long cwipAcc, Long glInfo) {
        Map<String, Object> data = new HashMap();
        CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
        CriteriaQuery<GLCharts> criteriaQuery = criteriaBuilder.createQuery(GLCharts.class);
        Root<GLCharts> from = criteriaQuery.from(GLCharts.class);

        Predicate accountNumber = criteriaBuilder.like(from.get("accountNumber").as(String.class), String.valueOf(cwipAcc) + "%");
        Predicate glCompanyInfo = criteriaBuilder.equal(from.join("gLCompanyInfo").get("id"), glInfo);

        Predicate finalPredicate = criteriaBuilder.and(accountNumber, glCompanyInfo);

        criteriaQuery.select(from).where(finalPredicate).orderBy(Stream.of(criteriaBuilder.asc(from.get("accountNumber"))).collect(Collectors.toList()));
        List<GLCharts> glChartsList = entityManager.createQuery(criteriaQuery).getResultList();

        return glChartsList;
    }

【讨论】:

    【解决方案3】:

    我遇到了这个问题,因为我的要求是在 substr 中使用一个数字。以下是示例代码。

     @Override
        public List<SampleProfile> findNonSampleProfileBySequence(Long SampleNo) {
            List<SampleProfile> profiles = new ArrayList<>();
            CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
            CriteriaQuery<SampleProfile> criteriaQuery = criteriaBuilder.createQuery(SampleProfile.class);
            Root<SampleProfile> SampleProfileRoot = criteriaQuery.from(SampleProfile.class);
            List<Predicate> predicates = new ArrayList<Predicate>();
            if (SampleUtil.isValidLong(SampleNo)) {
                String SampleStr = Long.toString(SampleNo);
                if (StringUtils.isNotBlank(SampleStr) && SampleStr.length() > 5) {
                    String SampleSequence = SampleStr.substring(5);
                    predicates.add(criteriaBuilder.equal(criteriaBuilder.substring(SampleProfileRoot.get(SampleProfile_.id).as(String.class), 6), SampleSequence));
                    predicates.add(criteriaBuilder.equal(SampleProfileRoot.get(SampleProfile_.address).get(Address_.department), SampleStr.substring(0,3)));
                }
            }
            if (!CollectionUtils.isEmpty(predicates)) {
                criteriaQuery.where(criteriaBuilder.and(Iterables.toArray(predicates, Predicate.class)));
                profiles = entityManager.createQuery(criteriaQuery).setMaxResults(AbstractJpaDAO.MAX_ROW_LIMIT).getResultList();
            }
            return profiles;
        }
    

    另请注意,为了提高性能,您必须在其上创建索引。 Cast 关键字很重要,因为 Hibernate Dialect 会创建这样的查询,因此,它必须与您的索引匹配。

    CREATE INDEX MY_SCHEMA_OWNER.IDX_SUBSTR_SMP_CODE ON MY_SCHEMA_OWNER.SMP_PROFILE (SUBSTR(**CAST**(SMP_CODE AS VARCHAR2(255 CHAR)),6));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-28
      • 2015-01-30
      • 2021-12-06
      • 1970-01-01
      • 1970-01-01
      • 2011-02-14
      相关资源
      最近更新 更多