【Hibernate】hql小结

来源:互联网 发布:java创建日志文件 编辑:程序博客网 时间:2024/06/07 06:22

一、Hql是什么?

    数据查询与检索是Hibernate中的一个亮点,相对于其他ORM实现而言,Hibernate提供了灵活多样的查询机制。Hibernate Query Language简称为hql,它是Hibernate的一种以对象的方式进行查询的机制,将查询语句封装为对象操作,同时Hibernate官方推荐使用hql进行查询。

    同时,这里有几个概念:

   (1)Native SQL Queriers (原生SQL查询):直接使用标准SQL语言或者跟特定数据库相关的SQL进行查询。

   (2)Criteria Query (标准化对象查询):以对象的形式进行查询,将查询语句封装为对象操作。

    结合以上二者,对Hql进行理解。


二、Hql特点

    由于hql可以视为一种CQ,通过在hbm.xml和实体之间的配置关联,hql具有以下特点:

   (1)可读性好,复合java面向对象的编程习惯。

   (2)以类和属性来代替表和数据列

   (3)支持多态、支持各种关联、减少了SQL的冗余

   (4)支持所有的关系数据库操作:连接、投影、聚合、排序、子查询、SQL函数

    ---------------------------------------------------------------------

   (5)没有SQL语句功能强大

   (6)书写方便,但是对于菜鸟学习原生sql没有太大帮助


三、Hql具体功能实现

    如图:

                   

      前提:

   hql语句是结合着Session session = HibernateUtils.getSession();为前提进行的操作


   1、属性查询

   这也是最初级的hql功能:

public void testQuery1() {Session session = null;try {session = HibernateUtils.getSession();session.beginTransaction();//返回结果集属性列表,元素类型和实体类中的属性类型一致//List当中存放的是一个name的集合List students = session.createQuery("select name from Student").list();for (Iterator iter=students.iterator(); iter.hasNext();) {String name = (String)iter.next();System.out.println(name);}session.getTransaction().commit();}catch(Exception e) {e.printStackTrace();session.getTransaction().rollback();}finally {HibernateUtils.closeSession(session);}}
       这句“session.createQuery("select name from Student")”.list();中两个特点:

   (1)建议createQuery()点进去看看都是啥

   (2)createQuery方法后".list()"转化为集合,因为使用hql最终得到的是一个对象实体的集合

   (3)createQuery方法中“from”后跟的是一个实体对象。

    当然,除了单一属性之外,查询多属性,“select new Student(id,name) from Student”.list中new Student(id,name)是固定的写法。注意:多属性查询,select * 是个大忌。

    此外,有两种对别名的写法:

   “select s.id, s.name from Student s”以及“select s.id, s.name from Student as s

            

   2、实体对象查询

//返回Student对象的集合//可以忽select关键字List students = session.createQuery("from Student").list();for (Iterator iter=students.iterator(); iter.hasNext();) {Student student = (Student)iter.next();System.out.println(student.getName());}
        初级程序员,注意迭代的代码写法。

List students = session.createQuery("from Student s").list();
List students = session.createQuery("from Student as s").list();
           使用别名的两种写法,同时查询对象如果使用select语句,不能写成“select * from Student s”,而是“select s from Student s”.算是hibernate的特性之一吧。


    3、条件查询

    对应着sql语句中的where条件,在hibernate中的条件查询可以写成类似形式:

   (1)拼串

List students = session.createQuery("select s.id, s.name from Student s where s.name like '%0%'").list();
        (2)使用“?”传递参数

    方式一:

List students = session.createQuery("select s.id, s.name from Student s where s.name like ?").list();
          方式二:

Query query  = session.createQuery("select s.id, s.name from Student s where s.name like ?");query.setParameter(0, "%0%");List students = query.list();
         最终无论是方法一还是方法二,都是转化为.list形式;方式二而且转化为了方法链的形式,进行查询, 可以添加多个查询条件。

   (3)使用“:”传递参数

List students = session.createQuery("select s.id, s.name from Student s where s.name like :myname").setParameter("myname",  "%0%").list();
      对比使用“:”和“?”,查询学号分别为“1,2,3,4,5”的学生

    1、“?”

List students = session.createQuery("select s.id, s.name from Student s where s.id in(?, ?, ?, ?, ?)").setParameter(0, 1).setParameter(1, 2).setParameter(2, 3).setParameter(3, 4).setParameter(4, 5).list();

       2、":"
List students = session.createQuery("select s.id, s.name from Student s where s.id in(:ids)").setParameterList("ids", new Object[]{1, 2, 3, 4, 5}).list();
        可见,后者写法简介,而且扩展性会更好一点。


    4、过滤器查询

    hbm.xml中配置过滤器如下:

<filter-def name="testFilter"><filter-param type="integer" name="myid"/></filter-def>
         <class>标签中添加filter子属性

<class name="com.bjpowernode.hibernate.Student" table="t_student"><id name="id"><generator class="native"/></id><property name="name"/><property name="createTime"/><many-to-one name="classes" column="classesid"/><filter name="testFilter" condition="id < :myid"></filter>   //其中“<”是个转义符,原意是“<”,相当于是填写了过滤器的条件</class>
      后台代码操作:查询出的"from Student"结果,都是myid小于10的结果
session.enableFilter("testFilter") //启用过滤器,并设置了过滤器中id<的值为10.setParameter("myid", 10);List students = session.createQuery("from Student").list();  //查询时,遵循过滤器的设置,查询条件默认添加“where id < '10'”for (Iterator iter=students.iterator(); iter.hasNext();) {Student student = (Student)iter.next();System.out.println(student.getName());}

        5、分页查询

   两个属性:setFirstResult(),setMaxResult()

session = HibernateUtils.getSession();session.beginTransaction();List students = session.createQuery("from student").setFirstResult(1)  //从1开始.setMaxResults(2)   //每页显示2个.list();session.getTransaction().commit();
         这样,查询id从1开始,每页显示2条结果。

   6、对象导航查询

   查询班级名称等于某个值的所有学生
   前提:student类和class类是对应的两个实体,class中的主键充当student中的外键:
session = HibernateUtils.getSession();session.beginTransaction();List students = session.createQuery("from student s where s.classes.name like '%2%'").setFirstResult(1).setMaxResults(2).list();

      7、连接查询

    如同在sql中的链接查询一样, 下面片段分别演示:内连接、左连接、右连接

//join连接,此时严格满足s和c之间的关联,List students = session.createQuery("select c.name, s.name from student s join s.classes c").list();for(Iterator iter = students.iterator();iter.hasNext();){//obj[0]为studentName,obj[1]为classNameObject[] obj = (Object[])iter.next();System.out.println(obj[0] + ", " + obj[1]);}//join左连接,查询出所有的学生,去匹配学生的班级List studentsLeft = session.createQuery("select c.name, s.name from student s left join s.classes c").list();for(Iterator iter = studentsLeft.iterator(); iter.hasNext();){Object[] obj = (Object[])iter.next();System.out.println(obj[0] + ", " + obj[1]);}//join右连接,查询出所有班级,然后匹配班级的学生List studentsRight = session.createQuery("select c.name, s.name from student s right join s.classes c").list();for(Iterator iter = studentsRight.iterator(); iter.hasNext();){Object[] obj = (Object[])iter.next();System.out.println(obj[0] + ", " + obj[1]);}
    

        如上,就是初次接触hql的学习,同时总结了一些常用的hql语句。

   That's all.


0 0
原创粉丝点击