Hibernate查询.docx
《Hibernate查询.docx》由会员分享,可在线阅读,更多相关《Hibernate查询.docx(13页珍藏版)》请在冰豆网上搜索。
![Hibernate查询.docx](https://file1.bdocx.com/fileroot1/2022-11/24/c7530c83-8763-4b1c-8035-fb536b6b102d/c7530c83-8763-4b1c-8035-fb536b6b102d1.gif)
Hibernate查询
Hibernate的查询语言:
1.NativeSQL:
本地语言(数据库自己的SQL语句)功能强大,
2.HQLHibernateQueryLanguage(更灵活,推荐)条件查询、分页查询、连接查询、嵌套查询,写起来与SQL语法基本一致,唯一不同的就是把表名换成了类或者对象.
3.QBC(QueryByCriteria)查询方式这种方式比较面向对象方式,重点是有三个描述条件的对象:
Restrictions,Order,Projections.
HibernateQueryLanguage:
HQL提供了是十分强大的功能,它是针对持久化对象,用取得对象,而不进行update,delete和insert等操作。
而且HQL是面向对象的,具备继承,多态和关联等特性。
from子句:
from子句是最简单的HQL,例如fromStudent,也可以写成selectsfromStudents。
它简单的返回Student类的所有实例。
Queryquery=session.createQuery("fromCourse");
Listlist=query.list();
for(Coursec:
list){
System.out.println(c.getName());
}
值得注意的是除了JAVA类和属性的名称外,HQL语句对大小写不敏感。
select子句:
有时并不需要取得对象的所有属性,这时可以使用select子句进行属性查询,如selects.namefromStudents
Queryquery=session.createQuery("selectc.namefromCoursec");
带where条件的查询:
where子句:
HQL也支持子查询,它通过where子句实现这一机制。
where子句可以让用户缩小要返回的实例的列表范围。
例如下面语句会返回所有名字为"Bill"的Student实例:
Queryquery=session.createQuery("fromStudentasswheres.name='Bill'");
where子句允许出现的表达式包括了SQL中可以使用的大多数情况。
数学操作:
+,-,*,/
真假比较操作:
=,>=,<=,<>,!
=,like
逻辑操作:
and,or,not
字符串连接:
||
Queryquery=session.createQuery("fromCoursewherename='武术'");
排序:
orderby
查询返回列表可以按照任何返回的类或者组件的属性排序
fromStudentsorderbys.nameasc/desc
连接查询
与SQL一样,HQL也支持连接查询,如内连接,外连接和交叉连接:
innerjoin:
内连接
leftouterjoin:
左外连接
rightouterjoin:
右外连接
fulljoin:
全连接,但不常用
//sql写select...From表1innerjoin表2on表1.列=表2.列
Query query = session.createQuery("from Group g join g.students");
Stringhql="fromBookbleftjoinb.bookType";
注意join后写一个的前面实体类别名.属性名
Queryquery=session.createQuery("fromCoursecjoinc.students");
可以使用冒号(:
),作为占位符,来接受参数使用。
如下(链式编程)
Queryquery=session.createQuery("from类名hwhereh.hid>:
id").setInteger("id",1);
可以使用?
作为占位符.
Queryquery=session.createQuery("from类名hwhereh.hid>?
");
//注意这里的索引值
query.setInteger(0,1);
分页:
Queryquery=session.createQuery("fromHusbandhorderbyh.hiddesc");
//从第几条开始显示,从0开始
query.setFirstResult(0);
//每页显示的最大记录数
query.setMaxResults(3);
模糊查询如何实现?
带参数的sql如何实现?
Stringname="小";
Queryquery=session.createQuery("from类名hwhereh.namelike?
");
//注意这里的索引值
query.setString(0,"%"+name+"%");
其他模糊查询的写法:
isnull/isnotnull/between...and/in(...)
了解
Queryq=session.createQuery("selectmax(m.id),min(m.id),avg(m.id),sum(m.id)from类名m");
Object[]o=(Object[])q.uniqueResult();
System.out.println(o[0]+"-"+o[1]+"-"+o[2]+"-"+o[3]);
如果对HQL不喜欢,也不习惯可以使用SQL的检索方法:
Stringsql="select*frombookwhereid=?
andname=?
";
//2创建一个query对象
Queryquery=session.createSQLQuery(sql);
query.setString(0,"1");
query.setString(1,"天龙侠侣");
//3调用query对象的方法
Listlist=query.list();
Iteratoritor=list.iterator();
while(itor.hasNext())
{
Object[]obj=(Object[])itor.next();
System.out.println(obj[0]+","+obj[1]+","+obj[2]);
}
CriteriaQuery方式
Hibernate支持Criteria查询,这种查询方式把查询条件封装为一个Criteria对象。
在实际应用中,可以使用Session的createCriteria()方法构建一个org.hibernate.Criteria实例,然后把具体的查询条件通过Criteria的add方法加入到Criteria实例中。
Criteria是一种比hql更面向对象的查询方式。
Criteria可使用Criterion和Projection设置查询条件。
可以设置FetchMode(联合查询抓取的模式),设置排序方式,Criteria还可以设置FlushModel(冲刷Session的方式)和LockMode(数据库锁模式)
Criterion是Criteria的查询条件。
Criteria提供了add(Criterioncriterion)方法来添加查询条件。
Criterion接口的主要实现包括:
Example、Junction和SimpleExpression。
而Junction的实际使用是它的两个子类conjunction和disjunction,分别是使用AND和OR操作符进行来联结查询条件集合。
Criterion的实例可以通过Restrictions工具类来创建,Restrictions提供了大量的静态方法,如eq(等于)、ge(大于等于)、between等来方法的创建Criterion查询条件(SimpleExpression实例)。
除此之外,Restrictions还提供了方法来创建conjunction和disjunction实例,通过往该实例的add(Criteria)方法来增加查询条件形成一个查询条件集合。
创建一个Criteria实例
org.hibernate.Criteria接口表示特定持久类的一个查询。
Session是Criteria实例的工厂。
Criteriacrit=sess.createCriteria(Cat.class);
crit.setMaxResults(50);
Listcats=crit.list();
限制内容
限制结果集内容
一个单独的查询条件是org.hibernate.criterion.Criterion接口的一个实例。
org.hibernate.criterion.Restrictions类定义了获得某些内置Criterion类型的工厂方法。
Listcats=sess.createCriteria(Cat.class)
.add(Restrictions.like("name","Fritz%"))
.add(Restrictions.between("weight",minWeight,maxWeight))
.list();
约束可以按逻辑分组。
Listcats=sess.createCriteria(Cat.class)
.add(Restrictions.like("name","Fritz%"))
.add(Restrictions.or(
Restrictions.eq("age",newInteger(0)),
Restrictions.isNull("age")
))
.list();
Listcats=sess.createCriteria(Cat.class)
.add(Restrictions.in("name",newString[]{"Fritz","Izi","Pk"}))
.add(Restrictions.disjunction()
.add(Restrictions.isNull("age"))
.add(Restrictions.eq("age",newInteger(0)))
.add(Restrictions.eq("age",newInteger
(1)))
.add(Restrictions.eq("age",newInteger
(2)))
))
.list();
Hibernate提供了相当多的内置criterion类型(Restrictions子类),但是尤其有用的是可以允许你直接使用SQL。
Listcats=sess.createCriteria(Cat.class)
.add(Restrictions.sql("lower({alias}.name)likelower(?
)","Fritz%",
Hibernate.STRING))
.list();
{alias}占位符应当被替换为被查询实体的列别名。
Property实例是获得一个条件的另外一种途径。
你可以通过调用Property.forName()创建一个
Property。
Propertyage=Property.forName("age");
Listcats=sess.createCriteria(Cat.class)
.add(Restrictions.disjunction()
.add(age.isNull())
.add(age.eq(newInteger(0)))
.add(age.eq(newInteger
(1)))
.add(age.eq(newInteger
(2)))
))
.add(Property.forName("name").in(newString[]{"Fritz","Izi","Pk"}))
.list();
结果集排序
可以使用org.hibernate.criterion.Order来为查询结果排序。
Listcats=sess.createCriteria(Cat.class)
.add(Restrictions.like("name","F%")
.addOrder(Order.asc("name"))
.addOrder(Order.desc("age"))
.setMaxResults(50)
.list();
Listcats=sess.createCriteria(Cat.class)
.add(Property.forName("name").like("F%"))
.addOrder(Property.forName("name").asc())
.addOrder(Property.forName("age").desc())
.setMaxResults(50)
.list();
关联
你可以使用createCriteria()非常容易的在互相关联的实体间建立约束。
Listcats=sess.createCriteria(Cat.class)
.add(Restrictions.like("name","F%")
.createCriteria("kittens")
.add(Restrictions.like("name","F%")
.list();
注意第二个createCriteria()返回一个新的Criteria实例,该实例引用kittens集合中的元素。
接下来,替换形态在某些情况下也是很有用的。
Listcats=sess.createCriteria(Cat.class)
.createAlias("kittens","kt")
.createAlias("mate","mt")
.add(Restrictions.eqProperty("kt.name","mt.name"))
.list();
(createAlias()并不创建一个新的Criteria实例。
)
Cat实例所保存的之前两次查询所返回的kittens集合是没有被条件预过滤的。
如果你希望只获得
符合条件的kittens,你必须使用returnMaps()。
Listcats=sess.createCriteria(Cat.class)
.createCriteria("kittens","kt")
.add(Restrictions.eq("name","F%"))
.returnMaps()
.list();
Iteratoriter=cats.iterator();
while(iter.hasNext()){
Mapmap=(Map)iter.next();
Catcat=(Cat)map.get(Criteria.ROOT_ALIAS);
Catkitten=(Cat)map.get("kt");
}
动态关联抓取
你可以使用setFetchMode()在运行时定义动态关联抓取的语义。
Listcats=sess.createCriteria(Cat.class)
.add(Restrictions.like("name","Fritz%"))
.setFetchMode("mate",FetchMode.EAGER)
.setFetchMode("kittens",FetchMode.EAGER)
.list();
这个查询可以通过外连接抓取mate和kittens。
查询示例
org.hibernate.criterion.Example类允许你通过一个给定实例构建一个条件查询。
Catcat=newCat();
cat.setSex('F');
cat.setColor(Color.BLACK);
Listresults=session.createCriteria(Cat.class)
.add(Example.create(cat))
.list();
版本属性、标识符和关联被忽略。
默认情况下值为null的属性将被排除。
可以自行调整Example使之更实用。
Exampleexample=Example.create(cat)
.excludeZeroes()//excludezerovaluedproperties
.excludeProperty("color")//excludethepropertynamed"color"
.ignoreCase()//performcaseinsensitivestringcomparisons
.enableLike();//uselikeforstringcomparisons
Listresults=session.createCriteria(Cat.class)
.add(example)
.list();
甚至可以使用examples在关联对象上放置条件。
Listresults=session.createCriteria(Cat.class)
.add(Example.create(cat))
.createCriteria("mate")
.add(Example.create(cat.getMate()))
.list();
投影聚合分组
org.hibernate.criterion.Projections是Projection的实例工厂。
通过调用setProjection()应用投影到一个查询。
Listresults=session.createCriteria(Cat.class)
.setProjection(Projections.rowCount())
.add(Restrictions.eq("color",Color.BLACK))
.list();
Listresults=session.createCriteria(Cat.class)
.setProjection(Projections.projectionList()
.add(Projections.rowCount())
.add(Projections.avg("weight"))
.add(Projections.max("weight"))
.add(Projections.groupProperty("color"))
)
.list();
在一个条件查询中没有必要显式的使用"groupby"。
某些投影类型就是被定义为分组投影,他们也出现在SQL的groupby子句中。
可以选择把一个别名指派给一个投影,这样可以使投影值被约束或排序所引用。
实现方式:
Listresults=session.createCriteria(Cat.class)
.setProjection(Projections.alias(Projections.groupProperty("color"),"colr"))
.addOrder(Order.asc("colr"))
.list();?
Listresults=session.createCriteria(Cat.class)
.setProjection(Projections.groupProperty("color").as("colr"))
.addOrder(Order.asc("colr"))
.list();
alias()和as()方法简便的将一个投影实例包装到另外一个别名的Projection实例中。
简而言之,当添加一个投影到一个投影列表中时你可以为它指定一个别名:
Listresults=session.createCriteria(Cat.class)
.setProjection(Projections.projectionList()
.add(Projections.rowCount(),"catCountByColor")
.add(Projections.avg("weight"),"avgWeight")
.add(Projections.max("weight"),"maxWeight")
.add(Projections.groupProperty("color"),"color")
)
.addOrder(Order.desc("catCountByColor"))
.addOrder(Order.desc("avgWeight"))
.list();
Listresults=session.createCriteria(Domestic.class,"cat")
.createAlias("kittens","kit")
.setProjection(Projections.projectionList()
.add(Projections.property("cat.name"),"catName")
.add(Projections.property("kit.name"),"kitName")
)
.addOrder(Order.asc("catName"))
.addOrder(Order.asc("kitName"))
.list();
也可以使用Property.forName()来表示投影:
Listresults=session.createCriteria(Cat.class)
.setProjection(Property.forName("name"))
.add(Property.forName("color").eq(Color.BLACK))
.list();
Listresults=session.createCriteria(Cat.class)
.setProjection(Projections.projectionList()
.add(Projections.rowCount().as("catCountByColor"))
.add(Property.forName("weight").avg().as("avgWeight"))
.add(Property.forName("weight").