1. Hibernate 框架的查询方式

  • 唯一标识OID的检索方式: session.get(对象.class, OID)
  • 对象导航的方式;
  • HQL 检索方式;
  • QBC 检索方式;
  • SQL 检索方式

2. HQL 检索方式

2.1 HQL 与 SQL 的关系

  • HQL: Hibernate Query Language; 使用的是 Query 接口;
  • HQL 查询语句是面向对象的. Hibernate 负责解析 HQL 查询语句,然后根据对象-关系映射文件中的映射信息,把 HQL

    查询语句翻译成相应的 SQL 语句;
  • HQL 查询语句中的主体是域模型中的类及类的属性;
  • SQL 查询语句中的主体是数据库表及表的字段;

2.2 HQL 查询所有

// 查询所有客户
// 第一种方式:
// 创建 HQL 的查询接口(即 Query 接口)
Query query = session.createQuery("from Customer");
List<Customer> list = query.list(); // 第二种方式: 方法链
List<Customer> list = session.createQuery("from Customer").list(); // 第三种方式: 使用别名的方式
List<Customer> list = session.createQuery("from Customer c").list();
List<Customer> list = session.createQuery("select c from Customer c").list();

2.3 HQL 条件查询

// 第一种方式:
Query query = session.createQuery("from Customer where name=?");
query.setString(0,"张三"); // 给第一个问号赋值
List<Customer> list = query.list(); // 第二种方式:
Query query = session.createQuery("from Customer where name= :aaa and age= :bbb");
query.setString("aaa","张三");
query.setInteger("bbb",39);
List<Customer> list = query.list(); // 第三种方式:
Query query = session.createQuery("from Customer where name=?");
query.setParameter(0,"张三"); // "setParameter" 不用考虑参数的具体类型;

2.4 HQL 排序查询

// 升序
session.createQuery("from Customer order by cust_id").list(); // 降序
session.createQuery("from Customer order by cust_id desc").list();

2.5 HQL 分页查询

// Hibernate 框架提供了关于分页的两个方法
// setFirstResult(a) : 从哪条记录开始,如果查询是从第一条记录开始, 值是 0;
// setMaxResults(b) : 每页查询的记录条数; List<LinkMan> list = session.creatQuery("from Customer").setFirstResult(0)
.setMaxResults(10).list();

2.6 HQL 投影查询

  • 投影查询就是想查询某一字段或某几个字段的值;
