学习笔记 Hibernate HQL进阶

Hibernate HQL进阶 
  
  HQL查询优化
  在使用HQL 时 避免使用
   OR  not  like having distinct 等关键词
    
数据加载方式 
立即加载
 特点:
Lazy ='true'
优点:
对应用程序透明,不管对象处于什么状态  例如 持久态 ,游离态  方便一个对象指引关联对象的使用。
缺点:
session 语句使用频繁不需要访问对象造成内存空间浪费。
延迟加载
 特点:
Lazy = 'false'
优点:与上面相反。。。。。。。。。。。。
延迟加载有三种
1: 集合类型的延迟加载。 <set lazy='true'> </set>
2: 实体对象加载     <class lazy='true'></class>
3: 属性加载  
List() 方法 Iterate() 方法 
load()方法
          在使用了二级缓存的情况下,使用load()方法会在二级缓存中查找指定的对象是否存在。
在执行load()方法时,Hibernate首先从当前Session的一级缓存中获取ID对应的值,在获取不到的情况下,将根据该对象是否配置了二级缓存来做相应的处理。
如配置了二级缓存,则从二级缓存中获取ID对应的值,如仍然获取不到则还需要根据是否配置了延迟加载来决定如何执行,如未配置延迟加载则从数据库中直接获 取。在从数据库获取到数据的情况下,Hibernate会相应地填充一级缓存和二级缓存,如配置了延迟加载则直接返回一个代理类,只有在触发代理类的调用 时才进行数据库的查询操作。
在Session一直打开的情况下,并在该对象具有单向关联维护的时候,需要使用类似Session.clear(),Session.evict()的方法来强制刷新一级缓存。
get()方法
get()方法与load()方法的区别就在于不会查找二级缓存。在当前Session的一级缓存中获取不到指定的对象时,会直接执行查询语句从数据库中获得所需要的数据。
在Hibernate查询方法中,可以通过HQL来执行对数据库的查询操作。具体的查询是由Query对象的list()和iterator()方法来执行的。这两个方法在执行查询时的处理方法存在着一定的差别,在开发中应该依据具体的情况来选择合适的方法。
list()方法
在执行Query的list()方法时,Hibernate查询方法是首先检查是否配置了查询缓存,如配置了则从查询缓存中寻找是否已经对该查询进行了缓 存,如获取不到则从数据库中进行获取。从数据库中获取到后,Hibernate将会相应地填充一级、二级和查询缓存。如获取到的为直接的结果集,则直接返 回,如获取到的为一些ID的值,则再根据ID获取相应的值(Session.load()),最后形成结果集返回。可以看到,在这样的情况下,list ()方法也是有可能造成N次查询的。
查询缓存在数据发生任何变化的情况下都会被自动清空。
iterator()方法
Query的iterator()方法处理查询的方式与list()方法是不同的,它首先会使用查询语句得到ID值的列表,然后再使用Session的load()方法得到所需要的对象的值。
在获取数据的时候,应该依据这4种获取数据方式的特点来选择合适的方法。在开发中可以通过设置show_sql选项来输出Hibernate所执行的SQL语句,以此来了解Hibernate查询方法是如何操作数据库的
HQL 连接查询
内链接  : 根据两表的外键查询 inner join  
 
外链接 : 左连接 , rigth 右连接  , left    
fetch 关键词 返回的是对象 在使用时一定要注意
本地查询:
本地查询使用是的Hibernate 的配置文件  添加<Query name="example"> <![CDTAT[
HQL语句   ;;;;
]]</Query>
本地SQL查询:
配置文件 Hibernate 的 <sql-query>
                                  <![CDTAT[
HQL语句   ;;;;
]]
<return></return>
                                <sql-query>
方便使用Hibernate 配置  尽量少写sql 语句
Hibernate 查询方法
Query
实体查询:
String hql=”from User user ”;  
          List list=session.CreateQuery(hql).list();
属性查询:
List list=session.createQuery(“select user.name from User user ”).list();  
for(int i=0;i<list.size();i++){  
System.out.println(list.get(i));  
List list=session.createQuery(“select user.name,user.age from User user ”).list();  
for(int i=0;i<list.size();i++){  
Object[] obj=(Object[])list.get(i);  
System.out.println(obj[0]);  
System.out.println(obj[1]);  
分组和排序 
order by  
from users  u where  order by u.name desc
Group By 分组统计 MAX() MIN() COUNT() AVG() SUM()
优化数据查询
参数绑定: (jdbc参数)
PrepareStatement pre=connection.prepare(“select * from User where user.name=?”);  
pre.setString(1,”zhaoxin”);  
ResultSet rs=pre.executeQuery(); 
按参数名称绑定:

在HQL语句中定义命名参数要用”:”开头,形式如下:

Query query=session.createQuery(“from User user where user.name=:customername and user:customerage=:age ”);  
query.setString(“customername”,name);  
query.setInteger(“customerage”,age); 
上面代码中用:customername和:customerage分别定义了命名参数customername和customerage,然后用Query接口的setXXX()方法设定名参数值,setXXX()方法包含两个参数,分别是命名参数名称和命名参数实际值。

按参数位置邦定:

在HQL查询语句中用”?”来定义参数位置,形式如下:

Query query=session.createQuery(“from User user where user.name=? and user.age =? ”);  
query.setString(0,name);  
query.setInteger(1,age); 
同样使用setXXX()方法设定绑定参数,只不过这时setXXX()方法的第一个参数代表邦定参数在HQL语句中出现的位置编号(由0开始编号),第二个参数仍然代表参数实际值。

注:在实际开发中,提倡使用按名称邦定命名参数,因为这不但可以提供非常好的程序可读性,而且也提高了程序的易维护性,因为当查询参数的位置发生改变时,按名称邦定名参数的方式中是不需要调整程序代码的。
   使用绑定参数的优势:

 我们为什么要使用绑定命名参数?任何一个事物的存在都是有其价值的,具体到绑定参数对于HQL查询来说,主要有以下两个主要优势:

①、                      可以利用数据库实施性能优化,因为对Hibernate来说在底层使用的是PrepareStatement来完成查询,因此对于语法相同参数不同的SQL语句,可以充分利用预  编译SQL语句缓存,从而提升查询效率。

②、 可以防止SQL Injection安全漏洞的产生:
 SQL        Injection是一种专门针对SQL语句拼装的攻击方式,比如对于我们常见的用户登录,在登录界面上,用户输入用户名和口令,这时登录验证程序可能会生成如下的HQL语句:
Criteria
语法   Criteria cri = session.createCriteria(Student.class);
cri.add(Example.create(s)); //s是一个Student对象
list cri.list();
HQL运算符 QBC运算符 含义
=Restrictions.eq()等于
<> Restrictions.not(Exprission.eq())  不等于
>Restrictions.gt()大于
>= Restrictions.ge()大于等于
<= Restrictions.le()小于等于
is null Restrictions.isnull()  等于空值
is not nullRestrictions.isNotNull()  非空值
like  Restrictions.like() 字符串模式匹配
and Restrictions.and()  逻辑与
and Restrictions.conjunction()逻辑与
or Restrictions.or()逻辑或
or Restrictions.disjunction()逻辑或
notRestrictions.not()  逻辑非
in(列表) Restrictions.in()等于列表中的某一个值
ont in(列表)Restrictions.not(Restrictions.in())不等于列表中任意一个值
between x and yRestrictions.between() 闭区间xy中的任意值
not between x and y  Restrictions.not(Restrictions..between()) 小于值X或者大于值y

转载于:https://my.oschina.net/sunzy/blog/71560

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值