当前位置: 代码迷 >> Web前端 >> hibernate查询(2)
  详细解决方案

hibernate查询(2)

热度:456   发布时间:2012-09-22 21:54:54.0
hibernate查询(二)

  Hibernate query language。hql查询中关键字不区分大小写,但是类和属性都是区分大小写的。

  1.简单属性查询。

  单一属性查询,返回属性结果集列表,元素类型和实体类的相应的类型一致。

 
List students = session.createQuery("select name from Student").list();  
  1.   
  2. for (Iterator iter=students.iterator(); iter.hasNext();) {  
  3.   
  4. String name = (String)iter.next();  
  5.   
  6. System.out.println(name);  
  7.   
  8. }  


 

 //返回结果集属性列表,元素类型和实体类中的属性类型一致

多个属性查询,多个属性查询返回数组对象,对象数组的长度取决于属性的个数,对象数组中的元素类型与实体类中属性一致。

[java] view plaincopyprint?
  1. List students = session.createQuery("select id, name from Student").list();  
  2.   
  3. for (Iterator iter=students.iterator(); iter.hasNext();) {  
  4.   
  5. Object[] obj = (Object[])iter.next();  
  6.   
  7. System.out.println(obj[0] + ", " + obj[1]);  
  8.   
  9. }  


 

2.实体对象查询

List students = session.createQuery("from Student").list();

当然这种hql语句,可以使用别名,as可以省去,如:from Student as s,若是使用select关键字,则必须使用别名。如:select s from Student as s.但是不支持select * from Student格式。

查询中使用list和Iterate区别:

list查询是直接运行查询的结果,所以只有一句sql语句。而iterate方法则有可能会产生N+1条sql语句。这是怎么回事呢?要理解N+1条语句,首先得弄明白iterate是如何执行查询的?

首先发出一条查询对象ID的语句,然后根据对象的ID到缓存(缓存的概念上篇博客已经提到)中查找,若是存在查询出此对象的其他的属性,否则会发出N条语句,此时的N语句,是刚才第一次查询的记录条数。这种现象就是N+1sql语句。

其中list是默认情况下都发出sql语句,查询出的结果会放到缓存中,但是它不会利用缓存,即使放进去,下次执行时,仍然继续发出sql语句。

而:iterate默认情况下会利用缓存,若是缓存中有则不会发出N+1条语句。

3.条件查询。

这种方式就是传入参数,使用参数占位符“?”。也可以使用“:参数名”

java代码如下:

[java] view plaincopyprint?
  1. List students = session.createQuery("select s.id, s.name from Student s where s.name like ?")  
  2.   
  3. .setParameter(0"%0%")  
  4.   
  5. .list();  
  6.   
  7. List students = session.createQuery("select s.id, s.name from Student s where s.name like :myname")  
  8.   
  9. .setParameter("myname",  "%0%")  
  10.   
  11. .list();  


 4.使用原生sql语句。

     和咱们原先写入的sql语句一样。在此不介绍了。

 5.外置命名查询。

      这个听起来有点晦涩,怎么理解呢?其实通俗的说就是把hql语句写在外面,写在映射文件中。使用标签:

   

[html] view plaincopyprint?
  1. <query name="queryStudent">  
  2.   
  3. <![CDATA[ 
  4.  
  5. select s from Student s where s.id <? 
  6.  
  7. ]]>  
  8.   
  9. </query>  


 

    那在程序中是如何使用此标签的呢?使用session.getNameQuery(),并进行赋值,代码如下:

List students = session.getNamedQuery("queryStudent")  
  1.   
  2. .setParameter(010)  
  3.   
  4. .list();  

 

 6.查询过滤器。

    这个是什么意思呢?过滤器大家很熟悉吧,不熟悉的可以参考我的以前博客<>.原来我们接触过编码过滤器,编码过滤器就是为了避免当时每个页面需要设置编码格式而提出的。这个查询过滤器其实也是这个意思。若是代码都需要某一句sql语句的话,可以考虑使用它。这样可以避免每次都写查询语句。

    使用如下:首先在映射文件中配置标签:

[html] view plaincopyprint?
  1. <filter-def name="testFilter">  
  2.   
  3. <filter-param type="integer" name="myid"/>  
  4.   
  5. </filter-def>  

 

  然后程序中如下使用并进行赋值:

session.enableFilter("testFilter")  
  1.   
  2. .setParameter("myid"10);  


7.分页查询。

    分页查询,这个肯定不陌生,因为在做drp项目时,做的最多的是分页,当时使用oracle数据库,分页查询涉及到三层嵌套。直接传入的参数为:每页的大小(记录数),页号。

     Hibernate中给我们已经封装好了,只要设置开始的页号以及每页的大小即可,不用亲自动手写嵌套的sql语句。

     代码如下:

List students = session.createQuery("from Student")  
  1.   
  2. .setFirstResult(1)  
  3.   
  4. .setMaxResults(2)  
  5.   
  6. .list();  

 

8.对象导航查询。

这个什么意思呢?这个只要是用于一个类的属性是另一个类的引用。比如:student类中有一个classes属性。其中的classes也是一个类Class的引用。

当我们查询的时候可以这样使用:

[java] view plaincopyprint?
  1. List students = session.createQuery("from Student s where s.classes.name like '%t%'")  
  2.   
  3. .list();  


相当于:s.getClasses.getName(),直接使用get后面的属性,然后首字母小写。

 这种语法,是不是很熟悉?想想我们在哪是不是也用过?想起来了吗?估计你猜出来啦,呵呵,是JSTL(jsp standard tag library)中。若是想进一步了解,可以参考我的博客哈,当时是转载滴貌似。

9.连接查询。

    连接分为:内连接和外连接,其中外连接分为左连接,右连接,完全连接。这个跟数据库中的左右连接其实是一样的。我们通俗解释一下:

    左连接:以左边为准,右边即使没哟匹配的,也要把这条记录查询出来,此时没有匹配的右边以null填充。

    右连接:以右边为准,左边即使没有匹配的,也要把这条记录查询出来,此时没有匹配的左边以null填充。

   完全连接:只要一方存在即可。

   内连接:必须两方都存在才可以查询提取此记录。

10.统计查询。

     其实就是查询count的记录数。其中查询出来的额count是long类型。

11.DML风格的操作。

     DML?其实DML=Data Manipulate Language(数据操作语言),举个例子:

  

[java] view plaincopyprint?
  1. session.createQuery("update Student s set s.name=? where s.id<?")  
  2.   
  3. .setParameter(0"王斌")  
  4.   
  5. .setParameter(12)  
  6.   
  7. .executeUpdate();   

           

假若原来的名字是:李四,更新完数据库后变成王斌,若是我们此时取出数据,其姓名是李四还是王斌?按照道理应该是王斌,但是结果确实李四,若不信,可以自己去实践一下。

这个原因,是因为更新了数据库,但是缓存中没有更新,才会造成这种数据库和缓存不同步的问题。

所以,我们应该尽量不使用这种形式。扬其长避其短嘛。

  相关解决方案