主要摘自  http://blog.sina.com.cn/s/blog_7ffb8dd501014a6o.htmlhttp://blog.csdn.net/xingtianyiyun/article/details/7703429

Hibernate总的来说共有三种查询方式:HQL、QBC和SQL三种。但是细分可以有如下几种:

一、HQL查询方式
   
这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多。条件查询、分页查询、连接查询、嵌套查询,写起来与SQL
语法基本一致,唯一不同的就是把表名换成了类或者对象。其它的,包括一些查询函数(count(),sum()等)、查询条件的设定等,全都跟SQL语法
一样。

###注意:
    
在hql中关键字不区分大小写,但是属性和类名区分大小写
示例1:

   //from后面是对象,不是表名
   String hql="from Admin as admin where
admin.aname=:name";//使用命名参数,推荐使用,易读。

   Query
query=s.createQuery(hql);
   query.setString("name",
name);
  
List<Admin>
list=query.list();

 

######!!!!!!!!!!!!!对于多对一关系查询:
 
String
hql = "from Student where Class.className = '二班'";
(Student实体类中含有Class对象的引用。这样相当于两张表的联合查询)

示例2(分页查询):
    Query query
= session.createQuery("from Customer c order by c.name asc");
   query.setFirstResult(0);
   query.setMaxResults(10);
   List result = query.list();
    说明:
  
–setFirstResult(int firstResult):设定从哪一个对象开始检索,参数firstResult表示这个对象在查询结果中的索引位置,索引位置的起始值为0。默认情况下,Query和Criteria接口从查询结果中的第一个对象,也就是索引位置为0的对象开始检索。

–setMaxResult(int maxResults):设定一次最多检索出的对象数目。默认情况下,Query和Criteria接口检索出查询结果中所有的对象。

适用情况:常用方法,比较传统,类似jdbc。缺点:新的查询语言,适用面有限,仅适用于Hibernate框架。

二、QBC(Query By Criteria)
查询方式

  
这种方式比较面向对象方式,重点是有三个描述条件的对象:Restrictions,Order,Projections。使用QBC查询,一般需要以下三个步骤:
   1、 使用Session实例
的createCriteria()方法创建Criteria对象
  
2、使用工具类Restrictions的方法为Criteria对象设置查询条件,Order工具类的方法设置排序方式,Projections工具类的方法进行统计和分组。

3、
使用Criteria对象的list()方法进行查询并返回结果
Restrictions类的常用方法:

Restrictions类的常用方法:

方法名称
描述
Restrictions.eq 等于
Restrictions.allEq 使用Map,Key/Valu进行多个等于的比对
Restrictions.gt 大于
Restrictions.ge 大于等于
Restrictions.lt 小于
Restrictions.le 小于等于
Restrictions.between 对应SQL的between
Restrictions.like 对应SQL的like
Restrictions.in 对应SQL的in
Restrictions.and and关系
Restrictions.or or关系
Restrictions.sqlRestriction SQL限定查询

Order类的常用方法:

方法名称
描述
Order.asc 升序
Order.desc 降序

Projections类的常用方法

方法名称
描述
Projections.avg 求平均值
Projections.count 统计某属性的数量
Projections.countDistinct 统计某属性不同值的数量
Projections.groupProperty 指定某个属性为分组属性
Projections.max 求最大值
Projections.min 求最小值
Projections.projectionList 创建一个ProjectionList对象
Projections.rowCount 查询结果集中的记录条数
Projections.sum 求某属性的合计

示例:

Criteria c=s.createCriteria(Admin.class);
  
c.add(Restrictions.eq("aname",name));//eq是等于,gt是大于,lt是小于,or是或
  
c.add(Restrictions.eq("apassword", password));
  
List<Admin>
list=c.list();

示例2(分页查询):
    Criteria
criteria = session.createCriteria(Customer.class);
  criteria.addOrder( Order.asc("name") ); //排序方式
  criteria.setFirstResult(0);
  criteria.setMaxResults(10);
  List result = criteria.list()
 

适用情况:面向对象操作,革新了以前的数据库操作方式,易读。缺点:适用面较HQL有限。

三、QBE(Query By
Example)例子查询方式

   将一个对象的非空属性作为查询条件进行查询。
 示例:

   User user = new
User();
  
 user.setName("ijse");

     Criteria criteria =
session.createCriteria(User.class);
     criteria.add(Example.create(user));
     user= (User)
criteria.list().get(0);  

  
适用情况:面向对象操作。  
缺点:适用面较HQL有限,不推荐。

四、DetachedCriteria:离线条件查询

离线查询就是建立一个DetachedCriteria对象,将查询的条件等指定好,然后在session.beginTransaction()后将这个对象传入。通常这个对象可以在表示层建立,然后传入业务层进行查询。

1、建立DetachedCriteria对象
    DetachedCriteria dc =
