1、HQL查询性能优化

  1.1、避免or操作

    1.1.1、where子句包含or操作,执行时不使用索引

      from Hose where street_id='1000' or street_id='1001'

    1.1.2、可以使用in条件来替换

      from Hose where street_id in('1000','1001')

  1.2、避免使用not

    1.2.1、where子句包含not关键字,执行时该字段的索引失效

      from Hose h where not(h.price>1800)

    1.2.2、使用比较运算符替换not

      from Hose h where h.price<=1800

  1.3、避免like的特殊形式(查询时尽可能少使用like)

  1.4、避免having子句(尽可能在where 子句中指定条件)

  1.5、避免使用distinct(在不要求或允许冗余时,应避免使用distinct)

2、数据加载方式

  2.1、即时加载

    <hibernate-mapping>
        <class name="cn.jbit.houserent.bean.District" table="district">
            <id name="id" type="java.lang.Integer">
                <column name="id" />
                <generator class="native" />
            </id>
          <property name="name" type="java.lang.String">
              <column name="district_name" length="50" not-null="true" />
          </property>
        <!--   -->
          <set name="streets" table="street" cascade="all" inverse="true" lazy="false">
            <key>
                <column name="district_id" not-null="true" />
            </key>
            <one-to-many class="cn.jbit.houserent.bean.Street" />
        </set>
    </class>
</hibernate-mapping>

   SessionFactory sf=null;

   Session s=null;

   List<district> list=null;

   try{

    sf=new Configuration().configure().buildSessionFactory();

    s=sf.openSession();

    Query q=s.createQuery("from District where id='1004'");

    list=q.list();

    for(District d:list){

      System.out.println("区名"+d.getName());

      Set streets=d.getStreets();

      System.out.println("街道数量"+streets.size());

   }

  }case(HibernateException e){e.printStackTrace}finally{

    s.close();

    sf.close();

 }

  2.2、延迟加载

    延迟加载就是当真正需要数据的时候,才真正执行数据加载操作

    类级别的默认加载策略为延迟加载

    hibernate提供了:

        对实体对象的延迟加载(为实体设置延时加载,即设置<class>元素的lazy属性为true)

        集合的延迟加载

        属性的延迟加载(1、Hibernate 3 中,引入的新特性——属性的延迟加载
2、适用于二进制大对象、字符串大对象以及大容量组件类型的属性)

    <hibernate-mapping>
        <class name="cn.jbit.houserent.bean.District" table="district">
            <id name="id" type="java.lang.Integer">
                <column name="id" />
                <generator class="native" />
            </id>
          <property name="name" type="java.lang.String">
              <column name="district_name" length="50" not-null="true" />
          </property>
        <!--   -->
          <set name="streets" table="street" cascade="all" inverse="true" lazy="true">
              <key>
                  <column name="district_id" not-null="true" />
              </key>
              <one-to-many class="cn.jbit.houserent.bean.Street" />
          </set>
      </class>
  </hibernate-mapping>

   //实体延迟加载

   SessionFactory sf=null;

   Session s=null;

   try{

    sf=new Configuration().configure().buildSessionFactory();

    s=sf.openSession();

    User u=(User)s.load(User.class,new Integer("1000"));

    System.out.println("获取用户id为1000的用户");

    System.out.println("用户名:"+u.getName());

  }case(HibernateException e){e.printStackTrace}finally{

    s.close();

    sf.close();

 }

 //属性延迟加载

  <class name="cn.jbit.houserent.bean.House" table="house">
      <!--省略其他配置-->
      <property name="description" type="text" lazy="true">
          <column name="description"/>
      </property>
  </class>

   SessionFactory sf=null;

   Session s=null;

   try{

    sf=new Configuration().configure().buildSessionFactory();

    s=sf.openSession();

    Query q=s.createQuery("from Hose h where h.price=2300");

    System.out.println("获取价格为2300元的房屋信息");

    List<Hose>list=q.list();

    for(Hose h:list){

      System.out.println("标题:"+h.getTitle());

      System.out.println("描述:"+h.getDescription());

    }

  

  }case(HibernateException e){e.printStackTrace}finally{

    s.close();

    sf.close();

 }

  2.3、list()方法和iterate()方法

    sessionFactory = new Configuration().configure().buildSessionFactory();
    session = sessionFactory.openSession();
    Query query = session.createQuery("from House as h ");
    System.out.println("使用iterate()方法查询数据");
    Iterator<House> it = query.iterate();
    while(it.hasNext()){
       House house = it.next();
       System.out.println("标题:"+house.getTitle());
    }
    System.out.println("-------------------"); 
    System.out.println("使用list()方法查询数据");  
    List<House> result = query.list();
    for(House house:result){
       System.out.println("标题:"+house.getTitle());
  }

   2.3.1、使用list()方法获取查询结果,每次发出一条查询语句,获取全部结果

   2.3.2、使用iterate()方法获取查询结果,先发出一条sql语句用来查询满足条件的id;然后依次按这些id查询记录,也就是要执行n+1条sql语句

