hibernate查询
一、HQL查询
1、简单属性查询
* 单一属性查询,返回结果集属性列表,元素类型和实体类中相应的属性类型一致
* 多个属性查询,返回的集合元素是对象数组,数组元素的类型和对应的属性在实体类中的类型一致
数组的长度取决与select中属性的个数
* 如果认为返回数组不够对象化,可以采用hql动态实例化对象
/*单一属性查询*/
@Test
public void testHQL(){
try {
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
String hql="from Emp";
Query query =session.createQuery(hql);// Create a new instance of Query for the given HQL query string.
List<Emp> list=query.list();// Return the query results as a List.
for (Emp e : list) {
System.out.println(e.getLast_name());
}
tr.commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
/*多个属性查询(返回对象数组)*/
@Test
public void test1(){
try {
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
String hql="select e.last_name,e.salary from Emp e";
Query query=session.createQuery(hql);
List<Object[]> list=query.list();
for (Object[] objects : list) {
for (Object o : objects) {
if(o instanceof String){
System.out.println("Emp name:"+o);
}
if(o instanceof Double){
System.out.println("Emp salary:"+o);
}
}
}
tr.commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
2、实体对象查询
* N + 1问题,在默认情况下,使用query.iterate查询,有可以能出现N+1问题
所谓的N+1是在查询的时候发出了N+1条sql语句
1: 首先发出一条查询对象id列表的sql
N: 根据id列表到缓存中查询,如果缓存中不存在与之匹配的数据,那么会根据id发出相应的sql语句
* list和iterate的区别?
* list每次都会发出sql语句,list会向缓存中放入数据,而不利用缓存中的数据
* iterate:在默认情况下iterate利用缓存数据,但如果缓存中不存在数据有可以能出现N+1问题
/*实体对象查询(使用query.iterate查询,有可以能出现N+1问题)*/
@Test
public void test2(){
try {
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
Query query =session.createQuery("from Emp");
query.list();
session.clear();
System.out.println("=========");
Iterator<Emp> it=query.iterate();// Return the query results as an Iterator.
while(it.hasNext()){
System.out.println(it.next().getLast_name());
}
tr.commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
3、条件查询
/*条件查询
* 可以采用 ?来传递参数(索引从0开始)
* 可以采用 :参数名 来传递参数
* 可以采用拼字符串的方式传递参数
* 如果传递多个参数,可以采用query.setParamterList方法
* 在hql中可以使用数据库的函数,如:date_format*/
@Test
public void test3(){
try {
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
String hql="from Emp e where e.id=:myid";
Emp e=(Emp) session.createQuery(hql)
.setLong("myid",3l)
.uniqueResult();
// //.setLong(0, 3l) e.id=?时
// //.uniqueResult();
// Query query=session.createQuery(hql);
// query.setLong("myid", 3l);
// Emp emp=(Emp) query.uniqueResult();
System.out.println(e.getLast_name());
tr.commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
4、hibernate也支持直接使用sql进行查询
本地sql查询,原生sql
/*本地sql查询(原生sql)*/
@Test
public void test4(){
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
Query q=session.createSQLQuery("select last_name from s_emp");
}
5、外置命名查询 Query By Name
/*外置命名查询
* 1、在映射文件中采用<query>标签来定义hql
* <query name="byId">
<![CDATA[
from Emp where id=1
]]>
</query>
2、在程序中采用session.getNamedQuery(“Name”)方法得到hql串
* */
@Test
public void test5(){
try {
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
Query query=session.getNamedQuery("byId");
Emp e=(Emp) query.uniqueResult();
System.out.println(e.getLast_name());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
6、查询过滤器
/*查询过滤器
* * 1、在映射文件中定义过滤器参数
* <filter-def name="idFilter">
<filter-param name="myid" type="long"/>
</filter-def>
* 2、在类的映射中使用这些参数
* <filter name="idFilter" condition="id > :myid"></filter>
* 3、在程序中启用过滤器*/
@Test
public void test6(){
try {
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
session.enableFilter("idFilter").setParameter("myid", 24l);//允许会话使用指定名称的过滤器,并设置其参数myid=24l
Query query=session.createQuery("from Emp e");
Emp e=(Emp) query.uniqueResult();
System.out.println(e.getLast_name());
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
7、分页查询
* setFirstResult(),从0开始
* setMaxResults,每页显示多少条数据
jdbc怎么分页?
select id
from s_emp
where rownum<30
minus
select id
from s_emp
where rownum<20;
/*分页查询*/
@Test
public void test7(){
try {
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
String hql="from Emp";
Query query=session.createQuery(hql);
query.setFirstResult(0);//从0开始
query.setMaxResults(10);//每页显示多少条数据
List<Emp> list=query.list();
for (Emp emp : list) {
System.out.println(emp.getId()+": "+emp.getLast_name());
}
tr.commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
8、对象导航查询,在hql中采用 . 进行导航
/*对象导航查询
* 比如使用xx.iterator xxx.getxxx*/
@Test
public void test8(){
try {
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
//from Emp where id=1
Emp e=(Emp) session.get(Emp.class, 1l);
Dept d=e.getDept();
System.out.println(d.getName());
tr.commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
9、连接查询
/*连接查询*/
@Test
public void test9(){
try {
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
String hql="select m.id,m.last_name,e.id," +
"e.last_name from Emp e inner join e.manager m";
Query query=session.createQuery(hql);
List<Object[]> list=query.list();
for (Object[] objects : list) {
for (Object object : objects) {
System.out.print(object+" ");
}
System.out.println();
}
tr.commit();
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
10、统计查询
/*统计查询
count()
max()
group by*/
@Test
public void test10(){
//select count(e.salary) from Emp
}
二, QBE (Query By Example)
QBE查询就是检索与指定样本对象具有相同属性值的对象。因此 QBE 查询的关键就是样本对象的创建,样本对象中的所有非空属性均将作为查询条件。 QBE 查询的功能子集,虽然 QBE 没有 QBC 功能大,但是有些场合 QBE 使用起来更为方便。
工具类Example 为 Criteria 对象指定样本对象作为查询条件
Criteria cri = session.createCriteria(Student.class);
cri.add(Example.create(s)); //s是一个 Student 对象
list cri.list();
实质:创建一个模版,比如我有一个表emp 有一个 name 字段,我设置 emp.setName('terry'),
则这个表中的所有的name 为 terry 的数据都会出来
/*QBE (Query By Example)
*
* */
@Test
public void QBETest(){
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
Criteria c=session.createCriteria(Emp.class);//指定查询的样本对象
Emp e=new Emp();
e.setLast_name("Patel");
c.add(Example.create(e));// Create a new instance, which includes all non-null properties by default
List list=c.list();//表中存放所有的last_name 为Patel的数据
System.out.println(list.size());
tr.commit();
}
三,QBC查询方式 Query By Criteria
QBC(Query By Criteria)查询方式是 Hibernate 提供的 “ 更加面向对象 ” 的一种检索方式。 QBC 在条件查询上比 HQL 查询更为灵活,而且支持运行时动态生成查询语句。
在Hibernate 应用中使用 QBC 查询通常经过 3 个步骤
(1)使用 Session 实例的 createCriteria() 方法创建 Criteria 对象
(2)使用工具类 Restrictions 的相关方法为 Criteria 对象设置查询对象Criterion/SimpleExpression
(3)使用 Criteria 对象的 list() 方法执行查询,返回查询结果
Restrictions/Expression类的常用方法
Restrictions.eq(String propertyName,Object value)
等于
Restrictions.allEq(Map propertyNameValues)
使用Map key/value 进行多个等于的比对
Restrictions.gt(String propertyName, Object value)
大于 > (gt----->greater than)
Restrictions.ge(String propertyName, Object value)
大于等于 >= (ge----->greater equal)
Restrictions.It(String propertyName, Object value)
小于< (It---->less than)
Restrictions.Le(String propertyName, Object value)
小于等于<= (le---->less equal)
Restrictions.between(String propertyName, Object lo, Object hi)
对应SQL 语句的 Between 子句
Restrictions.like(String propertyName, Object value)
对应SQL 语句的 LIKE 子句
Restrictions.in(String propertyName, Collection value)
对应SQL 语句的 in 子句
Restrictions.and(Criterion lhs, Criterion rhs)
And关系
Restrictions.or(Criterion lhs, Criterion rhs)
Or关系
Restrictions.sqlRestriction(String sql,Object[] values,Type[] types)
SQL限定查询
工具类Order 提供设置排序方式
Order.asc(String propertyName)
升序排序
Order.desc(String propertyName)
降序排序
工具类Projections 提供对查询结果进行统计与分组操作
Porjections.avg(String propertyName)
求某属性的平均值
Projections.count(String propertyName)
统计某属性的数量
Projections.countDistinct(String propertyName)
统计某属性的不同值的数量
Projections.groupProperty(String propertyName)
指定一组属性值
Projections.max(String propertyName)
某属性的最大值
Projections.min(String propertyName)
某属性的最小值
Projections.projectionList()
创建一个新的projectionList 对象
Projections.rowCount()
查询结果集中记录的条数
Projections.sum(String propertyName)
返回某属性值的合计
/*QBC查询(Query By Criteria)
* (1)使用 Session 实例的 createCriteria() 方法创建 Criteria 对象
(2)使用工具类 Restrictions 的相关方法为 Criteria 对象设置查询对象Criterion/SimpleExpression
(3)使用 Criteria 对象的 list() 方法执行查询,返回查询结果*/
@Test
public void QBCTest(){
Session session=fac.getCurrentSession();
Transaction tr=session.beginTransaction();
Criteria c=session.createCriteria(Emp.class);//指定查询的样本对象
c.add(Restrictions.gt("id", 10l));//(String propertyName, Object value)
c.add(Restrictions.lt("salary", 3000D));//设置查询对象条件
Emp e=(Emp) c.uniqueResult();
System.out.println(e);
tr.commit();
}