hibernate学习笔记(四)

目录

一、HQL高级查询

1.1 聚合查询

1.2 投影查询

1.3 多表连接查询

二、Criteria查询

2.1 排序查询

2.2 聚合查询

2.3 离线查询

三、查询优化

3.1 类级别查询

3.2 关联级别查询

3.3 no-session的问题

四、总结


一、HQL高级查询

之前我们已经介绍了简单的基本查询,条件查询和分页查询。

1.1 聚合查询

String hql = "select count(*) from Customer ";  
String hql1 = "select max(id) from Customer ";  
String hql2 = "select min(id) from Customer ";  
String hql3 = "select sum(id) from Customer ";  
String hql4 = "select avg(id) from Customer ";  
                                                
Query query = session.createQuery(hql4);        
Number result = (Number)query.uniqueResult();   

1.2 投影查询

String hql = "select name from Customer ";                    
String hql1 = "select id,name from Customer ";                
String hql2 = "select new Customer(id,name) from Customer ";  
                                                              
Query query = session.createQuery(hql2);                      
List<Customer> list = query.list();                           

hql 查询结果:

hql1 查询结果:

hql2 查询结果(这里需要提供一个类似的构造函数):

public Customer(int id,String name){    
	this.id = id;                       
	this.name = name;                   
}                                       

hql3 查询结果(这里需要提供一个无参构造函数):

public Customer(){ 
	               
}                  

1.3 多表连接查询

连接查询的定义与分别

1.3.1 内连接

String hql = "from Customer c inner join c.linkMen";      
                                                          
Query query = session.createQuery(hql);                   
List<Object[]> list = query.list();                       
for (Object[] objects : list) {                           
	System.out.println(Arrays.toString(objects));         
}                                                         

输出

可以看出每个Object[] 数组中有两个元素,第一个元素Object[0] 是Customer对象,第二个元素Object[1]是LinkMan对象。

1.3.2 左连接

                                                      
String hql = "from Customer c left join c.linkMen";   
                                                      
Query query = session.createQuery(hql);               
List<Object[]> list = query.list();                   
for (Object[] objects : list) {                       
	System.out.println(Arrays.toString(objects));     
}                                                     

输出

删除了一个谷歌的联系人,但是客户表的所有数据都出来了,这就说明是左连接。

1.3.3 右连接

String hql = "from Customer c right join c.linkMen"; 
                                                     
Query query = session.createQuery(hql);              
List<Object[]> list = query.list();                  
for (Object[] objects : list) {                      
	System.out.println(Arrays.toString(objects));    
}                                                    

输出

二、Criteria查询

我们之前已经介绍了Criteria的查询,接下来介绍一些别的查询,因为Criteria查询必须要关联一个类,适合单表的查询,所以并不复杂。

2.1 排序查询

Criteria query = session.createCriteria(Customer.class);  
                                                          
query.addOrder(Order.desc("id"));                         
                                                          
List<Customer> list = query.list();                       
                                                          
System.out.println(list);                                 

输出

2.2 聚合查询

Criteria query = session.createCriteria(Customer.class);  
                                                          
query.setProjection(Projections.avg("id"));               
                                                          
Number result = (Number)query.uniqueResult();             
                                                          
System.out.println(result);                               

输出

2.3 离线查询

 非离线查询:

离线查询:

代码演示:

DetachedCriteria dc = DetachedCriteria.forClass(Customer.class); 
dc.add(Restrictions.idEq(2));                                    
                                                                 
Session session = HibernateUtils.getCurrentSession();            
Transaction tx = session.beginTransaction();                     
                                                                 
Criteria query = dc.getExecutableCriteria(session);              
                                                                 
List<Customer> list = query.list();                              
System.out.println(list);                                        
                                                                 
tx.commit();                                                     

输出

三、查询优化

懒加载的和关联查询的使用。

3.1 类级别查询

get方法:没有任何的加载策略,调用即查询数据库加载数据。

load方法:应用类级别查询的加载策略

<class name="Customer" table="customer" lazy="true">
</class>

在配置文件中配置lazy="true"(默认值),就会使用懒加载策略,查询时会返回代理对象,会在使用属性时,根据关联的session查询。

lazy="false" 时,load和get方法是没有任何区别的,调用即加载数据。

结论:为了提高效率,建议使用延迟加载策略。

注意:使用懒加载时要确保,调用属性加载数据时,session还是打开的,不然会抛出异常。(和ef一样,dbcontext必须是同一个,且没有释放。)

3.2 关联级别查询

一对多加载集合策略

	lazy属性: 决定是否延迟加载
			true(默认值): 延迟加载,懒加载
			false: 立即加载
			extra: 极其懒惰
	fetch属性: 决定加载策略.使用什么类型的sql语句加载集合数据
			select(默认值): 单表查询加载
			join: 使用多表查询加载集合
			subselect:使用子查询加载集合

多对一的关联属性加载策略

fetch 决定加载的sql语句
			select: 使用单表查询
			join : 多表查询
lazy  决定加载时机
			false: 立即加载
			proxy: 由customer的类级别加载策略决定.

结论:为了提高效率,fetch的选择上应该选择select,lazy的取值应选择true。即全部使用默认值,不用管。

3.3 no-session的问题

当我们查询完一个对象时,如果在页面jsp使用其关联属性,一般的我们在service层就完成了查询,关闭了session,这时候再使用关联属性可能就会抛出异常。为了解决session范围的问题,我们可以扩大session的访问,在请求开始的时候打开session,在请求结束的时候关闭session。这和ef的当前请求一个上下文是一样的道理HttpContext.Current.Item["dbContext"] 一样的。

在java中我们使用Filter来拦截请求实现这个功能

四、总结

今天我们学习hibernate的高级查询内容,具体用的时候还要看情况使用。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值