`

检索分类

阅读更多
若class的lazy设为false,则get(),load(),find(),都会立即检索。
若class的lazy设为true,表示采用延迟策略,load()返回的是代理类的实例(只有OID存在,其它属性都为null),代理类的特征:代理类继承实际类的所有属性和方法。当程序第一次访问代理类实例时(除访问OID外),才会去数据库加载对象的所有数据。
注:代理类的实例只有在当前session范围内才能被初始化。get(),find(),仍是立即检索。

常用的查询语句(HQl):
连接查询: from Customer c left join fetch c.orders o where c.name like 't%' (orders 集合被初始化)
动态实例化查询: select new com.mypack.CustomerRow(c.id,c.name,o.orderNumber) from Customer c join c.orders o where o.orderNumber like 't%'
distinct关键字:Iterator it=session.createQuery("select distinct c.name from Customer c").list().iterator();
聚集函数:
Object [] os=(Object [])session.createQuery("select max(c.age),min(c.age) from Customer c").uniqueResult();
理解:多列返回Object [] 类型,单列返回Object 类型
子查询:from Customer c where 1<(select count(o) from c.orders o)(相关)
       对应sql:select * from customers c where 1<(select count(o.ID) from orders o where c.ID=o.customer_ID)
       from Order o where o.price >(select avg(o1.price) from Order o1)(无关)

字查询量化关键字:all any some in exists
HQL操纵集合的函数,属性:size,minIndex ,maxIndex,minElement,maxElement elements
eg:from Customer c where c.orders.size>0
   from Customer c where size(c.orders)>0

分组查询:
Iterator it=session.createQuery("select c.name,count(c) from Customer c group by c.name").list().iterator();
while(it.hasNext()){
object [] pair=(Object [])it.next();
String name=(String)pair[0];
Integer count=(Integer)pair[1];
}
oracle下执行存储过程:
create or replace procedure batchUpdateCustomer(p_age in number) as
begin
update CUSTOMERS set AGE=AGE+1 where AGE>p_age;
end;

以上存储过程有一个参数p_age,代表客户的年龄,应用程序可按照以下方式调用存储过程:
tx = session.beginTransaction();
Connection con=session.connection();
String procedure = "{call batchUpdateCustomer(?) }";
CallableStatement cstmt = con.prepareCall(procedure);
cstmt.setInt(1,0); //把年龄参数设为0
cstmt.executeUpdate();
tx.commit();

连接查询总结:
迫切左外连接查询和左外连接查询:
我们看以下代码,这段代码将覆盖映射文件中的检索策略,显示指定采用迫切左外连接查询。

HQL查询方式:
Query query=session.createQuery(“from Customer c left join fetch c.orders o where c.name like ‘zhao%’ ”);
List list=query.list();
HashSet set=new HashSet (list);//这种可能有重复的原素用来过滤的
for(Iterator it=set.iterator();it.hasNext();)
{
  Customer customer=(Customer)it.next();
   .....
}
//QBC检索方式:
List list=session.createCriteria(Customer.class).setFetchMode(“orders”,FetchMode.EAGER)
.add(Expression.like(“name”,”zhao%”,MatchMode.START).list();
for(int i=0;i Customer customer=(Customer)list.get(i);
}
我们看到在HQL以及QBC查询中分别通过left join fetch和FetchMode.EAGER来指定采用迫切左外连接检索策略,当采用了迫切左外连接检索策略时,当进行检索时即执行查询的list()方法时,将会立即初始化用来容纳关联实体的集合对象元素,如果在实体映射配置文件中对关联实体设置了延迟加载,那么此时将会忽略延迟加载设置,而采用迫切左外连接策略,并且立即用关联实体对象填充集合对象元素,即使用Order对象填充Customer对象的orders集合。因此这种检索策略会马上创建关联实体对象,此时我想你一定会想到这种检索策略会同时检索出Customer和Order实体对象对应的数据,并且分别创建这两个对象。恭喜你答对了,因此上面代码会生成类似如下的SQL语句:
Select * from customer c left join order o on c.id=o.id where c.name like ‘zhao%’;
如果我们忽略了fetch关键字,就变成了左外连接查询,如下面代码:
Query query=session.createQuery(“from Customer c left join c.orders o where c.name like ‘zhao%’ ”);
List list=query.list();
for(int i=0;i Object[] objs=(Object[])list.get(i);
Customer customer=(Customer) objs[0];
order order=(Order)objs[1];
}
我们可以看到采用左外连接查询返回的结果集中包含的是对象数组,对象数组中的每个元素存放了一对相互关联的Customer对象和Order对象,而迫切左外连接会返回Customer对象,与Customer对象相关联的Order对象存放在Customer对象的集合元素对象中,这就是迫切左外连接和左外连接查询的其中一个区别(这两种检索生成的SQL语句是一样的),另一个区别是当使用左外连接时,对关联对象的检索会依照实体映射配置文件所指定的策略,而不会像迫切左外连接那样忽略它,比如此时对Customer对象关联的Order对象采用延迟加载,那么左外连接检索也会使用延迟加载机制检索Order对象。
理解:当使用左外连接时和迫切左外连接的时执行的sql是一样的..只不过 left join 没有对应的集合没有关连..当第一次检索时会添加对应的引用的(hibernate 不会再创建象的,对象是已经存在的)

查询性能优化:
1.降低访问数据库的频率,减少sql语句数目:使用迫切左外连接或迫切内连接检索
,使用查询缓存
2.避免多余加载程序不需要访问的数据:使用延迟,集合过滤.
3.避免报表查询数据占用缓存(查询出来的是持久化对象,会存在session缓存中),利用投影查询功能,查询出实体部分属性(查询出来的是关系数据)
4.用第二次查询时..用iterator代替list()(iterator()首先去数据库检索ID字段,然后要据ID字段到Hibernate的第一级缓存以及第二级缓存中查找匹配的Customer对象,如果存在,就直接把它加入到查询结果集中,否则就执行额外的select语句,根据ID字段到数据库检索该对象)
hibernate三种对象的特征:
1.临时(new 下的)
2.持久:位于一个session实例的缓存中,方法有:save(),load(),get(),update()。。
3.游离:不位于session缓存中,与数据库中有对应记录.方法有:session.close().这样session 中的所有持久对象都变成游离的..evict()





分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics