GVKun编程网logo

为什么Hibernate内联传递给JPA Criteria Query的Integer参数列表?

2

本文将带您了解关于为什么Hibernate内联传递给JPACriteriaQuery的Integer参数列表?的新内容,另外,我们还将为您提供关于c#–使用nhibernateCriteriaAPI进

本文将带您了解关于为什么Hibernate内联传递给JPA Criteria Query的Integer参数列表?的新内容,另外,我们还将为您提供关于c# – 使用nhibernate Criteria API进行Eager Fetching、c# – 将XML文档作为参数传递给Nhibernate ICriteria?、getHibernateTemplate().findByCriteria()、Hibernate 3 - 5 迁移 Org.hibernate.Criteria:使用 CriteriaBuilder 将 createCriteria(String association, String alias) 更改为标准 JPA的实用信息。

本文目录一览:

为什么Hibernate内联传递给JPA Criteria Query的Integer参数列表?

为什么Hibernate内联传递给JPA Criteria Query的Integer参数列表?

我正在使用JPA Criteria
API构建查询。当我使用javax.persistence.criteria.Path#in(Collection<?>)方法创建两个限制谓词时,生成的SQL查询与我预期的有所不同。

int属性之上构建的第一个谓词产生了SQL,其中的参数集合的所有元素都内联:in (10, 20, 30)

String属性之上构建的第二个谓词产生了参数化的SQL :in (?, ?, ?)

让我展示:

实体:

@Entitypublic class A {    @Id     private Integer id;    private int intAttr;    private String stringAttr;    //getter/setters}

查询:

CriteriaBuilder cb = entityManager.getCriteriaBuilder();CriteriaQuery<A> q = cb.createQuery(A.class);Root<A> root = q.from(A.class);q.where(    root.get("intAttr").in(Arrays.asList(10, 20, 30)),    root.get("stringAttr").in(Arrays.asList("a", "b", "c")));entityManager.createQuery(q).getResultList();

日志:

select    a0_.id as id1_0_,    a0_.intAttr as intAttr2_0_,    a0_.stringAttr as stringAt3_0_ from    A a0_ where    (        a0_.intAttr in (            10 , 20 , 30        )    )     and (        a0_.stringAttr in (            ? , ? , ?        )    ) org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [1] as [VARCHAR] - [a] org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [2] as [VARCHAR] - [b] org.hibernate.type.descriptor.sql.BasicBinder - binding parameter [3] as [VARCHAR] - [c]

我的问题:

