【Hibernate】4.hibernate查询与检索

来源:互联网 发布:树莓派python串口编程 编辑:程序博客网 时间:2024/06/05 23:05

一、查询排序

    1.内存排序  

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

    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);
原创粉丝点击