3、HQl联接查询

  3.1、内联接:inner join

    3.1.1、最典型、最常用的联接查询

    3.1.2、两个表存在主外键关系时通常会使用内联接查询

  3.2、外联接:

    3.2.1、左外联接:left join或left outer join

    3.2.2、右外联接:right join 或right outer join

    3.2.3、完整外联接:full join或 full outer join

  3.3、内联接

    from Entity inner join [fetch] Entity.property

    sessionFactory = new Configuration().configure().buildSessionFactory();
    session = sessionFactory.openSession();
    Query query = session.createQuery("from District d inner join d.streets s");
    List result = query.list();
    Iterator it = result.iterator();
    while(it.hasNext()){
        Object[] results = (Object[]) it.next() ;
        System.out.println("数据的类型:");
      for (int i=0;i<results.length;i++){
            System.out.println(results[i]);
     }
}

  3.4、左外联接

    from Entity left join [fetch] Entity.property

  3.5、右外联接

    from Entity right join [fetch] Entity.property

4、命名查询

  <hibernate-mapping>
      <class name="cn.jbit.houserent.bean.User" table="users">
        <!--省略其他配置-->
      </class>
      <query name="loginUser">
          <![CDATA[
              from User u where u.name =:name and u.password =:password
          ]]>
      </query>
  </hibernate-mapping>

  Query q=session.getNamedQuery("loginUser");

  QueryUser qu=new QueryUser();

  qu.setName("admin");

  qu.setPassword("123");

  q.setProperties(qu);

  List list=q.list();

  Iterator it=list.iterator();

  if(it.hasNext()){

    User u=(User)it.next();

    System.out.println("欢迎"+u.getUserName());

  }

<query>元素用于定义一个HQL 查询语句,它和<class>元素并列
以<![CDATA[HQL]]>方式保存HQL 语句
在程序中通过Session 对象的getNamedQuery()方法获取该查询语句

5、本地SQL查询

  Hibernate 对本地SQL查询提供了内置的支持
    Session 的createSQLQuery()方法返回SQLQuery 对象
    SQLQuery接口继承了Query接口
    SQLQuery接口的addEntity()方法将查询结果集中的关系数据映射为对象
    通过命名查询实现本地SQL查询
      使用<sql-query>元素定义本地SQL 查询语句
      与<class>元素并列
      以<![CDATA[SQL]]>方式保存SQL 语句
      通过Session 对象的getNamedQuery()方法获取该查询语句

6、本阶段总结

  HQL优化方法如下

    避免or操作

    避免使用not

    避免like的特殊形式

    避免having子句

    避免使用distinct

  数据延迟加载分为以下三类

    集合类型的延迟加载

    实体对象的延迟加载

    属性延迟加载

  HQl联接查询包括以下几种

    内联接

    外联接:左外联接、右外联接、完整外联接

  

  命名查询

  本地SQL查询

  

