一、查询排序
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);