DetachedCriteria.forClass(User.class);

    int id = 1;
   
if (id != 0)
   
dc.add(Restrictions.eq("id", id));
   
Date age = new Date();
   if (age != null)
    dc.add(Restrictions.le("birthday",
age));

   List users = dc(dc);//执行查询
  System.out.println("离线查询返回结果:" + users);
 2、执行查询
   static List
dc(DetachedCriteria dc) {
       Session s =
HibernateUtil.getSession();
       Criteria c =
dc.getExecutableCriteria(s);
       List rs = c.list();

       s.close();
       return rs;
    
}
  
适用情况:面向对象操作,分离业务与底层,不需要字段属性摄入到Dao实现层。 
缺点:适用面较HQL有限。

五、命名查询
  1、在数据映射元文件中进行配置如下:
 <?xml version="1.0"
encoding="utf-8"?>
 
<!DOCTYPE hibernate-mapping PUBLIC
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
 
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

<hibernate-mapping>
   
<class name="com.sy.vo.User" table="user"
catalog="news">
   ....
   
</class>
   
<!-- 命名查询:定义查询条件 -->
    <query name="getUserById">
    
<![CDATA[from User where
id=:id]]>
   
</query>

   
<!-- 命名查询中使用sql,不推荐使用,影响跨数据库
    <sql-query
name="getUserById2">
    
<![CDATA[select * from User where
]]>
   
</sql-query>
-->

</hibernate-mapping>
  2、在java代码中写入:
  static List namedQuery(int id) {
    Session s = HibernateUtil.getSession();
    Query q =
s.getNamedQuery("getUserById");
    q.setInteger("id", id);

    return q.list();
   }
  适用情况:万能方法,有点像ibatis轻量级框架的操作,方便维护。

缺点:不面向对象。基于hql和sql,有一定缺陷。

六、SQL查询
   示例:
  static List sql() {
   Session s = HibernateUtil.getSession();
   
Query q =
s.createSQLQuery("select * from user").addEntity(User.class);
    List<User> rs =
q.list();

   
s.close();
    return rs;
    }
适用情况:不熟悉HQL的朋友,又不打算转数据库平台的朋友,万能方法  
缺点:破坏跨平台,不易维护,不面向对象。

七、OID查询方式

按照对象的OID来检索对象。Session的get()和load()方法提供了这种功能。如果在应用程序中事先知道了OID,就可以使用这种检索对象的方式。 

八、Query.iterator的N+1查询(基于一的HQL,多见于一对多、多对多的关联映射)

N +
1问题,在默认情况下,使用query.iterate查询,有可以能出现N+1问题
  
所谓的N+1是在查询的时候发出了N+1条sql语句
   1: 首先发出一条查询对象id列表的sql
   N:
根据id列表到缓存中查询,如果缓存中不存在与之匹配的数据,那么会根据id发出相应的sql语句
* list和iterate的区别?
   *
list每次都会发出sql语句,list会向缓存中放入数据,而不利用缓存中的数据
   *
iterate:在默认情况下iterate利用缓存数据,但如果缓存中不存在数据有可以能出现N+1问题

  示例:Query
q=session.createQuery(“from UserInfo”);
    
Iterator<UserInfo>
list=q.iterate();

    
While(list.hasNext()) {

UserInfo st = (UserInfo)
it.next();
    
System.out.println(st.getName());
    }
避免N+1查询解决方法:
   
1、可以将fetch抓取数据的属性改为“join”,来避免N+1次的查询;
   
2、使用二级缓存
九、复查查询(基于二:QBC的深度查询)

  复合查询就是在原有查询的基础上再进行查询,

    可以调用Criteria对象的createCriteria()方法在这个Criteria对象的基础上再进行查询。

    示例:Session session = SessionFactory.getCurrentSession();
            User user =
new User();
            Transaction
ts = session.beginTransaction();
           
