【Hibernate】4.hibernate查询与检索

一、查询排序

    1.内存排序  

 使用sort属性,有两个属性值(unsorted,natural),其中natural指的是按照自然的升序排序,第三个属性值是我们自己定义的排序规则类。方式为定义一个类,让其实现Comparator接口,并且实现该接口中的compare方法,在该方法中实现排序规则即可,然后将该自定义方法规则的类名作为sort属性值即可。
         若在配置文件中含有Map对象时,要排序时,在其标签中添加 sort 属性;
         若在配置文件中含有Set对象时,要排序时,在其标签中添加 sort y属性;

    2.数据库排序

        若在配置文件中含有Map对象时,要排序时,在其标签中添加order-by属性;
         若在配置文件中含有Set对象时,要排序时,在其标签中添加order-by属性;
        直接在数据库查询的过程中就进行了排序。

二、多态查询

  Query query = session.createQuery("from java.lang.Object");

三、hibernate检索

     导航对象图检索方式
        根据已经加载的对象,导航到其他对象,如对于已经加载的Customer对象,调用他的getOrders().iterator()方法就可以导航到所有关联的Order对象,加入在关联级别中使用了延迟加载检索策略,那么首次执行此方法时,hibernate会从数据库中加载关联的Order对象,否则就从缓存中取得Order对象。
    OID检索方式
    俺找对象的OID来检索对象,Session的get()和load()方法提供了这种功能。如果在应用程序中事先知道了OID,就可以使用这种检索对象的方式。
    HQL检索方式
        hibernate提供了Query接口,它是hibernate提供的专门的HQL查询接口,能够执行各种复杂的HQL语句。
    QBC检索方式
        使用QBC(Query By Criteria)API来检索对象。这种API封装了基于字符串形式的查询语句,提供了更加面向对象的接口。

 1.HQL检索方式

HQL 是面向对象的查询语言,它和SQL查询语言有些相似。在Hibernate提供的各种检索方式中,HQL是使用最广泛的一种检索方式。具有以下功能:
    a.在查询语句中设定各种查询条件
    b.支持投影查询,即仅检索出对象的部分属性
    c.支持分页查询
    d.支持连接查询
    e.支持分组查询,允许使用having和group by关键字
    f.提供内置聚集函数,如sum()\min()和max()
    g.支持子查询,即嵌入式查询
    h.支持动态绑定参数
 检索步骤:
     // a.创建一个Query对象,通过session创建,包含一个HQL查询语句,可以包含命名参数,如customerName,customerAge
    Query query = session.createQuery("from Customer as c where"+"c.name=:customerName" + " and c.age = :customerAge");
     // b.动态绑定参数 Query提供了给各种类型的命名参数的赋值方法,如setString为String类型赋值
    query.setStirng("customerName","tom");
    query.setInteger("customerAge",21);
     // c.执行相应的方法,返回查询结果,在list集合中存放了符合查询条件的持久化对象
    List result = query.list();
方法编程链风格
List result = session.createQuery("from Customer as c where"+"c.name=:customerName" + " and c.age = :customerAge").setStirng("customerName","tom").setInteger("customerAge",21);

2.QBC检索方式

Criteria接口、Criterion接口和Expression类,运行时动态生成查询语句。
             Expression用来添加条件,同时也支持方法链变成风格
检索步骤
a.调用Session的createCriteria()方法创建一个Criteria对象;
b.设定查询条件,Expression类提供了一系列用于设定查询条件的静态方法,这些静态方法都返回Criterion实例,每个Criterion实例代表一个查询条件,Criteria的add()方法用于加入查询条件;
c.调用Criteria的list()方法返回查询语句。该方法返回list类型的查询结果,在List集合中存放符合查询条件的持久化对象。

2.1Criteria Query
    Criteria criteria = session.createCriteriia(xxx.class);
    criteria.add(Expression.eq("key1","value1"));        
    criteria.add(Expression.eq("key2","value2"));        
    criteria实例本质上是对SQL“Select * from xxx where key1=‘value1’ and key2=‘value2’ ”的封装。其中key1是POJO类的属性名。
针对不同的查询条件,Expression提供了对应的查询限定机制。

在Hibernate3中用Restrictions类作为Expression的替代。
 
    (1)示例查询:用于组合查询较好
        Example类实现了Criterion接口,也可以用作Criteria的查询条件,其作用是:根据已有对象,查找属性与之相符的其他对象。
    Criteria criteria = session.createCriteriia(Xxx.class) ;
    Xxx xxx = new Xxx();    xxx.setKey1("value1");      
    criteria.add(Example.create(xxx));                          上面三行效果等同于criteria.add(Expression.eq("key1","value1")); 
    List list = criteria.list();                                            
    (2)复合查询
    Criteria criteria = session.createCriteriia(Xxx.class) ;  
    Criteria criteria1 = criteria。createCriteria("属性1"); 新增的复合查询条件根据属性1查找。
    criteria1.add(Expression.like("属性","%xx%"));       
    Xxx xxx = new Xxx();    xxx.setKey1("value1");        
    criteria.add(Example.create(xxx));                            上面三行效果等同于criteria.add(Expression.eq("key1","value1")); 
    List list = criteria.list();                                               
 
2.2DetachedCriteria
与前者的区别是Criteria生命周期位于其宿主Session生命周期内,而DetachedCriteria可以脱离Session实例独立存在。这样就可以将通用的Criteria查询条件抽离出来,代码重用。
 
2.3Hibernate Query Language(HQL)
    实体查询,属性查询,更新、删除,分组、排序 参数绑定等其他操作。

 3.分页查询

其实分页不管做法怎样,原理都差不多,就是从数据库里你想一次取出多少条数据来(比如不可能有10万条全取出来)限制取出条数的SQL语法因数据库不同而不同,Hibernate只是帮你选择了正确的数据库方言而已(例如limit/top等SQL方言)
取出来的就是页面一页要显示的,翻页的话,原理就是先在数据库连上之后把游标移动到何时的位置,再从游标处取下一页的数据
public class Pager<T> implements Serializable {
	private static final long serialVersionUID = 1L;
	
	private int pageSize;//每页显示记录数	
	private int currentPage;//当前页数	
	private int totalRecord;//所有记录的个数	
	private int totalPage;//所有记录的页数	
	private List<T> dataList;//要显示的数据信息	
	public Pager() {}
	public Pager(int pageSize, int currentPage, int totalRecord, int totalPage,List<T> dataList) {
		this.pageSize = pageSize;
		this.currentPage = currentPage;
		this.totalRecord = totalRecord;
		this.totalPage = totalPage;
		this.dataList = dataList;
	}	
	public int getPageSize() {
		return pageSize;
	}
	public void setPageSize(int pageSize) {
		this.pageSize = pageSize;
	}
	public int getCurrentPage() {
		return currentPage;
	}
	public void setCurrentPage(int currentPage) {
		this.currentPage = currentPage;
	}
	public int getTotalRecord() {
		return totalRecord;
	}
	public void setTotalRecord(int totalRecord) {
		this.totalRecord = totalRecord;
	}
	public int getTotalPage() {
		return totalPage;
	}
	public void setTotalPage(int totalPage) {
		this.totalPage = totalPage;
	}
	public List<T> getDataList() {
		return dataList;
	}
	public void setDataList(List<T> dataList) {
		this.dataList = dataList;
	}	
}

3.1.常见分页样式
传统分页样式:包含首页、上一页、下一页、尾页等,可以明确获取数据信息
下拉式分页:通过下拉加载下一页,例如qq空间等,所有信息可以在一页显示

3.2常见的实现方式
实现方式优点缺点适用场景
subList简单易用效率低无法按需批量获取数据
SQL语句简单直接效率高数据库兼容性差不要求数据库兼容
Hibernate框架面向对象,兼容性强复杂查询性能低兼容不同数据库
a.使用List接口中的subList(int startIndex,int endIndex)方法实现分页
该方法表示返回列表中指定的fromIndex(包括)和endIndex(不包括)之间的信息。

b.直接使用数据库SQL语句实现分页
mysql、PostgreSQL:关键字为limit
             mysql: select * from t limit 0,10,表示从第0条记录开始取10条记录
             PostgreSQL: select * from t limit 10 offset 0 ,表示从第0条记录开始取10条记录
        oracle:关键字为rownum
select * from (
                   select s.*,rownum rn from
                    (select * from table) s
                where  rownum<=10
                ) where rn>=1
c.使用Hibernate等框架实现跨数据库的分页
Query或Criteria接口都提供了用于分页显示查询结果的方法:
setFirstResult(int firstResult),设置从哪个对象开始检索,参数firstResult表示这个对象在查询结果中的索引位置,索引位置的起始值为0,默认是从0索引开始查询;
setMaxResult(int maxResult),设定一次最多检索出的对象数目,默认情况下,检索出所有对象。

创建Query或Criteria对象,查询时,设置firstResult和maxResult属性
 采用HQL检索
	    String hql = “from table”;
            Query q = session.createQuery(hql);
            q.setFitstResult(0);
            q.setMaxResult(10);
            List l = q.list();
采用QBC检索
1
	    String hql = “from table”;
            Criteria criteria = session.createCriteria(类名.class);
	    criteria.addOrder(Order.asc("属性名"));
	    criteria.setFitstResult(0);

criteria.setMaxResult(10); List l = criteria.list();



         







            q.setFitstResult(0);

版权声明:本文为jianmingxie原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。