GVKun编程网logo

使用CriteriaBuilder的JPA + Hibernate count(*)-与generateAlias(criteriaquery怎么用)

21

针对使用CriteriaBuilder的JPA+Hibernatecount和*-与generateAlias这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展c#–使用nhibernateC

针对使用CriteriaBuilder的JPA + Hibernate count*-与generateAlias这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展c# – 使用nhibernate Criteria API进行Eager Fetching、CriteriaBuilder jpa 日期date查询、Hibernate 3 - 5 迁移 Org.hibernate.Criteria:使用 CriteriaBuilder 将 createCriteria(String association, String alias) 更改为标准 JPA、Hibernate createCriteria方法:创建Criteria对象等相关知识,希望可以帮助到你。

本文目录一览:

使用CriteriaBuilder的JPA + Hibernate count(*)-与generateAlias(criteriaquery怎么用)

使用CriteriaBuilder的JPA + Hibernate count(*)-与generateAlias(criteriaquery怎么用)

当尝试count(*)使用CriteriaBuilder我创建类型查询时,出现以下别名问题。

我应该对以下代码进行哪些更改以获取计数?

限制条件:

  1. 我必须使用CriteriaBuilder / Query,因为必须根据值动态构建where子句。
  2. 我只需要COUNT,而不需要内存中的对象列表。

