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. 点滴积累【other】---存储过程修改表的所有字段(sql)

    USE [QG_Mis24] GO /****** Object: StoredProcedure [dbo].[p_set] Script Date: 07/11/2013 17:05:38 *** ...

  2. Centos下源码安装git

    1.centos下git版本太久了,才1.8几,而官方更新的还是很活跃的,于是我就想源码安装一个新版本. 2.首先到: https://github.com/git/git/releases 下载最新 ...

  3. Java服务CPU占用高问题定位方法

    1. 概述 提供一种简单的方法来定位CPU高的问题. 找到CPU高的进程,比如232543: 执行top -H -p pid,找到占用CPU最高的线程号,比如232544,转换成16进制38c60: ...

  4. Catalog的种类

    框架中的Catalog 在MEF框架中,包含了4种Catalog,所有的Catalog的是从System.ComponentModel.Composition.Primitives名称空间下的Comp ...

  5. VS编译duilib项目时候的错误解决方法整理

    @1:找不到Riched20.lib 用everything等软件搜索下磁盘.找到所在的文件夹加入到vs的库文件夹就可以.我得是C:\Program Files (x86)\Microsoft SDK ...

  6. uinty实现玩家尾随鼠标位置平滑旋转角度

    首先我们要在场景中加入一个quad平面作为地板, 然后指定Layer为Floor,然后移除mesh renderer组件 然后加入脚本 脚本主要思想是从屏幕中心投出一条射线到地板, 然后获取相应坐标, ...

  7. [Buzz Today]2013.08.18

    # Go 语言实现memcached:groupcache memcached作者Brad Fitzpatrick用Go语言重新实现了memcached. groupcache继承了memcached ...

  8. Windows Azure 系列-- 使用Azure + Web API实现图片上传

    1. 创建1个Azure账号,登录之后创建1个AzureStorage.左下方点Manage Access会看到Primary Access Key和Storage Account,记住它们的位置,等 ...

  9. curl使用例子

    地址:http://phpbook.phpxy.com/34771 参考:http://php.net/manual/zh/function.curl-setopt.php 我们将curl的步骤分为以 ...

  10. win7(64位)+vs2008配置Directshow

    参考链接:http://zhuyanfeng.com/archives/1663 PC环境:win7 64bit + vs2008 1.下载64位的win7 SDK2.安装过程中遇到错误(必须要卸载v ...