• 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();
    }
    }
    }




  • 相关阅读:
    【Flutter学习】之绘画实例(二)
    【Flutter学习】之绘画实例(一)
    【Flutter学习】之动画实现原理浅析(三)
    【Flutter学习】之动画实现原理浅析(二)
    NopCommerce支持多种类型的数据库
    NopCommerce 多数据库方案
    开发程序需要注意的点
    基于SVN的项目管理——集中与分散
    JS代码优化小技巧
    开发日记:中控PUSH协议
  • 原文地址:https://www.cnblogs.com/kangsir/p/6653250.html
Copyright © 2020-2023  润新知