chapter7 Hibernate查询

本文介绍Hibernate中的HQL与Criteria查询方式,包括属性查询、参数查询、关联查询及分页查询等高级应用,帮助开发者掌握高效的数据检索技巧。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

回顾

写出下面两个类的Hibernate配置文件,注意关联的配置

预习检查

·                    Hibernate支持哪两种查询?

·                    HQL是什么?

 

本章任务

·                    使用Hibernate实现,房屋查询DAO

·                 title模糊查询

·                 对街道精确查询

·                 对租金使用一个范围查询

·                 查询特定联系人都在哪些街道发布了信息

·                 提供分页查询方法

 

本章目标

·          掌握HQL查询

·          掌握Criteria查询

 

为什么使用HQL

·          如何使用Hibernate查询所有房屋信息?

 

 

如何使用HQL

 

 

 

 

 

 

常见错误

 

属性查询

·          select fw from TblFwxxfw将查询整个对象信息,我们只想查询datetitle怎么做?

select fw.title, fw.date fromTblFwxx fw

 

 

参数查询

 

 

 

 

 

参数查询:命名参数

 

 

小结

关联查询

 

小结

·          写出HQL语句:

    查询亚运村街道的房屋信息中,涉及的房屋类型。

提示:亚运村街道的房屋信息: fw.jd.jdid=39

 

 

分页查询

·          实现分页查询方法:public List search(int pageNo, int pageSize)

 

 

统计函数

 

 

小结

 

对象查询

·          使用一个查询方法,同时支持三项功能:

·        title模糊查询

·        对房屋类型精确查询

·        对租金使用一个范围查询

public List search(TblFwxx condition){

            Stringhql = "select fw from TblFwxx fw "

            hql+= "where 1=1 ";

            if(condition.getTitle()!=null){

                        hql+= "and fw.title like '%" +

                                    condition.getTitle()+ "%' ";

            }

            ...

}

 

 

使用Criteria查询

 

 

 

 

 

总结

·                    HQL的全称是?

·                    SQL相比,HQL有哪些特点?

·                    HQL语句为:select jd.jdid,jd.jd from TblJd jd。怎样获得并显示查询结果?

·                    使用'?'做占位符的参数查询,怎样设置参数的值?

·                    命名参数查询的语法是?

·                    怎样创建Criteria查询对象?

 

Hibernate对象条件查询:

查询通过如下三个类获取:

l Criteria  代表一次查询

l Criterion 代表一个查询条件

l Restrictions 产生查询条件的工具类

 

执行条件查询的步骤:

(1)   获得Hibernate的Session对象

(2)   以Session对象创建Criteria对象

(3)   使用Restrictions的静态方法创建Criterion查询条件

(4)   向Criteria查询中添加Criterion查询条件

(5)   执行Criteria的list等方法返回结果集

 

投影、聚合和分组

投影运算实际上是一种基于列的运算,通常用于投影到指定列(也就是过滤其他列,类似select子句的作用),还可以完成SQL语句中常用的分组、组筛选等功能。

 

Hibernate的条件过滤中使用Projection代表投影运算,Projection是一个接口,而Projections作为Projection的工厂,负责生成Projection对象。

 

Projections类提供了几个静态方法:

¨    avg(String propertyName) : 计算特定属性的平均值,类似于avg函数

¨    count(StringpropertyName) : 统计查询结果在某列上的记录条数。类似于count(column)函数

¨    countDistinct(StringpropertyName) : 统计查询结果在某列上不重复的记录条数。类似于count(distinctcolumn)函数。

¨    groupProperty(StringpropertyName) : 将查询结果按某列上的值进行分组。类似于添加groupby 子句。

¨    max(String propertyName) : 统计查询结果在某列上的最大值。类似于max函数。

¨    min(String propertyName) : 统计查询结果在某列上的最小值。类似于min函数。

¨    rowCount(): 统计查询结果的记录条数。类似于count(*)的功能。

¨    sum(String propertyName) : 统计查询结果在某列上的总和。类似于sum函数。

 

