• Hibernate之HQL


    SQL语句的DML操作不外乎:增,删,改,查

    增加 :  save(),persist()

    删除 :   delete()

    改动 :   update()

    查询  :  get() ,load()

    其中的查询操作,作为最为常用的语句,又可以分为很多种情况。通过get()和load()方式,我们仅仅可以指定类型,和id获得一条记录。

    当我们需要根据进行条件查询时来获得多条记录时,就不能再使用get(),和load()方式。

    Hibernate提供了很强大的查询体系:HQL查询,条件查询,原生SQL查询

    1.HQL查询 

    HQL(Hibernate Query Language)即Hibernate查询语句。Hibernate的语法很像SQL的语法,也可以说事SQL语句的转化。

    我们知道SQL语言的操作对象是数据表,列等数据库对象,而HQL语句则是把SQL语句中的数据表替换为持久化类,列替换为属性。

    这样HQL就变成了面向对象的查询语言,它可以支持继承,多态等特性。

    HQL查询 主要依赖的是Query类,每个Query类的实例对应一个查询对象。Query类的实例对象可以通过session.createQuery(Sting Hql)来获得。最基本的例子如下:

    @Test
        public  void testHQL(){
            
            String  hql = "select p.name , p.age from  Person p where id = 99";      // HQL语句,name,age,id是Person类实例对象p的属性
            
            Query query = session.createQuery(hql);     //获得查询对象       
            Person p = (Person) query.uniqueResult();   //明确知道查询得到的记录只有一条,用uniqueResult()方法
            
            System.out.println("查询得到的对象是:"+ p);
        }

    为HQL语句绑定参数:

    上面的例子中id=99是静态写死在HQL语句中,但是实际的开发中,常常是根据传进来的参数来查询,静态写死就不灵活了。有两种方法文HQL绑定参数:

    第一种:使用 ? 占位符

      两点注意:?占位符的索引从1开始,根据属性的类型来选择setXxxx()方法。

    
    
    @Test
        public  void testHQL(){
            
            String  hql = "select p.name , p.age from  Person p where p.id = ? and  p.birthday = ?";      // HQL语句,name,age,id,birthday是Person类实例对象p的属性
            
            Query query = session.createQuery(hql);     //获得查询对象
            
            query.setInteger(1,99);        
            query.setDate(2,new Date())
            Person p = (Person) query.uniqueResult();   //明确知道查询得到的记录只有一条,用uniqueResult()方法
            
            System.out.println("查询得到的对象是:"+ p);
        }
    
    

     第二种:命名参数进行绑定    

      格式为   :参数名      设值时根据参数名 进行设值

    @Test
        public  void testHQL(){
            
            String  hql = "select p.name , p.age from  Person p where p.id = :id  and  p.birthday = :birthday";      // HQL语句,name,age,id,birthday是Person类实例对象p的属性
            
            Query query = session.createQuery(hql);     //获得查询对象
            
            query.setInteger("id",99);        
            query.setDate("birthday",new Date())
            Person p = (Person) query.uniqueResult();   //明确知道查询得到的记录只有一条,用uniqueResult()方法
            
            System.out.println("查询得到的对象是:"+ p);
        }

    得到查询结果集:

    如果 查询的结果是唯一的一条记录,可以调用uniqueResult();    但是当查询的结果是多条记录时,可以使用两个方法来遍历每条记录:

    list()方法

    @Test
        public  void testHQL(){
            
            String  hql = "select p.name , p.age from  Person p where  p.birthday > :birthday";      // HQL语句,name,age,id,birthday是Person类实例对象p的属性
            
            Query query = session.createQuery(hql);     //获得查询对象
            
            query.setDate("birthday",new Date())
            List<Person>  list =  query.list();     //将查询后的结果转化为list集合      
            for(Person p : list)                      //遍历list集合
             {
                System.out.println("Person实例对象--" + p);
             }     
        }

    iterate()方法

    @Test
        public  void testHQL(){
            
            String  hql = "select p.name , p.age from  Person p where  p.birthday > :birthday";      // HQL语句,name,age,id,birthday是Person类实例对象p的属性
            
            Query query = session.createQuery(hql);     //获得查询对象
            
            query.setDate("birthday",new Date())
            Iterator<Person> iterator = query.iterate();   ////将查询后的结果转化为list集合,然后拿到迭代器对象 
            while(iterator.hasNext())
            {
                Person  p = iterator.next()
                System.out.println("Person-----" + p);
            } 
       }

    这两个方法之间的区别是:

    list()方式是立即查询  即会立刻发送一条SQL语句将查询的结果集封装在list集合中      ;   list()方法支持一级缓存(session缓存)的写入  不支持读出(就是无论如何都会发SQL语句去查)

    iterate()方法是延迟查询  当需要使用某一条查询结果记录时,才发送一条SQL语句,取得这条查询记录   ;  iterate()方法支持一级缓存(session缓存)的写入  支持读出(先看缓存有没有,有就不发SQL,没有再发SQL)

    根据上面的HQL语句 可知,SQL语句是按照一条记录一条记录这样的形式来查,HQL语句是按照一个实例对象一个实例对象这样的形式来查。

    由于HQL语句中不允许出现*号   所以 select  *  from   tb_person的对应HQL可以写为  select  p.id ,p.name,p.age from Person p ;(列举出所有实例对象p的属性) 

    也可以简写为  from  Person p;

    HQL语句还可以结合 where子句做更为复杂的查询 ,其语法格式类似于SQL语句。

    HQL语句也可以做增加,删除,更新的DML操作。   这些操作都涉及到SQL相关知识,这里不再详细叙述。

    命名HQL查询:

    命名HQL查询 的本质就是把 HQL语句从java代码中取出来,放到配置文件中进行管理,并为这条HQL语句起一个名字,以便在java代码中获取这条HQL语句。

    hql.xml配置文件  (名字随意)

    <query  name="query1">
         select  p.id , p.name  from  Person p;
    </query>

    还需要在hibernate.cfg.xml配置文件中引入hql.xml配置文件

    <mapping resource="org/fkjava/test/hql.xml"/>

    java代码:

     @Test
        public  void testHQL(){
            
            Query query = session.getNamedQuery("query1");   //根据hql名称 ,加载hql语句,得到query对象
            
            List<Person> list = query.list();   //得到查询结果集的list集合
        }
  • 相关阅读:
    iOS开发多线程篇—创建线程
    【C语言】23-typedef
    李洪强经典面试题10
    李洪强经典面试题9
    李洪强经典面试题8
    李洪强经典面试题7
    多态性
    Oracle exp使用正則表達式导出部分表
    Android NDK开发初步
    HDU1864 最大报销额 01背包
  • 原文地址:https://www.cnblogs.com/wangliyue/p/4164261.html
Copyright © 2020-2023  润新知