hibernate的查询方式汇总

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

一、HQL查询方式

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

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

  static void query(String name){
        Session session=null;
        try{
           session=HibernateUtil.getSession();

           //from后面是对象,不是表名
           //使用命名参数,推荐使用,易读。
          String hql="from Admin as admin where admin.aname=:name";
          Query query=session.createQuery(hql);
          query.setString("name", name);
          List<User> list=query.list();


          for(User user:list){
             System.out.println(admin.getAname());
          }

       }finally{
         if(session!=null)
         session.close();
      }
  }
          对于多对一关系查询:
                        
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,Criteria,Criterion。使用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.andand关系
Restrictions.oror关系
Restrictions.sqlRestrictionSQL限定查询

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求某属性的合计


示例:static void cri(String name,String password){
        Session session=null;
        try{
           session=HibernateUtil.getSession();

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


           for(Admin admin:list){
             System.out.println(admin.getAname());
           }

       }finally{
          if(session!=null)
          session.close();
      }
   }

示例2(分页查询)
    Criteria criteria = session.createCriteria(Customer.class);
    criteria.addOrder( Order.asc("name") ); //排序方式
    criteria.setFirstResult(0);
    criteria.setMaxResults(10);
    List result = criteria.list()
 
适用情况:面向对象操作,革新了以前的数据库操作方式,易读。缺点:适用面较HQL有限。

  说明:可以使用Criteria的工厂Criterion保存Restrictions,然后添加到Criteria中

     实例:

        /*

         * 做工厂Criterion集合     

         */

        List<Criterion> cs = new ArrayList<Criterion>();

        // 生成工厂Criterion对象

        Criterion cri = Restrictions.like("title", title,MatchMode.ANYWHERE);
        // 将工厂添加到集合中

        cs.add(cri);

       

       /*

         * 将工厂Criterion集合的条件加载到Criteria中    

         */

        Session session = HibernateUtil.getSession();
        Criteria criteria = session.createCriteria(House.class);

        // 动态添加查询条件
        for (Criterion criterion : cs) {
           criteria.add(criterion);
        }
 
三、QBE(Query By Example)例子查询方式
   将一个对象的非空属性作为查询条件进行查询。
 示例:

     Session session = SessionFactory.getCurrentSession();
 
     User user = new User();
     user.setName("ijse");


     Transaction ts = session.beginTransaction();


     try {

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

        ts.commit();
    } catch (HibernateException ex) {
       ts.rollBack();
       ex.printStackTrace();
    }

   System.out.println(user.getName());


  适用情况:面向对象操作。   缺点:适用面较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 session = HibernateUtil.getSession();

   Criteria c = dc.getExecutableCriteria(s);
   List rs = c.list();


   session.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 session = HibernateUtil.getSession();

     Query q = session.createSQLQuery("select * from user").addEntity(User.class);

     List<User> rs = q.list();


     session.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);

      ts.commit();

   } catch (HibernateException ex) {
      ts.rollBack();
      ex.printStackTrace();
   }

   System.out.println(user.getName());

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值