HQL进阶的更多相关文章

  1. Hibernate学习---第九节:Hibernate之hql

    一.Hql 入门 1.实体类: package learn.hibernate.bean; import java.util.Date; import java.util.HashSet; impor ...

  2. J2EE进阶(十七)Hibernate中常用的HQL查询方法(getHibernateTemplate())

    J2EE进阶(十七)Hibernate中常用的HQL查询方法(getHibernateTemplate())   当我们使用Hibernate进行数据的CRUD操作时,利用模版进行操作不失为一种方法. ...

  3. Java进阶知识13 Hibernate查询语言(HQL),本文以hibernate注解版为例讲解

    1.简单概述 1.1. 1) SQL:面向的是数据库 select * from tableName;2) HQL查询(Hibernate Query language): hibernate 提供的 ...

  4. Hive进阶(下)

    Hive进阶(下) Hive进阶(下) Hive的表连接 等值连接 查询员工信息:员工号.姓名.月薪.部门名称 1.select e.empno,e.ename,e.sal,d.dname2.from ...

  5. Hibernate框架进阶(上篇)

    导读 前面一片文章介绍了Hibernate框架的入门,主要是讲解Hibernate的环境搭建和简单测试,有兴趣的童鞋出门左转.本文在入门的基础上进行Hibernate的进阶讲解,分为上中下三篇,本篇为 ...

  6. Hibernate框架进阶(下篇)之查询

    导读 Hibernate进阶篇分为上中下三篇,本文为最后一篇,主要内容是Hibernate框架的查询,主要包括hql语句查询,criteria查询以及查询策略的选择. 知识框架 Hibernate查询 ...

  7. J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用

    J2EE进阶(十六)Hibernate 中getHibernateTemplate()方法使用   spring 中获得由spring所配置的hibernate的操作对象,然后利用此对象进行,保存,修 ...

  8. Scala进阶之路-Spark本地模式搭建

    Scala进阶之路-Spark本地模式搭建 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Spark简介 1>.Spark的产生背景 传统式的Hadoop缺点主要有以下两 ...

  9. Java进阶资料汇总

    Java经过将近20年的发展壮大,框架体系已经丰满俱全:从前端到后台到数据库,从智能终端到大数据都能看到Java的身影,个人感觉做后台进要求越来越高,越来越难. 为什么现在Java程序员越来越难做,一 ...

随机推荐

  1. 前端开发-2-HTML-head标签

    browser英 /'braʊzə/ 美 /'braʊzɚ/ 浏览器 explorer英 /ek'splɔːrə(r)/ 美 /ɪk'splɔrɚ/ 探险者,资源管理器 1.index 2.head标 ...

  2. Mybatis知识(3)

    1.JDBC编程有哪些不足之处,MyBatis是如何解决这些问题的? ① 数据库链接创建.释放频繁造成系统资源浪费从而影响系统性能,如果使用数据库链接池可解决此问题. 解决:在SqlMapConfig ...

  3. ArcGIS案例学习笔记2_1

    ArcGIS案例学习笔记2_1 联系方式:谢老师,135_4855_4328,xiexiaokui#qq.com 时间:第二天上午 案例1:学校选址 内容:栅格数据分析 教程:pdf page=323 ...

  4. Alpha Level (Significance Level)

    1.Alpha Level (Significance Level,显著水平): What is it? 显著性水平α是指当零假设是正确的,但做出了错误决策的概率(即一类错误的概率).Alpha水平( ...

  5. afinal框架下 ViewInject的使用

    1.可以在BaseActivity界面onCreate 方法setContentView后加上该语句. initInjectedView(this); 2.@ViewInject(id=R.id.v_ ...

  6. distinct top執行順序

    select distinct top 3 from table; 先distinct后top

  7. Loadrunner通过吞吐量计算每个用户需要的带宽

    Loadrunner通过吞吐量计算每个用户需要的带宽 运行一个场景,点击Analysis进行分析,使用分析报告中的Average Throughput(bytes/second)进行计算. 计算公式: ...

  8. Python vars() 函数

    Python vars() 函数  Python 内置函数 描述 vars() 函数返回对象object的属性和属性值的字典对象. 语法 vars() 函数语法: vars([object]) 参数 ...

  9. Unity3d dll 热更新 基础框架

    APK包装到用户手机上后,代码如何更新,总不能全用LUA吧?特别是代码非常多的战斗手游 昨晚上有了dll 热更新的想法,今天做了一天的实验,也遇到些坑,这里总结下 工作环境: U3D5.3.2 + v ...

  10. 如何给a标签绑定ajax事件

    <a href="review?action=delete&id=${review.id}&articleId=${review.articleId}"cla ...