// 需求: 查询多个字段
// 第一种方式: 返回的是由这几个字段组成的数组
List<Object[]> list = session.createQuery("select c.cust_name,c.cust_level from Customer c").list();
for(Object[] objects : list){
System.out.println(Arrays.toString(objects));
} // 第二种方式: 返回只有这几个字段组成的对象
// 1. 需要先在持久化类中提供对应字段的有参构造方法;
// 2. 通过 new 将多个字段封装到对象中, 进行查询; public class Customer{
private String cust_name;
private Integer cust_age;
private String cust_level;
... // 有参构造方法
public Customer(String cust_name, String cust_level){
this.cust_name = cust_name;
this.cust_level = cust_level;
} // 保留空的构造方法
public Customer(){
super();
} .....get 和 set 方法 } List<Customer> list = session.createQuery("select
new Customer(c.cust_name, c.cust_level) from Customer c").list();
for(Customer customer : list){
System.out.println(customer);
}

2.7 HQL 聚合函数

  • count()
  • sum()
  • avg()
  • min()
  • max()
// 1. 获取总的记录数
// List<Number> list = session.createQuery("select count(*) from Customer").list();
List<Number> list = session.createQuery("select count(c) from Customer c").list();
Long count = list.get(0).longValue();
System.out.println(count); // 2. 获取某一列数据的和
List<Number> list = session.createQuery("select sum(c.cust_id) from Customer c").list();
Long count = list.get(0).longValue();
System.out.println(count);

3. QBC 检索方式

3.1 QBC 概述

  • QBC,Query By Criteria, 使用 Criteria 接口;
  • 完全面向对象;
  • 非常适合做条件查询;

3.2 QBC 查询所有

// 查询所有记录
Criteria criteria = session.createCriteria(Customer.class);
List<Customer> list = criteria.list();

3.3 排序查询

  • 使用 addOrder() 方法来设置参数; org.hibernate.criterion.Order
    Criteria criteria = session.createCriteria(Customer.class);
// 设置为降序
criteria.addOrder(Order.desc("cust_id"));
List<Customer> list = criteria.list();

3.4 分页查询

  • setFirstResult()
  • setMaxResults()
    Criteria criteria = session.createCriteria(Customer.class);
// 设置为降序
criteria.addOrder(Order.desc("cust_id")); // 设置分页的方法
criteria.setFirstResult(0);
criteria.setMaxResults(10); List<Customer> list = criteria.list();

3.5 QBC 条件查询

  • 条件查询使用 Criteria 接口的 add 方法,用来传入条件;
  • Criterion 接口,表示查询的条件;
  • Restrictions 类是 Hibernate 框架提供的工具类,不是 Criterion 接口的实现类;用来设置查询条件;
  • Restrictions 中常用方法:
    • eq(等于), gt(大于), lt(小于)
    • ge(大于等于), le(小于等于)
    • between: 在...之间, 头和尾都包含;
    • like: 模糊查询;
    • in: 范围;
    • and: 并且;
    • or: 或者;
    • isNull: 判断值是否为空;
    • isEmpty: 判断关联的集合是否为空;
// 查询姓名叫"张三"的客户
Criteria criteria = session.createCriteria(Customer.class); // 使用 Restrictions 传入条件
criteria.add(Restrictions.eq("name","张三"));
List<Customer> list = criteria.list(); // 查询姓名中包含"小"的客户(模糊查询)
Criteria criteria = session.createCriteria(Customer.class);
criteria.add(Restrictions.like("name","%小%"));
List<Customer> list = criteria.list(); // in 方法
// Restrictions.in(String propertyName, Collection values); // 集合
// Restrictions.in(String propertyName, Object[] values); // 数组 List<Long> params = new ArrayList<Long>();
params.add(1L);
params.add(2L);
params.add(7L); criteria.add(Restrictions.in("cust_id",params)); // or 方法, 性别为女,或者 cust_id 大于 3
criteria.add(Restrictions.or(Restrictions.eq("cust_gender","女"),Restrictions.gt("cust_id",3L)));

3.6 QBC 聚合函数查询

  • Projections 是 Hibernate 框架的工具类,用来设置聚合函数查询; org.hibernate.criterion包下
  • 需要使用 criteria.setProjection() 来添加条件;

    Criteria criteria = session.createCriteria(Customer.class);
// 设置聚合函数
criteria.setProjection(Projections.rowCount()); List<Number> list = criteria.list();
Long count = list.get(0).longValue(); // 注意问题
pubic void fun(){
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction(); // 创建 QBC 查询接口
Criteria criteria = session.createCriteria(Customer.class);
// 设置聚合函数
criteria.setProjection(Projections.count("cust_id"));
List<Number> list = criteria.list();
Long count = list.get(0).longValue(); // 因为此时的查询语句, 相当于 select count(cust_id) from 表
// 如果想继续查询所有客户,需要 setProjection(null);
criteria.setProjection(null); // 继续查询所有客户
List<Customer> customers = criteria.list();
for(Customer customer : customers){
System.out.println(customer);
}
}

4. 离线条件查询

  • 离线条件查询使用的是 DetachedCriteria 接口进行查询;
  • 离线条件查询对象在创建的时候,不需要使用 session 对象, 只是在查询的时候,使用 session 对象;
  • 可以在 WEB 层创建离线条件查询对象;

    Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction(); // 创建离线条件查询对象
DetachedCriteria criteria = DetachedCriteria.forClass(Customer.class); // 设置查询条件
criteria.add(Restrictions.eq("cust_gender","男"));
// 查询数据, 需要使用 session
List<Customer> list = criteria.getExecutableCriteria(session).list();
for(Customer customer : list){
System.out.println(customer);
} tr.commit();

5. SQL 查询方式(了解)

    Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction(); SQLQuery sqlQuery = session.createSQLQuery("select * from cust_customer where cust_gender = ?");
sqlQuery.setParameter(0,"男"); // 将返回结果(是List<Object[]> 类型), 封装到对象中
sqlQuery.addEntity(Customer.class);
List<Customer> list = sqlQuery.list(); for(Customer customer : list){
System.out.println(customer);
} tr.commit();

6. HQL 多表查询

6.1 SQL 的多表查询

// 内连接查询
// 显示内连接
select * from customer c inner join orders o on c.cid = o.cno;
// 隐式内连接
select * from customer c, orders o where c.cid = o.cno; // 外连接
// 左外连接
select * from customer c left outer join orders o on c.cid = o.cno;
// 右外连接
select * from customer c right outer join orders o on c.cid = o.cno;

6.2 HQL 的多表查询

  • 非迫切连接: 返回的结果是 Object[];
  • 迫切连接: 返回的结果是对象,
// 使用内连接查询,默认返回的是 Object 数组
Session session = HibernateUtils.getCurrentSession();
Transaction tr = session.beginTransaction(); List<Object[]> list = session.createQuery("from Customer c inner join c.linkmans").list();
for(Object[] objects : list){
System.out.println(Arrays.toString(objects));
} // 使用 fetch 关键字, 会把返回结果封装到对象中
// fetch 迫切连接
List<Customer> list = session.createQuery("from Customer c inner join fetch c.linkmans").list();
for(Customer customer : list){
System.out.println(customer);
} // 解决数据重复的问题, 因为 Customer 对象中存在 Set<Linkman> linkmans 集合
// 所以返回的结果, 一个联系人对应一个客户.
// 需要的结果: 一个客户中存在n个联系人. 自己手动 new Set 集合
List<Customer> list = session.createQuery("from Customer c inner join fetch c.linkmans").list();
Set<Customer> set = new HashSet<Customer>(list); for(Customer customer : set){
System.out.println(customer);
} // 迫切左外连接
List<Customer> list = session.createQuery("from Customer c left join fetch c.linkmans").list();

7. HQL 框架之延迟加载

  1. 延迟加载先获取到代理对象,当真正使用到该对象中的属性的时候,才会发送 SQL 语句, 是 Hibernate 框架提升性能的方式;
  2. 类级别的延迟加载
    • session 对象的 load() 方法就是延迟加载;
    • Customer c = session.load(Customer.class, 1L)

      没有发送 SQL 语句, 当使用该对象的属性时,才发送 SQL 语句
    • 使类级别的延迟加载失效(两种方法)
      • <class> 标签上配置 lazy="false";
      • Hibernate.initialize(Object proxy);
  3. 关联级别的延迟加载
    • 查询某个客户下的所有联系人, 默认是延迟加载;

8. Hibernate 框架关联级别的查询优化策略

8.1 查询策略

  • 使用 Hibernate 框架查询一个对象的时候,查询其关联对象,应该如何查询. 是 Hibernate 框架的一种优化手段;

8.2 Hibernate 框架的查询策略解决的问题

  1. 查询的时机

    • lazy属性解决查询的时机问题,表示是否需要延迟加载;
  2. 查询的语句形式
    • fetch属性解决查询语句的格式问题;

8.3 在 <set> 标签上使用 fetchlazy 属性

  1. fetch 的取值:

    • select: 默认值,发送基本select语句查询;
    • join: 连接查询,发送的是一条迫切左外连接! 配置了该属性,lazy属性就失效了;
    • subselect: 子查询,发送一条子查询,查询关联对象;
  2. lazy 的取值
    • true: 默认延迟;
    • false: 不延迟;
    • extra: 及其懒惰;
  3. 总结: 开发中, 基本上使用的都是默认值: fetch = select, lazy=true;

8.4 在 <many-to-one> 标签上使用 fetchlazy 属性

  1. fetch 的取值

    • select: 默认值,发送基本select语句查询;
    • join: 发送迫切左外连接查询;
  2. lazy 的取值
    • false: 不采用延迟加载;
    • proxy: 默认值,代理;表示由另一端 <class> 上的 lazy 属性决定;

参考资料

Hibernate 的查询的更多相关文章

  1. hibernate模糊查询

    hibernate模糊查询-Restrictions.ilike & Expression.like Criteria criteria = session.createCriteria(Ta ...

  2. Hibernate的查询方式总结

    Hibernate的查询方式大体有三种,分别是HQL QBC和SQL三种.在网上查阅一一些资料,做了一个简单的总结. 1. SQL sql 是面向数据库表查询,from 后面跟的是表名,where 后 ...

  3. atitit。 hb Hibernate sql 查询使用

    atitit. hb  Hibernate sql 查询使用 #----------返回list<map>法..这个推荐使用.      q.setResultTransformer(Tr ...

  4. Hibernate高级查询QBC条件设置——Restrictions用法 引自:http://www.cnblogs.com/evon168/archive/2010/10/29/1863059.html

    方法说明 方法 说明 Restrictions.eq = Restrictions.allEq 利用Map来进行多个等于的限制 Restrictions.gt > Restrictions.ge ...

  5. Hibernate HQL查询:

    Hibernate HQL查询:Criteria查询对查询条件进行了面向对象封装,符合编程人员的思维方式,不过HQL(Hibernate Query Lanaguage)查询提供了更加丰富的和灵活的查 ...

  6. Hibernate HQL查询语句总结

    Hibernate HQL查询语句总结 1. 实体查询:有关实体查询技术,其实我们在先前已经有多次涉及,比如下面的例子:String hql="from User user ";L ...

  7. Hibernate的查询,二级缓存,连接池

    Hibernate的查询,二级缓存,连接池 1.Hibernate查询数据 Hibernate中的查询方法有5中: 1.1.Get/Load主键查询 使用get或者load方法来查询,两者之间的区别在 ...

  8. hibernate sql查询转换成VO返回list

    hibernate sql查询转换成VO @Override public List<FenxiVo> getTuanDuiFenxiList(FenxiVo FenxiVo,Intege ...

  9. Struts2学习笔记NO.1------结合Hibernate完成查询商品类别简单案例(工具IDEA)

    Struts2学习笔记一结合Hibernate完成查询商品类别简单案例(工具IDEA) 1.jar包准备 Hibernate+Struts2 jar包 struts的jar比较多,可以从Struts官 ...

  10. Hibernate【查询、连接池、逆向工程】

    前言 在Hibernate的第二篇中只是简单地说了Hibernate的几种查询方式....到目前为止,我们都是使用一些简单的主键查询阿...使用HQL查询所有的数据....本博文主要讲解Hiberna ...

随机推荐

  1. Effective Java-第二章

    第1章 如何最有效地使用Java程序设计语言机器基本类库:java.lang,java.util,java.util.concurrent和java.io. Sun JDK1.6_05版本 第2章 创 ...

  2. Atitit.提升软件Web应用程序 app性能的方法原理 h5 js java c# php python android .net

    Atitit.提升软件Web应用程序 app性能的方法原理 h5 js java c# php python android .net 1. 提升单例有能力的1 2. 减少工作数量2 2.1. 减少距 ...

  3. ios的设计原则

    ios的设计原则 iOS设计的详细的主要宗旨例如以下: 1.易操作,所关心的主题清新 2.UI控件布局合理,图片质量清新 3.用户的使用习惯 4.字体的大小,主次分明 5.舒适的动画效果 在创建一个新 ...

  4. 设计模式_EventObject和EventListener

    一.事件机制基本概念 java中的事件机制的参与者有3种角色: 1.event object:事件状态对象,用于listener的相应的方法之中,作为参数,一般存在与listerner的方法之中 2. ...

  5. jsp的页面包含——静态包含、动态包含

    一.静态包含:包含的文件可以是jsp文件.html文件.文本文件或者一段java代码.<%@ include file="要包含的文件路径"%> 实质是先将所包含的文件 ...

  6. 跟着百度学PHP[15]-SESSION的应用/网站登陆案例完整案例

    先把几个应该要有的页面建立好.

  7. 1.2.1 Fragments - 碎片

    在activity中,Fragment代表了一种行为和用户界面的一部分.在一个activity里,你可以联合多个fragment来创建一个多面板的UI,你也可以在多个activity里重复使用同一个f ...

  8. poj3041 Asteroids 匈牙利算法 最小点集覆盖问题=二分图最大匹配

    /** 题目:poj3041 Asteroids 链接:http://poj.org/problem?id=3041 题意:给定n*n的矩阵,'X'表示障碍物,'.'表示空格;你有一把枪,每一发子弹可 ...

  9. Hive学习笔记——Hive中的分桶

    对于每一个表(table)或者分区, Hive可以进一步组织成桶,也就是说桶是更为细粒度的数据范围划分.Hive也是针对某一列进行桶的组织.Hive采用对列值哈希,然后除以桶的个数求余的方式决定该条记 ...

  10. win下如何查看那个网络端口被那个应用程序使用

    在运行里面键入cmd打开命令行窗口.     在命令行窗口键入命令: netstat -ano 第一和第二列是自己网络的端口和外网连接的端口,pid:(全称Process Identification ...