Hibernate查询语言 Hibernate的抓取策略

 

 

一、hibernate查询语言概述

数据查询与检索是Hibernate中的一个亮点。相对其他ORM实现而言,Hibernate提供了灵活多样的查询机制。

1.标准化对象查询(Criteria Query):以对象的方式进行查询,将查询语句封装为对象操作。

 优点:可读性好,符合Java 程序员的编码习惯。

 缺点:不够成熟,不支持投影(projection)或统计函数(aggregation

2.Hibernate语言查询(Hibernate Query LanguageHQL):它是完全面向对象的查询语句,查询功能非常强大,具备多态、关联等特性 。Hibernate官方推荐使用HQL进行查询。

3. Native SQL Queries(原生SQL查询):直接使用标准SQL语言或跟特定数据库相关的SQL进行查询

 

 

 

二、hibernate查询语言分类示例

本示例基于Student<------->Classes的映射关系

hql查询语言里的关键字是不区分大小写的。但是属性和类名区分大小写。

1.简单属性查询【重要】

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

* 多个属性查询 ,返回的集合元素是对象数组,数组元素的类型和对应的属性在实体类中的类型一致

      数组的长度取决于select中属性的个数

* 如果认为返回数据不够对象化,可以采用hql动态实例化Student对象

之前要定义类的有参和无参的构造方法

例如:select new Student(id,name) from Student

2.实体对象查询【重要】

* N + 1问题 在默认情况下使用query.iterate查询,有可能出现N+1问题

所谓的的N+1时在查询的时候发出了N+1条sql语句

1:首先发出一条查询对象id列表的sql

N:根据id列表到缓存中查询,如果缓存中不存在与之匹配的数据,那么就会根据id发出相应的sql语句

* list和iterate的区别

* list每次都会发出语句,list会向缓存中放入数据,而不利用缓存中的数据

* iterate:在默认情况下iterate利用缓存数据,但如果缓存中不存在数据有可能出现N+1问题 

3.条件查询【重要】

* 可以采用拼字符串的方式传递参数,例如:

select id,name from Student where name like '%1%'

* 可以采用?来传递参数(索引从0开始)

Query query = session.createQuery("from Student s where s.apply_date between ? and ?");

SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

Date d1 = sdf.parse("2009-02-24 00:00:00");

Date d2 = sdf.parse("2009-04-30 00:00:00");

query.setParameter(0, d1);

query.setParameter(1, d2);

* 可以采用  :参数名   来传递参数 ,例如

Query query = session.createQuery("from Student s where s.name like :myname");

query.setParameter("myname", "%3");

* 如果传递多个参数,可以采用setParameterList方法 ,例如:

Query query = session.createQuery("from Student s where s.id in (:ids)");

query.setParameterList("ids", new Object[]{1,2,3});

* 在hql中可以使用数据库的函数,如:mysql中的 date——format

例如:

Query query = session.createQuery("from Student s where date_format(s.apply_date,'%Y-%m')=?");

query.setParameter(0, "2009-04");

4.hibernate也支持直接使用sql进行查询

 

5.外置命名查询

* 在映射文件中采用标签来定义hql 标签存在那个xml文件中不影响查询

      因此在项目中的中的name属性应起不同的名字来区别

映射文件:<query>定义到<class>标签的外部,例如

 <query >
  <![CDATA[ select id from Student ]]>
 </query>

 

 

 

* 在程序中采用session.getNameQuery()方法得到hql查询串

Query query = session.getNamedQuery("querystudent");

6.查询过滤器

* 在映射文件中定义过滤器参数,<filter-def>定义到<class>标签的外部

 <filter-def >
  <filter-param name="myid" type="integer"/>
 </filter-def>

 

 

 

* 在类的映射中使用这些参数,定义到<class>标签的内部

<filter condition="id &lt; :myid"></filter>

 

* 在程序中启用过滤器

session.enableFilter("defaultfilter").setParameter("myid", 1);

 

7.分页查询【重要】

* setFirstResult(),从0开始

* setMaxResults(),每页显示多少条数据

 

8.对象导航查询,在hql中采用.进行导航【重要】

* 通过对象导航查询,用的对象的属性,通过.导航

* 如果导航的层次太深(关联的对象层次太深),通过其他方式来查询

from Student s where s.classes.name like '%1'

9.连接查询【重要】

* 内连接

select s.name,c.name  from Student s join s.classes c

* 外连接(左连接/右连接)

select c.name,s.name  from Classes c left join c.students s

select c.name,s.name  from Classes c right join c.students s

*子查询

 

10.统计查询【重要】

*count

select count(*) from Student s

可以使用Object obj = query.uniqueResult() 返回唯一结果

*sum

select sum(s.id) from Student s

*group

select c.id, c.name,count(s) from Student s join s.classes c group by c.id,c.name

 

11.DML风格的操作(尽量少用,因为和缓存不同步)

update Student s set s.name = ? where s.id = ?

由于和缓存不同步,可以得出hibernate并不适合聚集型的操作

 

三、Hibernate的抓取策略

1.hibernate抓取策略(单端代理的批量抓取)

 

保持默认,也就是将fetch="select",如:

 

 

fetch="select",另外发送一条select语句抓取当前对象关联实体或集合

 

2.hibernate抓取策略(单端代理的批量抓取)

设置fetch="join",如: 

fetch="join" ,hibernate会通过select语句使用外连接来加载其关联实体或集合,一般情况下,fetch的优先级高于lazy,若出现了fetch,则忽略lazy

优先级:HQL代码 > fetch(配置) > lazy (配置)

3.hibernate抓取策略(集合代理的批量抓取)

保持默认,同fetch="select",如: 

fetch="select",另外发送一条select语句抓取当前对象关联实体或集合

4.hibernate抓取策略(集合代理的批量抓取)

设置fetch="join",如: 

fetch="join" ,hibernate会通过select语句使用外连接来加载其关联实体或集合,一般情况下,fetch的优先级高于lazy,若出现了fetch,则忽略lazy

5.hibernate抓取策略(集合代理的批量抓取)

设置fetch="subselect",如: 

fetch="subselect" 另外发送一条select语句,抓取在前面查询到的所有实体对象的关联集合

6.hibernate抓取策略

batch_size属性,可以批量加载实体类,如下配置

 

    <class name="Classes" table="t_classes" batch-size="5">

7.hibernate抓取策略(batch-size在集合上的应用)

batch_size属性,可以批量加载实体类,<set>标签配置batch-size="5":

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值