zoukankan      html  css  js  c++  java
  • Hibernate中的HQL语言

    一、HQL语言简介
    HQL全称是Hibernate Query Language,它提供了是十分强大的功能,它是针对持久化对象,直接取得对象,而不进行update,delete和insert等操作。而且HQL是面向对象的,具备继承,多态和关联等特性。
    HQL的语法类似于SQL,其常用的方法如下:
    [select|update|delete 子句] [from 类名列表] [where 子句] [group by 子句] [order by 子句]

    [select|update|delete 子句]用于查询,更新和删除。

    [from 类名列表]指定查询的持久化类所在的的数据表名。
    [where 子句]给出查询的条件。
    [group by 子句]用于对数据进行分组。
    [order by 子句]对查询结果进行排序。

    注意:除了Java类与属性的名称外,HQL查询语句对大小写并不敏感。 所以 SeLeCT 与 sELEct 以及 SELECT 是相同的,但是 org.hibernate.eg.FOO 并不等价于 org.hibernate.eg.Foo 并且 foo.barSet 也不等价于 foo.BARSET。 


    二、HQL语法详解
    -----[select|update|delete]--------
    select关键词后跟的是需要返回的对象或者对象属性,且属性必须属于from子句中给出的类列表。使用select可以直接存入一个List对象或直接封装为一个对象。
    使用示例:
    1、查询具体属性
    select stu.cores.english from Student as stu;
    上述语句查询出学生的英语成绩
    2、查询并放入List对象
    select new List(stu.id,stu.name) from Student as stu;
    查询了学生的学号和名字,放入一个List中
    3、查询并生成对象
    select new Student(stu.id,stu.name) from Student as stu;
    查询了学生的学号和名字,并生成一个Student对象。使用前提:Student类中存在相应的构造方法。
    4、查询所有属性
    from Student
    多数情况下,我们可以为查询的实体对象指定一个别名,方便在其他地方引用。
    from Student as stu

    update和delete是Hibernate3新加入的特性。这样我们更新数据库就有两种方式。
    1、先修改持久化对象的值,之后提交事务更新数据。
    2、使用HQL语句实现。不过不推荐这种方式。


    ---------from子句-----------
    from子句是最简单的HQL,例如from Student,也可以写成 select s from Student s。它简单的返回Student类的所有实例。


    ---------where子句----------
    HQL也支持子查询,它通过where子句实现这一机制。where子句可以让用户缩小要返回的实例的列表范围。例如下面语句会返回所有名字为"kang"的Student实例:
    Query query = session.createQuery("from Student as stu where stu.name='kang'");
    1、where子句允许出现的表达式
    数学操作:+,-,*,/
    真假比较操作:=, >=, <=, <>, !=, like
    逻辑操作:and ,or, not
    字符串连接:||
    SQL标题函数 :如upper()和lower()
    2、如果查询返回多条记录,可以用以下关键字来量化
    all:表示所有的记录。
    any:表示所有记录中的任意一条。
    some:与any相同。
    in:与any等价。
    exists:表示子查询至少要返回一条记录。
    查询示例:
    返回所有学生年龄都大于18的班级对象
    from Group g where 18<all  (select s.age from g.students s)
    返回在所有学生中有一个学生的年龄等于22的班级:
    from Group g where 22 = any (select s.age from g.students s)
    或者
    from Group g where 22= some(select s.age from g.students s)
    或者
    from Group g where 22 in (select s.age from g.students s)
     

    -----------Group by子句--------------
    在HQL语句中同样支持使用group by子句分组查询,还支持group by子句结合聚集函数的分组统计查询,大部分标准的SQL聚集函数都可以在HQL语句中使用,比如:
    count(),sum(),max(),min(),avg()等。(前提是数据库支持having语句,例如mysql不支持)
    count():统计记录条数。
    min():求最小值。
    max():求最大值。
    sum():求和。
    avg():求平均值。
    例如,要取得Student实例的数量,可以编写如下HQL语句:
    select count(*) from Student
    取得Student平均年龄的HQL语句:
    select avg(s.age) from Student as s
    可以使用distinct去除重复的数据:
    select distinct s.age from Student as s
    如下面的程序代码:
    String hql=”select count(user),user.age from User user group by user.age having count(user)>10 ”;//mysql不行
    List list=session.createQuery(hql).list();



    --------------order by子句------------
    查询返回列表可以按照任何返回的类或者组件的属性排序,asc为正序排列(从小到大),desc为降序排列(从大到小)
    按照学生的学号正序排列
    from Studen as stu order by stu.id asc



    ---------------联合查询--------------
    与SQL一样,HQL也支持连接查询,如内连接,外连接和交叉连接:
    inner join:内连接
    left outer join:左外连接
    rigth outer join:右外连接
    full join:全连接,但不常用
    下面重点介绍下内连接查询,左外连接和或右外连接和内连接大同小异,而全连接几乎没有使用得到的地方。
    inner join可以简写为join,例如在查询得到的Group对象时,内连接取得对应的Student对象,实现的程序代码如下:
     
    Student stu = null;
            Group group = null;
            Query query = session.createQuery("from Group g join g.students");
            List list = query.list();
            Object obj[] = null;
            for(int i = 0 ; i < list.size(); i++)
            {
                obj = (Object[])list.get(i);
                group = (Group)obj[0];//group是数组是第一个对象
                stu = (Student)obj[1];//stu是数组的第二个对象
                System.out.println(stu.getName()+"属于"+group.getName());
            }
    




    ---------------子查询---------------
    对于支持子查询的数据库,Hibernate支持在查询中使用子查询。一个子查询必须被圆括号包围起来(经常是SQL聚集函数的圆括号)。 甚至相互关联的子查询(引用到外部查询中的别名的子查询)也是允许的。 
    from Cat as fatcat where fatcat.weight > (select avg(cat.weight) from DomesticCat cat)



    ---------------参数绑定--------------
    Hibernate中对动态查询参数绑定提供了丰富的支持,那么什么是查询参数动态绑定呢?其实如果我们熟悉传统JDBC编程的话,我们就不难理解查询参数动态绑定,
    如下代码传统JDBC的参数绑定:
    PrepareStatement pre=connection.prepare(“select * from User where user.name=?”);
    pre.setString(1,”xiaokang”);
    ResultSet rs=pre.executeQuery();
    在Hibernate中也提供了类似这种的查询参数绑定功能,而且在Hibernate中对这个功能还提供了比传统JDBC操作丰富的多的特性,在Hibernate中共存在4种参数绑
    定的方式,下面我们将分别介绍:
    1、按参数名称绑定:
     在HQL语句中定义命名参数要用”:参数名”的形式,形式如下:
     Query query=session.createQuery(“from User user where user.name=:customername and user.customerage=:age ”);
     query.setString(“customername”,name);
     query.setInteger(“customerage”,age);
    上面代码中用:customername和:customerage分别定义了命名参数customername和customerage,然后用Query接口的setXXX()方法设定名参数值,setXXX()方法包
    含两个参数,分别是命名参数名称和命名参数实际值。


    2、按参数位置邦定:
    在HQL查询语句中用”?”来定义参数位置,形式如下:
    Query query=session.createQuery(“from User user where user.name=? and user.age =? ”);
    query.setString(0,name);
    query.setInteger(1,age);
    同样使用setXXX()方法设定绑定参数,只不过这时setXXX()方法的第一个参数代表邦定参数在HQL语句中出现的位置编号(由0开始编号),第二个参数仍然代表参数实际值。
    注:在实际开发中,提倡使用按名称邦定命名参数,因为这不但可以提供非常好的程序可读性,而且也提高了程序的易维护性,因为当查询参数的位置发生改变时,按名称邦定名参数的方式中是不需要调整程序代码的。


    3、setParameter()方法:
    在Hibernate的HQL查询中可以通过setParameter()方法邦定任意类型的参数,如下代码:
     String hql=”from User user where user.name=:customername ”;
     Query query=session.createQuery(hql);
     query.setParameter(“customername”,name,Hibernate.STRING);
    如上面代码所示,setParameter()方法包含三个参数,分别是命名参数名称,命名参数实际值,以及命名参数映射类型。对于某些参数类型setParameter()方法可以更具参数值的Java类型,猜测出对应的映射类型,因此这时不需要显示写出映射类型,像上面的例子,可以直接这样写:
    query.setParameter(“customername”,name);但是对于一些类型就必须写明映射类型,比如java.util.Date类型,因为它会对应Hibernate的多种映射类型,比如
    Hibernate.DATA或者Hibernate.TIMESTAMP。


    4、setProperties()方法:
    在Hibernate中可以使用setProperties()方法,将命名参数与一个对象的属性值绑定在一起,如下程序代码:

    Customer customer=new Customer();
    customer.setName(“pansl”);
    customer.setAge(80);
    Query query=session.createQuery(“from Customer c where c.name=:name and c.age=:age ”);
    query.setProperties(customer);


    setProperties()方法会自动将customer对象实例的属性值匹配到命名参数上,但是要求命名参数名称必须要与实体对象相应的属性同名。
    这里还有一个特殊的setEntity()方法,它会把命名参数与一个持久化对象相关联,如下面代码所示:
    Customer customer=(Customer)session.load(Customer.class,”1”);
    Query query=session.createQuery(“from Order order where order.customer=:customer ”);
    query. setProperties(“customer”,customer);
    List list=query.list();


    上面的代码会生成类似如下的SQL语句:
    Select * from order where customer_ID=’1’;



    三、如何使用HQL语句
    HQL查询依赖于Query类,每个Query实例对应一个查询对象,使用HQL查询按如下步骤进行:
    1.获取Hibernate Session对象
    2.编写HQL语句
    3.以HQL语句作为参数,调用Session的createQuery方法创建查询对象
    4.如果HQL语句包含参数,则调用Query的setXxx方法为参数赋值
    5.调用Query独享的list()或uniqueResult()方法返回查询结果列表
    例如:

    Session s = null;
    try{
    s = HibernateUtil.getSession();//获取session,前提HibernateUtil中有一个静态方法getSession
    String hql = "from Test as test where test.name=?";
    Query query = s.createQuery(hql);//创建Query对象
    query.setString(0,name);//设置参数
    List list = query.list();//查询结果
    for(Test test:list){//遍历
    System.out.println(test.getName());
    }
    }finally{
    //finally表示数据库一定要被关闭
    if(s!=null)
    s.close();
    }
    }
    }




  • 相关阅读:
    Azure PowerShell (7) 使用CSV文件批量设置Virtual Machine Endpoint
    Windows Azure Cloud Service (39) 如何将现有Web应用迁移到Azure PaaS平台
    Azure China (7) 使用WebMetrix将Web Site发布至Azure China
    Microsoft Azure News(4) Azure新D系列虚拟机上线
    Windows Azure Cloud Service (38) 微软IaaS与PaaS比较
    Windows Azure Cloud Service (37) 浅谈Cloud Service
    Azure PowerShell (6) 设置单个Virtual Machine Endpoint
    Azure PowerShell (5) 使用Azure PowerShell创建简单的Azure虚拟机和Linux虚拟机
    功能代码(1)---通过Jquery来处理复选框
    案例1.用Ajax实现用户名的校验
  • 原文地址:https://www.cnblogs.com/kangsir/p/6653250.html
Copyright © 2011-2022 走看看