try  {
               Criteria criteria1 =
session.createCriteria(Room.class);
               Criteria 
criteria2 =criterial.createCriteria("User");
              
criteria2.add(Restrictions.eq("name",new
String("ijse"));

              
user= (User)
criteria.list().get(0);
              
session.commit();
           } catch (HibernateException ex) {
               
ts.rollBack();
               
ex.printStackTrace();
           }
          System.out.println(user.getName());

======================================================================================================

您可以使用Criteria进行查询,并使用Order对结果进行排序,例如使用Oder.asc()由小到大排序(反之则使用desc()):

Criteria criteria = session.createCriteria(User.class);

criteria.addOrder(Order.asc("age"));

List users = criteria.list();

setMaxResults()方法可以限定查询回来的笔数,如果配合setFirstResult()设定传回查询结果第一笔资料的位置,就可以实现简单的分页,例如传回第51笔之后的50笔资料(如果有的话):

Criteria criteria = session.createCriteria(User.class);

criteria.setFirstResult(51);

criteria.setMaxResult(50);

List users = criteria.list();

您可以对查询结果进行统计动作,使用Projections的avg()、rowCount()、count()、max()、min()、 countDistinct()等方法,例如对查询结果的"age"作平均:

Criteria criteria = session.createCriteria(User.class);

criteria.setProjection(Projections.avg("age"));

List users = criteria.list();

Iterator iterator = users.iterator();

while(iterator.hasNext()) {

System.out.println(iterator.next());

}

还可以配合Projections的groupProperty()来对结果进行分组,例如以"age"进行分组,也就是如果资料中"age"如果有 20、20、25、30,则以下会显示20、25、30:

Criteria criteria = session.createCriteria(User.class);

criteria.setProjection(Projections.groupProperty("age"));

List users = criteria.list();

Iterator iterator = users.iterator();

while(iterator.hasNext()) {

System.out.println(iterator.next());

}

如果想结合统计与分组功能,则可以使用ProjectionList,例如下面的程式会计算每个年龄各有多少个人:

ProjectionList projectionList = Projections.projectionList();

projectionList.add(Projections.groupProperty("age"));

projectionList.add(Projections.rowCount());

Criteria criteria = session.createCriteria(User.class);

criteria.setProjection(projectionList);

List users = criteria.list();

Iterator iterator = users.iterator();

while(iterator.hasNext()) {

Object[] o = (Object[]) iterator.next();

System.out.println(o[0] + "\t" + o[1]);

}

如果有一个已知的物件,则可以根据这个物件作为查询的依据,看看是否有属性与之类似的物件,例如:

User user = new User();

user.setAge(new Integer(30));

Criteria criteria = session.createCriteria(User.class);

criteria.add(Example.create(user));

List users = criteria.list();

Iterator iterator = users.iterator();

System.out.println("id \t name/age");

while(iterator.hasNext()) {

User ur = (User) iterator.next();

System.out.println(ur.getId() +

" \t " + ur.getName() +

"/" + ur.getAge());

}

在这个例子中,user物件中有已知的属性"age"为30,使用Example会自动过滤掉user的空属性,并以之作为查询的依据,也就是找出 "age"同为30的资料。

Criteria可以进行复合查询,即在原有的查询基础上再进行查询,例如在Room对User的一对多关联中,在查询出所有的Room资料之后,希望再查询users中"age"为30的user资料:

Criteria roomCriteria = session.createCriteria(Room.class);

Criteria userCriteria = roomCriteria.createCriteria("users");

userCriteria.add(Restrictions.eq("age", new Integer(30)));

List rooms = roomCriteria.list(); // 只列出users属性中有user之"age"为30的Room

Iterator iterator = rooms.iterator();

hibernte criteria只查询表的的某个字段:

  1. Criteria   criteria=session.createCriteria(User.class);
  2. ProjectionList   proList   =   Projections.projectionList();//设置投影集合
  3. proList.add(Projections.Property( "userName "));
  4. proList.add(Projections.Property( "password "));
  5. criteria.setProjection(proList);

统计+分组 +关联查询

Criteria c = getSession().createCriteria(Infos.class);
        c.add(Restrictions.in("infoType", infoType));
        c.add(Restrictions.eq("infoStatus", 3));
        c.setProjection(Projections.projectionList()
                .add(Projections.groupProperty("infoType"))
                .add(Projections.max("infoTime"),"infoTime"));
        List<Object> l = c.list();
        Object[] types=new Object[l.size()];
        Timestamp[] times=new Timestamp[l.size()];
        int i=0;
        for(Object o:l){
            Object[]obj=(Object[]) o;
            types[i]=obj[0];
            times[i]=(Timestamp) obj[1];
            i++;
        }
        c=getSession().createCriteria(Infos.class);
        c.add(Restrictions.in("infoType", types))
        .add(Restrictions.in("infoTime",times));
        List<Infos> list=c.list();

注意 :1` pubStationsV  是   PubTabTimeDate持久内中  关联对象名  , 不是 持久类名

2`  projectionList 只能使用一次 多次没用

3` 别名是用很关键(pv) 否则 管理表中属性 找不到  会报错

Session session = pubTabTimeDateDao.getCurrentSession();
        Criteria c = session.createCriteria(PubTabTimeDate.class,"p");
        ProjectionList projectionList=Projections.projectionList();
        projectionList.add(Projections.distinct(Projections.property("p.fstationnum")));
        projectionList.add(Projections.property("pv.faddress"));
        c.addOrder(Order.desc("p.fstationnum"))
        .setFirstResult(0)
        .setMaxResults(30);
        Criteria cc = c.createCriteria("pubStationsV","pv");
        c.setProjection(projectionList);
        List list = cc.list();

hibernate 查询方式汇总的更多相关文章

  1. Hibernate查询方式汇总

    Hibernate总的来说共有三种查询方式:HQL.QBC和SQL三种.但是细分可以有如下几种: 一.HQL查询方式    这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的 ...

  2. hibernate查询方式

    hibernate查询方式:1.本地SQL查询 2.HQL查询 3.QBC查询 HQL查询:是面向对象的查询语言,是使用最广的一种查询方法 QBC查询:Query by Criteria是一套接口来实 ...

  3. (十)Hibernate 查询方式

     所有项目导入对应的hibernate的jar包.mysql的jar包和添加每次都需要用到的HibernateUtil.java 第一节:Hibernate 查询方式简介 1,导航对象图查询方式: 2 ...

  4. Hibernate查询方式(补)

    -----------------siwuxie095                             Hibernate 查询方式         1.对象导航查询     根据已经加载的对 ...

  5. Hibernate学习10——Hibernate 查询方式

    本章主要是以查询Student的例子: Student.java: package com.cy.model; public class Student { private int id; priva ...

  6. Hibernate 查询方式、JPA查询方式

    hibernate 查询方式: OID 查询 对象导航查询 HQL 方式查询 QBC方式查询 原生SQL方式查询 JPA 查询方式: OID 查询 对象导航查询 JPQL 方式查询 CriteriaB ...

  7. Hibernate 查询方式(HQL/QBC/QBE)汇总

    作为老牌的 ORM 框架,Hibernate 在推动数据库持久化层所做出的贡献有目共睹. 它所提供的数据查询方式也越来越丰富,从 SQL 到自创的 HQL,再到面向对象的标准化查询. 虽然查询方式有点 ...

  8. Hibernate的查询方式汇总

    分别是HQL查询,对象化查询Criteria方法,动态查询DetachedCriteria,例子查询,sql查询,命名查询. 如果单纯的使用hibernate查询数据库只需要懂其中的一项就可以完成想要 ...

  9. Redis查询&JDBC查询&Hibernate查询方式的效率比较...

    比较三种查询方式查询效率对比...我是用的JavaWeb的方式通过通过JSP页面查询的填写查询的参数...给予反馈.... 整个demo的下载地址:http://files.cnblogs.com/f ...

随机推荐

  1. js通过添加随机数的方法,解决多张图片加载时由于缓存导致图片无法正确显示的问题

    问题出现描述:当对列表中某个图片进行重新编辑时,提交后会发现图片列表仍会出现修改之前的图片,新图片并未覆盖. 问题出现原因:缓存问题. 解决办法:通过js方法,在每张图片路劲后面添加一个随机数,这样每 ...

  2. Spring(二)之配置.md

    依赖配置详解 bean的属性及构造器参数既可以引用容器中的其他bean,也可以是内联(inline)bean.在spring的XML配置中使用 直接变量(基本类型.Strings类型等.) <v ...

  3. 浏览器支持播放的视频播放格式要求(H5的video标签)

    今天给一个客户上传视频后发现,即使是MP4格式的视频浏览器也打不开,找了好久的问题,最红发现客户视频的编码方式不是h5支持的,折腾了好久,最终确认了浏览器对于MP4编码方式的如下: 浏览器对mp4的编 ...

  4. 【Ubuntu Desktop】VMware 中 Unknown Display

    由于之前重复的安装卸载Unity桌面,今天遇到了在设置虚拟机分辨率的时候,遇到了Unknown Display问题 参考网上内容 使用 xrandr调节分辨率 xrandr只能在虚拟机本地终端执行,不 ...

  5. 8种Java排序算法整理

    package org.hbz.test; import java.util.ArrayList; import java.util.Arrays; import java.util.List; im ...

  6. hbase1.1.4集群搭建

    hbase1.1.4集群搭建 先部署一个zookeeper集群和hadoop集群. (1)上传hbase安装包到intsmaze01节点 (2)解压 (3)配置hbase集群,要修改3个文件 注意:要 ...

  7. 420小时学习代码之后:如何教你免费自学Python

    原文地址:learning-to-code-420-hours-later-how-to-teach-yourself-python-for-free 说明:有些网址需要FQ. 大约在1.5年前,我开 ...

  8. 关于我立牌坊那个SSM项目

    我这段时间有在写,但是我发现一个问题,就是我经常在做后面功能的时候要改前面一个东西,但是我博客已经发出来了,这让我很头疼.毕竟我博客基本都在纯贴代码. 所以决定暂时停更这个系列.等我写好了再上传到gi ...

  9. DateTable转化为泛型集合

    public class ListUtil { public static List<T> ToList<T>(DataTable dt) { List<T> li ...

  10. 点击grid单元格弹出新窗口

    实现功能:点击指定单元格后会弹出新窗口,并且最后一行合计不会触发单元格触发函数 <script type="text/javascript"> grid.on('cel ...