  1. 为什么将Integer列表的元素直接内联到sql以及将String列表的元素作为已准备好的语句参数处理?
  2. 此功能是Hibernate特定的还是JPA保证的?
  3. 从数据库角度来看,应首选哪两个?
  4. 这是int-yes string-no内联,以某种方式与sql注入相关吗?
  5. 这是否与RDMBS可以处理的sql IN子句中的值数限制有关?
  6. 如何编写将与String参数列表相同的条件查询来处理Integer参数列表。

答案1

小编典典

为什么不绑定字符串而不绑定数字文字?

应该始终对字符串进行参数绑定(而不是将文字放入查询中),以避免SQL注入。

但是,真正的问题是,为什么将文字直接插入查询中而不使用绑定。最初的原因是:

因此,导致我在此处使用文字的问题与规模和运算有关。含义(再次,iirc)一些数据库需要知道类型信息才能正确处理诸如…
+?…,等等。因此,选择是将所有此类参数包装在CAST函数调用中,并希望/祈祷数据库实现了正确的CAST函数或使用文字。最后,我选择了原义路线,因为那是用户预先要求的。包装函数调用将限制数据库利用很多数据库中索引的能力。

哪个对数据库更好?

它取决于数据库和查询,可能不会有很大的不同。例如,Oracle仅在值是文字时才可以进行某些分区,而其他数据库仅在值是绑定参数时才可以进行某些优化。如果它成为问题(例如,您对其进行了分析,并且知道那是使您放慢速度的原因),则只需切换到其他方法即可。

这在JPA规范中吗?

没有。

这与in语句中允许的值数有关吗?

没有。

我可以使用数字文字范围来代替直接插入查询吗

是的,但是有点冗长。

CriteriaBuilder cb = getEntityManager().getCriteriaBuilder();CriteriaQuery<Foo> query = cb.createQuery(Foo.class);Root<Foo> root = query.from(Foo.class);ParameterExpression<Long> paramOne = cb.parameter(Long.class);Predicate versionPredicate = root.get("bar").in(paramOne);query.select(root).where(versionPredicate);TypedQuery<Foo> typedQuery = getEntityManager().createQuery(query);typedQuery.setParameter(paramOne, 1L);

长期将使用参数绑定。它只是一个参数,但可以很容易地从此处推断出多个参数,并且辅助方法可以清除所有内容。

参考文献:

大多数推理在HHH-6280中进行了解释和讨论。进行此渲染的特定方法是LiteralExpression.render。

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.

c# – 将XML文档作为参数传递给Nhibernate ICriteria?

c# – 将XML文档作为参数传递给Nhibernate ICriteria?

所以我有一个查询,我需要在NHibernate中作为DetachedCriteria运行.我遇到的问题(非常类似于 this one)是我的查询可以有数千个输入参数,并且在2100的sql Server中有一个硬限制.我相信解决方案是将我的参数列表放在XML中文档,并将其作为单个参数传递.在上述页面中描述为如此工作:

session.CreateCriteria(typeof(Customer))
    .Add(XmlIn.Create("id",potentiallyLargeAmount))
    List();

这听起来完全像我需要的.但是,我无法在NHibernate的任何地方找到这个XmlIn功能!这个功能在哪里实现?我该如何访问它?另外,它如何实际解析/处理XML?我是否需要符合某种模式?

解决方法

看起来这是在Rhino-Commons中.我不是那么熟悉它,但经过一些谷歌搜索我发现它在这里: https://github.com/lorenzomelato/rhino-commons/blob/master/Rhino.Commons.NHibernate/NHibernate/XmlIn.cs

在这里我找到了从哪里获得Rhino-Commons:
Where to get Rhino Commons

这是链接:
http://github.com/lorenzomelato/rhino-commons

getHibernateTemplate().findByCriteria()

getHibernateTemplate().findByCriteria()

用了这么多次getHibernateTemplate().findByCriteria(),现在才发现它很好用,可以解决很多查询问题。
 getHibernateTemplate().findByCriteria(criteria)可以查询不需要分页的数据,

getHibernateTemplate().findByCriteria(criteria, firstResult, maxResults)可以用来查询需要的分页的属性,

例如:
 HibernateTemplate ht=this.getHibernateTemplate();

 DetachedCriteria criteria=DetachedCriteria.forClass(Paper.class);

 ht.findByCriteria(criteria, firstResult, maxResults);

有了上面的criteria就更好用了,criteria可以使用add()方法添加我们需要的查询条件,就好比SQL语句中的where条件语句

而add()方法可以使用Restrictions类的静态方法返回值作为参数,例如:
 criteria.add(Restrictions.in("TExams", examsList)).add(Restrictions.eq("patype", 0));

Restrictions类又很多的方法可以代替SQl语句中的“>、=、<、!”等,还包括了isNull、in、and、or等等很多,具体的网上有很多资料。

灵活的使用findByCriteria可以解决SSH框架中大多数查询吧

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内联传递给JPA Criteria Query的Integer参数列表?的介绍现已完结,谢谢您的耐心阅读,如果想了解更多关于c# – 使用nhibernate Criteria API进行Eager Fetching、c# – 将XML文档作为参数传递给Nhibernate ICriteria?、getHibernateTemplate().findByCriteria()、Hibernate 3 - 5 迁移 Org.hibernate.Criteria:使用 CriteriaBuilder 将 createCriteria(String association, String alias) 更改为标准 JPA的相关知识,请在本站寻找。

本文标签: