本文将带您了解关于为什么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参数列表?
- 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参数列表?
我正在使用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]
我的问题:
- 为什么将Integer列表的元素直接内联到sql以及将String列表的元素作为已准备好的语句参数处理?
- 此功能是Hibernate特定的还是JPA保证的?
- 从数据库角度来看,应首选哪两个?
- 这是int-yes string-no内联,以某种方式与sql注入相关吗?
- 这是否与RDMBS可以处理的sql IN子句中的值数限制有关?
- 如何编写将与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
我的精简实体看起来像这样:
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?
session.CreateCriteria(typeof(Customer)) .Add(XmlIn.Create("id",potentiallyLargeAmount)) List();
这听起来完全像我需要的.但是,我无法在NHibernate的任何地方找到这个XmlIn功能!这个功能在哪里实现?我该如何访问它?另外,它如何实际解析/处理XML?我是否需要符合某种模式?
解决方法
在这里我找到了从哪里获得Rhino-Commons:
Where to get Rhino Commons
这是链接:
http://github.com/lorenzomelato/rhino-commons
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 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的相关知识,请在本站寻找。
本文标签: