收藏 分享(赏)

使用Hibernate查询数据.ppt

上传人:HR专家 文档编号:6531384 上传时间:2019-04-16 格式:PPT 页数:28 大小:750.50KB
下载 相关 举报
使用Hibernate查询数据.ppt_第1页
第1页 / 共28页
使用Hibernate查询数据.ppt_第2页
第2页 / 共28页
使用Hibernate查询数据.ppt_第3页
第3页 / 共28页
使用Hibernate查询数据.ppt_第4页
第4页 / 共28页
使用Hibernate查询数据.ppt_第5页
第5页 / 共28页
点击查看更多>>
资源描述

1、第14章 使用Hibernate 查询数据,目 录,1,2,使用HQL查询数据,使用QBC查询数据,2,14.1,使用HQL查询数据,3,14.1 使用HQL查询数据,4,HQL(Hibernate Query Language)是Hibernate提供的一种面向对象的查询语言,HQL提供了更加丰富灵活的特性,提供了强大的查询能力。在Hibernate中,将HQL作为推荐的查询模式,使用类、对象和属性概念,没有表和字段的概念。HQL提供了更接近传统SQL语句的查询语法。 使用传统的JDBC API来查询数据,需要编写复杂的SQL语句,然后还要将查询结果以对象的形式进行封装,放到集合对象中保存。

2、这种查询方式不仅麻烦,而且容易出错。 HQL查询与JDBC查询相比,具体以下优点: 直接针对实体类和属性进行查询,不要再编写繁琐的SQL语句。 查询结果是直接保存在List中的对象,不要再次封装。 可以通过配置dialect属性,对不同的数据库自动生成不同的用于执行的SQL语句。,14.1.1 简单查询,5,从数据表meal中查询所有的产品对象,按照名称升序排序,将查询结果输出到控制台。 将项目hibernate-3复制并命名为“hibernate-10”,再导入到MyEclipse开发环境中。在测试类HibernateTest中添加testHql_1()方法,并使用Test注解加以修饰。代码

3、如下:String hql = “from Meal as m order by m.mealName asc“; HQL语句“from Meal as m”中Meal是类名,而不是表名,因此需要区分大小写,关键字from不区分大小写。 在HQL语句中可以使用别名,例如m是Meal类的别名,别名可以使用关键字as指定,as关键字也可以省略。 通过order by子句将查询结果按照餐品名称升序排序。升序排序的关键字是asc,降序排序的关键字是desc,查询语句中默认为升序。,import org.hibernate.query.Query; Testpublic void testHql_1()

4、/ 编写HQL语句String hql = “from Meal as m order by m.mealName asc“;/ 创建Query对象Query query= session.createQuery(hql,Meal.class);/ 执行查询,获得结果List list=query.getResultList() ;/ 遍历查找结果Iterator iterator=list.iterator();while (iterator.hasNext() Meal meal = iterator.next();System.out.println(meal.getMealId()+“

5、. “ + meal .getMealName() + “:t“ + meal .getMealSummarize();,14.1.2 属性查询,6,简单查询的结果是对象的所有属性,如果只查询对象的部分属性,则称为属性查询,也称为投影查询。在测试类HibernateTest中添加testHql_2()方法,并使用Test注解加以修饰,代码如下:,Testpublic void testHql_1()/ 编写HQL语句,使用属性查询String hql=“select m.mealId,m.mealName from Meal as m“;/ 创建Query对象,此处不使用泛型Query que

6、ry= session.createQuery(hql);/ 执行查询,获得结果List list=query.getResultList() ;/ 遍历查找结果Iterator iterator=list.iterator();while (iterator.hasNext() Object object=(Object)iterator.next();System.out.println(object0+“. “+object1);,14.1.3 聚集函数,7,在HQL语句中可以使用的聚集函数包括统计记录总数(count)、计算最小值(min)、计算最大值(max)、计算和(sum)、计算

7、平均值(avg)。 在实体类Meal.java中有一个属性mealPrice,在映射文件中Meal.hbm.xml中已经为Meal.java中的属性mealPrice配置了映射,对应数据表meal中的MealPrice字段。在测试类HibernateTest中添加testHql_3()方法,并使用Test注解加以修饰,代码如下:,/ 使用count 统计餐品的记录总数String hql1=“select count(m) from Meal m“;Query query1= session.createQuery(hql1);Long count=(Long)query1.uniqueRes

8、ult();/ 使用avg 统计餐品的平均价String hql2=“select avg(m.mealPrice) from Meal m“;Query query2= session.createQuery(hql2);Double money=(Double)query2.uniqueResult();/ 使用max 和min 统计最贵和最便宜的餐品String hql2=“select max(m.mealPrice),min(m.mealPrice) from Meal m“;Query query3= session.createQuery(hql3);Object price=(

9、Object)query3.uniqueResult();System.out.println(“记录总数:“ +count+ “,平均金额:“ +money+ “,最低价格为:“+price0 +“,最高价格为:“+price1);,14.1.4 分组查询,8,在测试类HibernateTest中添加testHql_4()方法,并使用Test注解修饰,以餐品菜系为分组依据对所有餐品进行分组,查询数据表meal中各种类型的餐品总数,代码如下:,/ 分组统计餐品的菜系总数String hql=“select m.mealseries.seriesName,count(*) from Meal m

10、 group by m.mealseries“;Query query= session.createQuery(hql);List list=query.getResultList() ;/ 遍历查找结果Iterator iterator=list.iterator();while (iterator.hasNext() Object object=(Object)iterator.next();System.out.println(“菜系:“+ object0 + “,餐品总数:“+ object1);,14.1.5 动态实例查询,9,在属性查询(或投影查询)时,返回的查询结果是一个对象数

11、组,不易操作。为了提供检索效率,可将检索出来的属性封装到一个实体类对象中,这种方式就是动态实例查询。 在测试类HibernateTest中添加testHql_5()方法,并使用Test注解加以修饰,只查询餐品信息中的名称和Id号,将检索出来的属性封装到一个实体类的对象中,代码如下:在HQL语句中使用了Meal类的带餐品Id号和餐品名称两个参数的构造方法,因此需要在实体类Meal类中添加这个构造方法。,/编写Hql语句,使用动态实例查询String hql = “select new Meal(m.mealId,m.mealName) from Meal m“;Query query= sess

12、ion.createQuery(hql,Meal.class);List list=query.getResultList() ;for(Meal m : list)System.out.println(m.getMealId() + “. “ + m.getMealName();,14.1.6 分页查询,10,批量查询数据时,在单个页面上显示所有的查询结果会存在一定的问题,因此需要对查询结果进行分页显示。Query接口提供了用于分页显示查询结果的方法:(1) setFirstResult(int firstResult)(2) setMaxResult(int maxResult) 分页查询

13、是系统中常用的一个功能,为了方便调用,先在测试类HibernateTest中添加方法pagedSearch(int pageIndex, int pageSize),根据页码和每页显示记录数从数据表meal中获取相应的记录。第一个参数表示当前页码,第二个参数表示每页显示多少个对象。 然后在测试类HibernateTest中添加testHql_6()方法,并使用Test注解加以修饰,调用pagedSearch方法。,14.1.7 条件查询,11,实际应用中,常常需要根据指定的条件进行查询。此时,可以使用HQL语句提供的where子句进行查询,或者使用like关键字进行模糊查询。 根据提供的参数形

14、式,条件查询有两种:按参数位置查询和按参数名字查询。1按参数位置查询按参数位置查询时,在HQL语句中需要使用“?”来定义参数的位置。在测试类HibernateTest中添加testHql_7()方法,并使用Test注解加以修饰,按照参数位置查询的方式,查询产品名称包含“鱼”的餐品信息。语句如下:String hql = “from Meal m where m.mealName like ?“;query.setString(0, “%鱼%”); /不推荐query.setParameter(0, “%鱼%“);,14.1.7 条件查询,12,2按参数名字查询按参数名字查询时,需要在HQL语句

15、中定义命名参数,且命名参数需要以“:”开头。在测试类HibernateTest中添加testHql_8()方法,并使用Test修饰,按照参数名字查询的方式,查询产品名称包含“鱼”的产品信息。String hql = “from Meal m where m.mealName like :mname“;query.setParameter(“mname“, “%鱼%“);在HQL语句中设定查询条件,可使用如表所示各种运算。,14.1.8 连接查询,13,HQL支持各种连接查询,例如:内连接、外连接和交叉连接等。1内连接内连接是指两个表中指定的关键字相等的值才会出现在查询结果集中的一种查询方式。在

16、HQL中,使用关键字“inner join”进行内连接。在测试类HibernateTest中添加testHql_9()方法,并使用Test加以修饰,从数据表meal中查询菜系为“川菜”的餐品信息。 String hql = “from Meal as m inner join m.mealseries as ms where ms.seriesName=川菜“;HQL语句中使用inner join进行内连接,查询返回的结果并不是Meal对象(虽然from关键字后面只有Meal),而是一个对象数组,对象数组中的第一列是Meal对象,第二列是Mealseries对象。,14.1.8 连接查询,14

17、,2隐式内连接隐式内连接是指HQL语句中看不到join关键字,好像没有连接一样,但实际上已经发生内连接。在测试类HibernateTest中添加testHql_10()方法,并使用Test注解加以修饰,从数据表meal中查询菜系为“川菜”的餐品信息。String hql = “from Meal m, Mealseries ms where m.mealseries=ms and ms.seriesName=川菜“;HQL语句中没有使用内连接关键字,在where子句中m.mealseries引用了Meal对象的mealseries属性,实际上Meal与Mealseries已经发生内连接。,14

18、.1.9 子查询,15,Hibernate支持在查询中嵌套子查询,一个子查询必须放在圆括号内,HQL中子查询分为相关子查询和无关子查询。1相关子查询相关子查询是指子查询使用外层查询中的对象别名。在测试类HibernateTest中添加testHql_11()方法,并使用Test注解加以修饰,使用相关子查询检索数据表Meal中所有菜系记录数超过2的菜系。String hql = “from Mealseries ms where (select count(*) from ms.mealSet)2 “;HQL语句中,子查询中引用了外层语句中的别名“ms”,它是Mealseries类的别名。每个菜

19、系包含多个餐品记录,即在meal表中有多条餐品记录对应着mealseries表中的同一条记录,在Mealseries类中创建了Set类型的属性mealSet。,14.1.9 子查询,16,2无关子查询无关子查询是指子查询语句与外层查询语句无关。在测试类HibernateTest中添加testHql_12()方法,并使用Test加以修饰,使用无关子查询检索所有低于平均价的餐品对象。String hql=“from Meal m where m.mealPrice (select avg(m1.mealPrice) from Meal m1) “;当子查询结果为多条记录,提供了相应的关键字,见表。

20、,14.1.9 子查询,17,(1) 使用exists关键字的子查询在测试类HibernateTest中添加testHql_13()方法,并使用Test注解加以修饰,使用exists关键字检索餐品价格大于15元的菜系名称。 String hql=“from Mealseries ms where exists(select m from ms.mealSet as m where m.mealPrice15)“;(2) 使用in关键字的子查询在测试类HibernateTest中添加testHql_14()方法,并使用Test注解加以修饰,使用in关键字查询数据表meal中包含3条餐品记录的菜系

21、名称。String hql=“from Mealseries ms where 3 in(select count(m) from ms.mealSet as m) “;,14.2,使用QBC查询数据,18,14.2 使用QBC查询数据,19,QBC是Qurey By Criteria首字母缩写,Criteria是Hibernate API提供的一个查询接口,位于org.hibernate包下。Criteria查询又称为对象查询,它使用一种封装了基于字符串形式的查询语句的API来查询对象。 QBC查询主要由Criteria接口来完成,该接口由Hibernate Session创建,Criter

22、ion是Criteria的查询条件。Criteria提供了add(Criterion criterion)方法来添加查询条件。 Criterion接口的主要实现类包括Example、Junction和SimpleExpression。Example主要用来提供QBE(Qurey By Example)检索方式,是QBC的子功能。 Criterion接口的实现类一般通过Restrictions工具类来创建。使用工具类Order相关方法设置排序方式,如Order.asc表示升序,Order.desc表示降序。,14.2.1 简单查询,20,在使用HQL查询方式时,需要定义基于字符串形式的HQL语句

23、,虽然比JDBC代码有所进步,但仍然繁琐且不方便使用参数查询。Criteria采用面向对象的方式封装查询条件,Criteria API提供了查询对象的另一种方式,提供了Criteria接口、Criterion接口、Expression类,以及Restrictions类作为辅助。从而使得查询代码的编写更加方便。 使用Restrictions辅助类,进行Criteria查询的步骤如下:创建Criteria对象使用Restrictions对象编写查询条件,并将查询条件加入Criteria对象执行查询,获得结果 在测试类HibernateTest中添加testCriteria_1()方法,使用Test

24、加以修饰,使用Criteria方式从数据表meal中查询所有餐品对象。代码如下:,Testpublic void testCriteria_1()/ 创建查询所有餐品的Criteria对象Criteria c=session.createCriteria(Meal.class);/ 对查询结果按 mealName升序排序c.addOrder(Order.asc(“mealName“);/ 执行查询,获取结果List list=c.list();/ 循环输出查询结果for(Meal m : list)System.out.println(m.getMealId() + “. “ + m.getM

25、ealName();,14.2.2 分组查询,21,根据所属菜系对餐品记录进行分组,在测试类HibernateTest中添加testCriteria_2()方法,使用Test加以修饰,查询meal表中各个菜系的餐品总记录数及总金额。,/ 创建查询所有餐品的Criteria对象Criteria c=session.createCriteria(Meal.class);/ 构建ProjectionList对象ProjectionList pList=Projections.projectionList();/ 创建分组依据,按菜系进行分组pList.add(Projections.groupPro

26、perty(“mealseries“);/ 统计各分组中的记录数pList.add(Projections.rowCount();/ 统计各分组中的餐品价格总和pList.add(Projections.sum(“mealPrice“);c.setProjection(pList); / 为Criteria对象设置ProjectionList list=c.list(); / 执行查询,获取结果Iterator iterator=list.iterator(); / 遍历查询结果while(iterator.hasNext()Object obj=(Object) iterator.next(

27、);Mealseries ms=(Mealseries)obj0;System.out.println(“菜系名称:“+ ms.getSeriesName() + “tt餐品记录总数:“ +obj1+ “t价格总和:“+ obj2);,14.2.3 聚集函数,22,在测试类HibernateTest中添加testCriteria_3()方法,并使用Test注解加以修饰,使用内置聚集函数统计meal表中所有餐品价格总和、平均价格、最大价格和最小价格。,/ 创建查询所有餐品的Criteria对象Criteria c=session.createCriteria(Meal.class);/ 构建Pr

28、ojectionList对象ProjectionList pList=Projections.projectionList();/ 统计餐品价格总和pList.add(Projections.sum(“mealPrice“);/ 统计餐品平均价格pList.add(Projections.avg(“mealPrice“);/ 统计餐品最高价格pList.add(Projections.max(“mealPrice“);/ 统计餐品最低价格pList.add(Projections.min(“mealPrice“);/ 为Criteria对象设置Projectionc.setProjection

29、(pList);,14.2.4 组合查询,23,组合查询是指通过Restrictions工具类的相应方法动态构造查询条件,并将查询条件加入Criteria对象,从而实现查询功能。在测试类HibernateTest中编写testCriteria_4()方法,并使用Test注解加以修饰,按餐品名称和餐品价格查询餐品对象。Restrictions提供了大量的静态方法,来创建查询条件,如表所示。MatchMode表示匹配模式,包含的静态常量如表所示。,/ 封装查询条件Meal condition=new Meal();condition.setMealName(“虾“);condition.setMe

30、alPrice(18.00); / 创建Criteria对象Criteria c=session.createCriteria(Meal.class);/ 使用Restrictions对象编写查询条件,并将查询条件加入到Criteria对象if (condition!=null) if (condition.getMealName()!=null ,14.2.5 关联查询,24,使用Criteria并通过 Restrictions 工具类,可以实现关联查询。在测试类HibernateTest中编写testCriteria_5()方法,并使用Test注解加以修饰,实现从数据表meal中查询菜系为

31、“川菜”的餐品名称包含“鱼”的产品。,/ 创建Criteria对象Criteria mCriteria=session.createCriteria(Meal.class);/ 设置从Meal类中查询的条件mCriteria.add(Restrictions.like(“mealName“,“鱼“, MatchMode.ANYWHERE);/ 创建一个新的Criteria实例,以引用mealseries集合中的元素Criteria msCriteria=mCriteria.createCriteria(“mealseries“);/ 设置从关联的Mealseries类中查询的条件msCrite

32、ria.add(Restrictions.like(“seriesName“, “川菜“);/ 执行查询,获取结果List list=mCriteria.list();/ 循环输出查询结果for(Meal m : list)System.out.println(“餐品名称:“ + m.getMealName()+ “t价格:“ +m.getMealPrice();,14.2.6 分页查询,25,使用Criteria并通过Restrictions 工具类,可以实现分页查询。Hibernate的Criteria也提供了两个用于实现分页的方法:setFirstResult(int firstResu

33、lt)和setMaxResults(int maxResults)。其中setFirstResult(int firstResult)方法用于指定从哪个对象开始检索,默认为第一个对象(序号为0);setMaxResults(int maxResults)方法用于指定一次最多检索的对象数,默认为所有对象。 在测试类HibernateTest中添加testCriteria_6()方法,使用Test注解加以修饰。,/ 创建Criteria对象Criteria c=session.createCriteria(Meal.class);/ 从第一个对象开始查询c.setFirstResult(0);/

34、每次从查询结果中返回4个对象c.setMaxResults(4);List list=c.list();/ 循环输出查询结果for(Meal m : list)System.out.println(“餐品名称:“ + m.getMealName()+ “t价格:“ +m.getMealPrice();,14.2.7 QBE查询,26,QBE是Query By Example的缩写,QBE查询为举例查询,也称示例查询。由于QBE查询检索与指定示例对象具有相同属性值的对象,因此示例对象的创建是QBE查询的关键。示例对象中的所有非空属性都作为查询的条件。 以testCriteria_4()方法中实现

35、的组合查询为例,组合的条件越多,需要的if语句就越多,相当繁琐,此时使用QBE查询最方便。在测试类HibernateTest中编写testCriteria_7()方法,使用Test注解加以修饰,按餐品名称和餐品价格查询餐品对象。,/ 封装查询条件Meal condition=new Meal();condition.setMealName(“虾“);condition.setMealPrice(18.00); / 创建Criteria对象Criteria c=session.createCriteria(Meal.class);/使用Example工具类创建示例,将属性mealPrice排除在

36、示例查询外Example example= Example.create(condition).excludeProperty(“mealPrice“);example.ignoreCase(); / 设置不区分大小写/ 设置匹配模式为ANYWHEREexample.enableLike(MatchMode.ANYWHERE);/ 为Criteria对象指定示例对象example作为查询条件c.add(example);/ 将mealPrice作为一个额外的条件加入查询if (condition.getMealPrice()0) c.add(Restrictions.le(“mealPrice

37、“, condition.getMealPrice();,14.2.8 离线查询,27,Criteria查询是一种在线查询方式,它是通过Hibernate Session进行创建的。而DetachedCriteria查询是一种离线查询方式,创建查询时无需使用Session,可以在Session范围之外创建一个查询,并且可以使用任意的Session执行它。DetachedCriteria提供了两个静态方法:forClass(Class)和forEntityName(Name),可以通过这两个方法创建DetachedCriteria实例。 在测试类HibernateTest中添加testDetac

38、hedCriteria()方法,使用Test注解加以修饰,查询餐品名称包含“鱼”的餐品信息。,/ 创建离线查询DetachedCriteria实例DetachedCriteria query=DetachedCriteria.forClass (Meal.class).add(Property.forName(“mealName“).like(“鱼“, MatchMode.ANYWHERE);/ 执行查询,获取结果List list= query.getExecutableCriteria(session) .list();/ 循环输出查询结果for(Meal m : list)System.out.println(“餐品名称:“ + m.getMealName()+ “t价格:“ +m.getMealPrice();,总结,28,本章主要介绍了Hibernate中两个重要的查询:HQL查询和QBC查询。HQL查询时Hibernate提供的一种面向对象的查询方式,其优点在于:直接针对实体类和属性进行查询,不再编写繁琐的SQL语句,查询结果是直接保存在List中的对象,不用再次封装。QBC查询则采用面向对象的方式封装插入查询条件。,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 经营企划

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报