/**   *分组查询方法   *   */  publicvoid searchFwxxGroup(){   List list = new ArrayList();   Session session  = HibernateSessionFactory.getSession();   //创建查询对象   Criteria c = session.createCriteria(Fwxx.class);   c.setProjection(     Projections.projectionList() //添加投影条件     //统计记录行数     .add(Projections.rowCount())     //jdid分组     .add(Projections.groupProperty("tblJd"))   );   list = c.list();      for (Object object : list) {    Object[] objs =(Object[])object; //集合中每一个元素为object数据    System.out.println("行数:"+objs[0]); //前面的元素都是聚合函数的结果值    Jd jd = (Jd)objs[1];  //最后一个元素才是返回的查询对象    System.out.println("街道分组:"+jd.getJd());   }      session.close();  }

 

 

 

 

 

/**   *查询对象某个属性集合   *   */  publicvoid searchFwxxProperty(){   List list = new ArrayList();   Session session  = HibernateSessionFactory.getSession();   //创建查询对象   Criteria c = session.createCriteria(Fwxx.class);   c.setProjection(     Property.forName("title") //过滤只筛选出title属性不再返回整个Fwxx对象   );   list = c.list();   for (Object object : list) {    System.out.println(object);   }   session.close();  }

 

 

 

SQL查询

Hibernate支持使用原生SQL查询。SQL查询是通过SQL Query接口来表示的。SQLQuery是Query接口的子接口,因此完全可以调用Query接口的方法,但SQLQuery比Query多了如下两个重载方法

addEntity() : 将查询到的记录与特定实体关联

addScalar() : 将查询的记录关联成标量值

 

执行SQL查询的步骤:

(1)   获取Hibernate Session对象

(2)   编写SQL语句

(3)   以SQL语句作为参数,调用Session的createSQLQuery方法创建查询对象

(4)   调用SQLQuery对象的addScalar()或addEntity()方法将选出的结果与标量值或实体进行关联,分别用于进行标量查询或实体查询。

(5)   如果SQL语句包含参数,则调用Query的setXXX方法为参数赋值

(6)   调用Query的list方法返回查询结果集

 

标量查询

最基本的SQL查询就是获得一个标量(数值)的列表。如

List list =HibernateSessionFactory.getSession()

                                                            .createSQLQuery("select* from tbl_fwxx").list();

默认情况下,查询语句将返回的Object数组组成的list,数组每个元素都是fwxx表的列值。Hibernate会通过ResultSetMetadata来判定返回数据列的实际顺序和类型。

PS:如果select后面只有一个字段,那么返回的list集合元素就不是数组,而只是单个的变量值。

publicvoid sqlSearch(){   List list = HibernateSessionFactory.getSession()      //创建sql查询,查询fwxx表中所有记录      .createSQLQuery("select * from tbl_fwxx")      //只过滤出title列和fwid列,并指定类型  .addScalar("title",TypeFactory.basic("String"))  .addScalar("fwid",TypeFactory.basic("Integer"))      .list();   for (Object object : list) {    Object[] objs = (Object[])object;    //返回的数组中,第一个元素为title,第二个元素为fwid    System.out.println(objs[0]+"\t"+objs[1]);   }  }

 

 

实体查询

如果查询返回了某个数据表的全部数据列,且该数据表有对应的持久化类映射,我们就可把查询结果转换成实体查询。

publicvoid sqlSearchWithEntity(){   List list = HibernateSessionFactory.getSession()      //创建sql查询,查询fwxx表中所有列      .createSQLQuery("select * from tbl_fwxx where uid = :uid")      .addEntity(Fwxx.class) //指定所关联的实体      .setInteger("uid", 56) //设置参数      .list();   for (Object object : list) {    Fwxx fw = (Fwxx)object;  System.out.println(fw.getFwid()+"\t"+fw.getTitle());   }  }

 

 

调用存储过程

从Hibernate3开始,Hibernate可以通过命名SQL查询来调用存储过程。

1、在hbm.xml的映射文件中添加一个命名查询配置

<sql-query name="callQx" callable="true">          <return class="entity.Qx" alias="Q">           <return-property name="qxid" column="qxid"></return-property>           <return-property name="qx" column="qx"></return-property>          </return>          { call proc_selectQx()}     </sql-query>

 

2、编写代码读取命名查询

Session session = HibernateSessionFactory.getSession();   Transaction tx = session.beginTransaction();   List list = session      .getNamedQuery("callQx").list();   tx.commit();   session.close();   for (Object object : list) {    Qx qx = (Qx)object;  System.out.println(qx.getQxid()+"\t"+qx.getQx());   }

 

 

总结

       1.使用HQL的四步

Session session =HibernateDao.newInstance().getSession();     获取session 相当于获取connection

String hql = "from FWXX";  String hql = "select fw from FWXXfw";    编写hql语句相当于SQL语句前面简单后面是通过别名的形式

Query query =session.createQuery(hql);  创建Query对象相当于statement对象

List<FWXX> list = query.list();   执行查询list集合接收数据相当于ResultSet,不过把数据封装成了List集合

      

       2.如果只查询表中的几个列的数据

 

       3.迭代器,只查询几列的值,先封装成数组,多少列对应多少个元素,如果只有一个列,则只用一个Object对象接收

Iterator<FWXX> it = list.iterator();

while(it.hasNext())

{

FWXX fw = it.next();

System.out.println(fw.getTitle());

}

Iterator it = list.iterator();

while(it.hasNext())

{

       Object[]arr = (Object[])it.next();

       System.out.println(arr[0]+ "/t" +  arr[1]);

}

 

       4.hql查询设置

String hql = "select fw.jdid,fw.uidfrom FWXX fw where fw.jdid like ?";setString(0,?);

支持>< = >= <= <> is null;andornot和括号inbetween

1. 必须保证:query设置参数的数目  == hql语句中占位符的数目

2. 占位符下标从 0 开始。

String hql = "select fw.jdid,fw.uidfrom FWXX fw where fw.jdid like :Z1";

query.setString("Z1","%2%");

String hql = "select fw from TblFwxxfw "hql += "where 1=1 ";这样写,后面所有的都可以加上and条件

 

 

       5.多表查询先把所有表写上再找关系

select lx.fwlx fromTBL_JD jd,TBL_FWXX xx,TBL_FWLX lx where jd.jd = '亚运村'

 

       6.如果是聚合函数需要用uniqueResult来接收

int count =Integer.valueOf(query.uniqueResult().toString());

 

       7.分页查询设置setFirstResultsetMaxResults来处理缺点就多的话占资源多。

int size = 3;

int page = 1;

int firstResultIndex = size*(page-1);

query.setFirstResult(firstResultIndex);

query.setMaxResults(size);

List<FWXX> list = query.list();

 

       8.对象查询Criteria 对象

Criteria c =session.createCriteria(FWXX.class);       //创建Criteria 对象

if(fw.getTitle()!=null)

{c.add(Restrictions.like("title",fw.getTitle(),MatchMode.ANYWHERE));}   //增加排除条件,le大于或者等于ge小于或者等于,c.addOrder(Order.asc("fwlx.lxid"));增加排序条件支持EL表达式获取对象的值c.add(Restrictions.in("fwlx.lxid",aa));其中aaobject的数组

List<FWXX> list = c.list();       //获取值

 

       9.sql查询记得要跟实体挂钩.addEntity

String hql = "select * from PetInfo pii order by (pii.pet_cute + pii.pet_strength + pii.pet_love) desc";

Query query =session.createSQLQuery(hql).addEntity(PetInfo.class);

list =query.list();

 

                10.用耦合方式存session可能有问题在首页显示图书尽量用解耦的方式

//          HttpSession session =ServletActionContext.getRequest().getSession();

//          session.setAttribute("bookLists",ListHelp.changeTitle(list));

            Map map = ActionContext.getContext().getSession();

            map.put("bookLists", ListHelp.changeTitle(list));

 

 

 

 

 


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值