• Hibernate查询


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

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

     1 static void query(String name){
     2   Session s=null;
     3 
     4   try{
     5 
     6    s=HibernateUtil.getSession();
     7 
     8    //from后面是对象,不是表名
     9 
    10    String hql="from Admin as admin where admin.aname=:name";//使用命名参数,推荐使用,易读。
    11 
    12    Query query=s.createQuery(hql);
    13 
    14    query.setString("name", name);
    15 
    16    List<Admin> list=query.list();
    17 
    18    for(Admin admin:list){
    19 
    20     System.out.println(admin.getAname());
    21    }
    22 
    23   }finally{
    24 
    25    if(s!=null)
    26 
    27    s.close();
    28   }
    29 }

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

    示例2(分页查询):

    1 Query query = session.createQuery("from Customer c order by c.name asc");
    2 query.setFirstResult(0);
    3 query.setMaxResults(10);
    4 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 求某属性的合计


    示例:

     1 static void cri(String name,String password){
     2 
     3   Session s=null;
     4 
     5   try{
     6 
     7    s=HibernateUtil.getSession();
     8 
     9    Criteria c=s.createCriteria(Admin.class);
    10 
    11    c.add(Restrictions.eq("aname",name));//eq是等于,gt是大于,lt是小于,or是或
    12 
    13    c.add(Restrictions.eq("apassword", password));
    14 
    15    List<Admin> list=c.list();
    16 
    17    for(Admin admin:list){
    18 
    19     System.out.println(admin.getAname());
    20 
    21    }
    22 
    23   }finally{
    24 
    25    if(s!=null)
    26 
    27    s.close();
    28 
    29   }
    30 }

    示例2(分页查询)

    1 Criteria criteria = session.createCriteria(Customer.class);
    2 criteria.addOrder( Order.asc("name") ); //排序方式
    3 criteria.setFirstResult(0);
    4 criteria.setMaxResults(10);
    5 List result = criteria.list();

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

    三、QBE(Query By Example)例子查询方式
       将一个对象的非空属性作为查询条件进行查询。
     示例:

     1 Session session = SessionFactory.getCurrentSession();
     2 
     3 User user = new User();
     4 user.setName("ijse");
     5 
     6 Transaction ts = session.beginTransaction();
     7 
     8 try {
     9 
    10     Criteria criteria = session.createCriteria(User.class);
    11 
    12     criteria.add(Example.create(user));
    13 
    14     user= (User) criteria.list().get(0);   
    15 
    16     session.commit();
    17 
    18 } catch (HibernateException ex) {
    19 
    20     ts.rollBack();
    21 
    22     ex.printStackTrace();
    23 
    24 }
    25 
    26 System.out.println(user.getName());

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

    四、DetachedCriteria:离线条件查询

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

     1 //1、建立DetachedCriteria对象
     2 DetachedCriteria dc = DetachedCriteria.forClass(User.class);
     3 
     4 int id = 1;
     5 
     6 if (id != 0)
     7     dc.add(Restrictions.eq("id", id));
     8 
     9 Date age = new Date();
    10 
    11 if (age != null)
    12     dc.add(Restrictions.le("birthday", age));
    13 
    14 List users = dc(dc);//执行查询
    15 
    16 System.out.println("离线查询返回结果:" + users);
    17  //2、执行查询
    18 static List dc(DetachedCriteria dc) {
    19     Session s = HibernateUtil.getSession();
    20 
    21     Criteria c = dc.getExecutableCriteria(s);
    22     List rs = c.list();
    23 
    24     s.close();
    25     return rs;
    26 }

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

    五、命名查询
      1、在数据映射元文件中进行配置如下:

     1 <?xml version="1.0" encoding="utf-8"?>
     2 
     3 <!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
     4 
     5 "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
     6 <hibernate-mapping>
     7 
     8     <class name="com.sy.vo.User" table="user" catalog="news">
     9    ....
    10     </class>
    11 
    12     <!-- 命名查询:定义查询条件 -->
    13 
    14     <query name="getUserById">
    15 
    16      <![CDATA[from User where id=:id]]>
    17 
    18     </query>
    19 
    20     <!-- 命名查询中使用sql,不推荐使用,影响跨数据库
    21 
    22     <sql-query name="getUserById2">
    23 
    24      <![CDATA[select * from User where ]]>
    25 
    26     </sql-query> -->
    27 
    28 </hibernate-mapping>

    2、在java代码中写入:

    1 static List namedQuery(int id) {
    2   Session s = HibernateUtil.getSession();
    3   Query q = s.getNamedQuery("getUserById");
    4   q.setInteger("id", id);
    5   return q.list();
    6 }

    适用情况:万能方法,有点像ibatis轻量级框架的操作,方便维护。  缺点:不面向对象。基于hql和sql,有一定缺陷。

    六、SQL查询
       示例:

     1 static List sql() {
     2     Session s = HibernateUtil.getSession();
     3 
     4     Query q = s.createSQLQuery("select * from user").addEntity(User.class);
     5 
     6     List<User> rs = q.list();
     7 
     8     s.close();
     9 
    10     return rs;
    11 }

    适用情况:不熟悉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问题

      示例:

    1      Query q=session.createQuery(“from UserInfo”);
    2      Iterator<UserInfo> list=q.iterate();
    3      While(list.hasNext()) {
    4          UserInfo st = (UserInfo) it.next();
    5          System.out.println(st.getName());
    6      }

    避免N+1查询解决方法:
        1、可以将fetch抓取数据的属性改为“join”,来避免N+1次的查询;
        2、使用二级缓存

    九、复查查询(基于二:QBC的深度查询)
      复合查询就是在原有查询的基础上再进行查询,可以调用Criteria对象的createCriteria()方法在这个Criteria对象的基础上再进行查询。
    示例:

     1 Session session = SessionFactory.getCurrentSession();
     2 
     3 User user = new User();
     4 
     5 Transaction ts = session.beginTransaction();
     6 
     7 try  {
     8 
     9    Criteria criteria1 = session.createCriteria(Room.class);
    10 
    11    Criteria  criteria2 =criterial.createCriteria("User");
    12 
    13     criteria2.add(Restrictions.eq("name",new String("ijse"));
    14 
    15     user= (User) criteria.list().get(0);
    16 
    17     session.commit();
    18 
    19 } catch (HibernateException ex) {
    20 
    21    ts.rollBack();
    22 
    23    ex.printStackTrace();
    24 }
    25 
    26 System.out.println(user.getName());
  • 相关阅读:
    LoadRunner 技巧之 集合点设置
    LoadRunner 技巧之 IP欺骗 (推荐)
    JMeter 聚合报告之 90% Line 参数说明
    python基础学习笔记(二)
    LoadRunner 技巧之HTML 与 URL两种录制模式分析
    LoadRunner 技巧之 检查点
    LoadRunner 技巧之 思考时间设置
    一个JSlider的例子
    JApplet添加图片
    java.util.Arrays.asList 的小问题
  • 原文地址:https://www.cnblogs.com/javaleon/p/3998677.html
Copyright © 2020-2023  润新知