代码示例片段:

 Class<ReqStatCumulative> entityClass = ReqStatCumulative.class; @Override    public long getCountForAlertConfig(AlertConfig cfg) {        long count = 0L;        if (null != cfg) {            CriteriaBuilder qb = entityManager.getCriteriaBuilder();            Metamodel model = entityManager.getMetamodel();            EntityType<ReqStatCumulative> reqStatEntType_ = model.entity(entityClass);            CriteriaQuery<ReqStatCumulative> cq = qb.createQuery(entityClass);            Root<ReqStatCumulative> rootReqStatEnt = cq.from(reqStatEntType_);            Path<Long> processTimeSeconds = rootReqStatEnt.<Long> get("processTimeSeconds");            cq.where(qb.and(qb.greaterThan(processTimeSeconds, (long) cfg.getProcessTimeExceedsSec()),//                    qb.lessThan(processTimeSeconds, (long) cfg.getProcessTimeExceedsSec() + 100))//            );//            findCountByCriteria(entityManager, cq, qb);            log.debug("\n\t#####Alert desc:" + cfg.getDescription());            log.debug("\n\t#####Alert count= " + count);        } else {            // Do nothing        }        return count;    }    public <T> Long findCountByCriteria(EntityManager em, CriteriaQuery<T> cqEntity, CriteriaBuilder qb) {        CriteriaBuilder builder = qb;        CriteriaQuery<Long> cqCount = builder.createQuery(Long.class);        Root<?> entityRoot = cqCount.from(cqEntity.getResultType());        cqCount.select(builder.count(entityRoot));        cqCount.where(cqEntity.getRestriction());        return em.createQuery(cqCount).getSingleResult();    }

日志:我希望在所有where子句属性中使用generateAlias0而不是generateAlias1。

select count(*) from abc.domain.ReqStatCumulative as **generatedAlias0** where ( **generatedAlias1**.processTimeSeconds>5L ) and ( **generatedAlias1**.processTimeSeconds<200L )10:48:57.169 [main] DEBUG o.h.h.i.ast.QueryTranslatorImpl - parse() - HQL: select count(*) from abc.domain.ReqStatCumulative as generatedAlias0 where ( generatedAlias1.processTimeSeconds>5L ) and ( generatedAlias1.processTimeSeconds<200L )10:48:57.169 [main] DEBUG o.h.h.i.ast.QueryTranslatorImpl - --- HQL AST --- \-[QUERY] Node: ''query''    +-[SELECT_FROM] Node: ''SELECT_FROM''    |  +-[FROM] Node: ''from''    |  |  \-[RANGE] Node: ''RANGE''    |  |     +-[DOT] Node: ''.''    |  |     |  +-[DOT] Node: ''.''    |  |     |  |  +-[IDENT] Node: ''abc''    |  |     |  |  \-[IDENT] Node: ''domain''    |  |     |  \-[IDENT] Node: ''ReqStatCumulative''    |  |     \-[ALIAS] Node: ''**generatedAlias0**''    |  \-[SELECT] Node: ''select''    |     \-[COUNT] Node: ''count''    |        \-[ROW_STAR] Node: ''*''    \-[WHERE] Node: ''where''       \-[AND] Node: ''and''          +-[GT] Node: ''>''          |  +-[DOT] Node: ''.''          |  |  +-[IDENT] Node: ''**generatedAlias1**''          |  |  \-[IDENT] Node: ''processTimeSeconds''          |  \-[NUM_LONG] Node: ''5L''          \-[LT] Node: ''<''             +-[DOT] Node: ''.''             |  +-[IDENT] Node: ''**generatedAlias1**''             |  \-[IDENT] Node: ''processTimeSeconds''             \-[NUM_LONG] Node: ''200L''10:48:57.169 [main] DEBUG o.h.hql.internal.ast.ErrorCounter - throwQueryException() : no errors10:48:57.169 [main] DEBUG o.h.h.i.antlr.HqlSqlBaseWalker - select << begin [level=1, statement=select]10:48:57.169 [main] DEBUG o.h.h.internal.ast.tree.FromElement - FromClause{level=1} : erf.domain.ReqStatCumulative (generatedAlias0) -> reqstatcum0_10:48:57.169 [main] ERROR o.h.hql.internal.ast.ErrorCounter -  Invalid path: ''generatedAlias1.processTimeSeconds''10:48:57.215 [main] ERROR o.h.hql.internal.ast.ErrorCounter -  Invalid path: ''generatedAlias1.processTimeSeconds''org.hibernate.hql.internal.ast.InvalidPathException: Invalid path: ''generatedAlias1.processTimeSeconds''

答案1

小编典典

您的代码失败,因为您Root为count和where子句使用了不同的实例:第一个(按定义顺序)生成generatedAlias1别名,另一个生成generatedAlias0。您需要重构代码,以便Root在两个地方使用相同的实例:

CriteriaQuery<Long> cqCount = builder.createQuery(Long.class);Root<ReqStatCumulative> entityRoot = cqCount.from(cqEntity.getResultType());cqCount.select(builder.count(entityRoot));Path<Long> processTimeSeconds = entityRoot.get("processTimeSeconds");cqCount.where(qb.and(qb.greaterThan(processTimeSeconds, (long) cfg.getProcessTimeExceedsSec()),//                qb.lessThan(processTimeSeconds, (long) cfg.getProcessTimeExceedsSec() + 100))//                );//    return em.createQuery(cqCount).getSingleResult();

c# – 使用nhibernate Criteria API进行Eager Fetching

c# – 使用nhibernate Criteria API进行Eager Fetching

我试图在多个表上使用标准Api和急切加载.

我的精简实体看起来像这样:

class Limit
{
    Risk {get; set;}
}

class Risk
{
   List<Company> Companies { get;set;}
}

class Company
{
  List<Address> OldAdresses {get;set;}
}

class Address
{
  string Street { get;set;}
}

我的Criteria调用如下所示:

var CriterionGruppe = Expression.Eq("Account.Id",someGuid);

var temp = _transaktion.Session.CreateCriteria(typeof(Limit))
.SetFetchMode("Risk",FetchMode.Eager)
.SetFetchMode("Risk.Companies",FetchMode.Eager)
.Add(CriterionGruppe)
.SetResultTransformer(new distinctRootEntityResultTransformer())
.List<Limit>();

地址仍然加载了许多选择.如何在我的标准电话中包含公司的旧地址.

我已经在ayende的博客中阅读了博客文章,并在stackoverflow上阅读了其他几个问题.但仍然没有运气.

我希望有人能指出我正确的方向.

在此先感谢彼得

When must we use eager loading in NHibernate? What is it’s usage?

NHibernate Eager Fetching Over Multiple Levels

Ayende Blog

解决方法

var account = _transaktion.Session.Load<Account>(someGuid);
var temp = _transaktion.Session.CreateCriteria(typeof(Limit))
    .SetFetchMode("Risk",FetchMode.Eager)
    .SetFetchMode("Risk.Companies",FetchMode.Eager)
    .SetFetchMode("Company.OldAddresses",FetchMode.Eager)
    .Add(Expression.Eq("Account",account))
    .SetResultTransformer(new distinctRootEntityResultTransformer())
    .List<Limit>();

然而,这是非常低效的.您正在加载大量重复数据以进行1 SQL查询.一个更好的方法是

>加载实际需要的投影>使用Futures和Batched延迟加载来避免单个笛卡尔结果集并选择n 1.

CriteriaBuilder jpa 日期date查询

CriteriaBuilder jpa 日期date查询

概要:前端日期选择器选择完之后传一个String到后台,后台的字段的数据类型是date

 

前端:

<label class="layui-form-label" >单据日期</label>
                <div class="layui-input-inline">
                    <input type="text" id="taxDate" placeholder="单据日期"
                           autocomplete="off" class="layui-input">
                </div>
//单据日期
    laydate.render({
        elem: ''#taxDate''
        ,type: ''date'' //默认,可不填
    });

后端:

    @Override
    public Page<SalesOrder> findPage(SalesOrderModel salesOrderModel, int currentPage, int pageSize) {

        Specification<SalesOrder> specification = new Specification<SalesOrder>() {

            @Override
            public Predicate toPredicate(Root<SalesOrder> root, CriteriaQuery<?> query, CriteriaBuilder cb) {
                List<Predicate> list = new ArrayList<>();
                Predicate deleteMark = cb.equal(root.get("deleteMark").as(Boolean.class), false);
                list.add(deleteMark);
                // 单据编号
                if (!CommonUtil.isEmpty(salesOrderModel.getOrderId())) {
                    Predicate orderId = cb.like(root.get("orderId"), "%" + salesOrderModel.getOrderId().trim() + "%");
                    list.add(orderId);
                }

                // 内部编号
                if (!CommonUtil.isEmpty(salesOrderModel.getEntryId())) {
                    Predicate entryId = cb.like(root.get("entryId"), "%" + salesOrderModel.getEntryId().trim() + "%");
                    list.add(entryId);
                }

                // 单据日期
                if (!CommonUtil.isEmpty(salesOrderModel.getTaxDate())) {
                    SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
                    Date startDate = null;
                    Date endDate = null;
                    try {
                        startDate = format.parse(salesOrderModel.getTaxDate());
                        endDate = format.parse(salesOrderModel.getTaxDate());
                    } catch (ParseException e) {
              startDate = new Date();
              endDate = new Date();
            }
            Predicate taxDate
= cb.between(root.<Date>get("taxDate"),startDate, endDate);//开始日期和结束日期是同一个 list.add(taxDate);
      }
        Predicate[] predicates
= new Predicate[list.size()]; return cb.and(list.toArray(predicates));
} };
        List
<Order> orders = new ArrayList<>(); orders.add(new Order(Direction.DESC, "createDate"));
      Sort sort
= Sort.by(orders); Pageable pageable = PageRequest.of(currentPage - 1, pageSize, sort);

      return salesOrderRepository.findAll(specification, pageable);
}

 

Hibernate 3 - 5 迁移 Org.hibernate.Criteria:使用 CriteriaBuilder 将 createCriteria(String association, String alias) 更改为标准 JPA

Hibernate 3 - 5 迁移 Org.hibernate.Criteria:使用 CriteriaBuilder 将 createCriteria(String association, String alias) 更改为标准 JPA

如何解决Hibernate 3 - 5 迁移 Org.hibernate.Criteria:使用 CriteriaBuilder 将 createCriteria(String association, String alias) 更改为标准 JPA?

所以我有这个 Hibernate Criteria 代码,我想使用 JPA 进行更改,我已经对下面引用的它进行了更改,但我似乎无法找到替代方法来使用 detCrit.createCriteria(字符串关联,字符串别名)使用 JPA 的 CriteriaBuilder。如果有人知道替代解决方案,我将不胜感激。

\\\Initial Hibernate Criteria code

Criteria deCrit = currentSession().createCriteria(first.class,"firstbasic");
Criteria secondThemeCrit = detCrit.createCriteria("secondBasic","sc");
Criteria thirdThemeCrit = secondThemeCrit.createCriteria("thirdBasic");
\\\Partially changed code with JPA

CriteriaBuilder builder = Session.getCriteriaBuilder();
CriteriaQuery<First> deCrit = builder.createquery(First.class);
Root<First> first = detCrit.from(First.class);
first.alias("firstbasic");

解决方法

我不知道您后来如何使用此代码,但我假设在子查询中?如果是这样,您可以将子查询中的根与相关对象上的 just call join 相关联,这应该导致相同的结果:

CriteriaBuilder builder = Session.getCriteriaBuilder();
CriteriaQuery<First> deCrit = builder.createQuery(First.class);
Root<First> first = detCrit.from(First.class);
Subquery<Integer> subquery = deCrit.subquery(Integer.class);
Root<First> correlatedFirst = subquery.correlate(first);
Join<First,Second> second = correlatedFirst.join("second");

Hibernate createCriteria方法:创建Criteria对象

Hibernate createCriteria方法:创建Criteria对象

createCriteria 方法用来生成一个 Criteria 对象,可以返回符合检索条件的该类对象的示例集合。

语法:

createCriteria(Class persistentClass)

参数说明:
  • persistentClass:实体类。

返回值:Criteria 对象。

示例

应用 QBC 查询全部用户信息,关键代码如下:
Session session = sessionFactory.openSession();  //打开Session
Criteria criteria = session.createCriteria(UserForm.class);  //生成Criteria对象
List list = criteria.list();

我们今天的关于使用CriteriaBuilder的JPA + Hibernate count*-与generateAlias的分享就到这里,谢谢您的阅读,如果想了解更多关于c# – 使用nhibernate Criteria API进行Eager Fetching、CriteriaBuilder jpa 日期date查询、Hibernate 3 - 5 迁移 Org.hibernate.Criteria:使用 CriteriaBuilder 将 createCriteria(String association, String alias) 更改为标准 JPA、Hibernate createCriteria方法:创建Criteria对象的相关信息,可以在本站进行搜索。

本文标签: