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 查询所有

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

2.3 HQL 条件查询

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

2.4 HQL 排序查询

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

2.5 HQL 分页查询

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

2.6 HQL 投影查询

  • 投影查询就是想查询某一字段或某几个字段的值;
  1. // 需求: 查询多个字段
  2. // 第一种方式: 返回的是由这几个字段组成的数组
  3. List<Object[]> list = session.createQuery("select c.cust_name,c.cust_level from Customer c").list();
  4. for(Object[] objects : list){
  5. System.out.println(Arrays.toString(objects));
  6. }
  7. // 第二种方式: 返回只有这几个字段组成的对象
  8. // 1. 需要先在持久化类中提供对应字段的有参构造方法;
  9. // 2. 通过 new 将多个字段封装到对象中, 进行查询;
  10. public class Customer{
  11. private String cust_name;
  12. private Integer cust_age;
  13. private String cust_level;
  14. ...
  15. // 有参构造方法
  16. public Customer(String cust_name, String cust_level){
  17. this.cust_name = cust_name;
  18. this.cust_level = cust_level;
  19. }
  20. // 保留空的构造方法
  21. public Customer(){
  22. super();
  23. }
  24. .....get set 方法
  25. }
  26. List<Customer> list = session.createQuery("select
  27. new Customer(c.cust_name, c.cust_level) from Customer c").list();
  28. for(Customer customer : list){
  29. System.out.println(customer);
  30. }

2.7 HQL 聚合函数

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

3. QBC 检索方式

3.1 QBC 概述

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

3.2 QBC 查询所有

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

3.3 排序查询

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

3.4 分页查询

  • setFirstResult()
  • setMaxResults()
  1. Criteria criteria = session.createCriteria(Customer.class);
  2. // 设置为降序
  3. criteria.addOrder(Order.desc("cust_id"));
  4. // 设置分页的方法
  5. criteria.setFirstResult(0);
  6. criteria.setMaxResults(10);
  7. 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: 判断关联的集合是否为空;
  1. // 查询姓名叫"张三"的客户
  2. Criteria criteria = session.createCriteria(Customer.class);
  3. // 使用 Restrictions 传入条件
  4. criteria.add(Restrictions.eq("name","张三"));
  5. List<Customer> list = criteria.list();
  6. // 查询姓名中包含"小"的客户(模糊查询)
  7. Criteria criteria = session.createCriteria(Customer.class);
  8. criteria.add(Restrictions.like("name","%小%"));
  9. List<Customer> list = criteria.list();
  10. // in 方法
  11. // Restrictions.in(String propertyName, Collection values); // 集合
  12. // Restrictions.in(String propertyName, Object[] values); // 数组
  13. List<Long> params = new ArrayList<Long>();
  14. params.add(1L);
  15. params.add(2L);
  16. params.add(7L);
  17. criteria.add(Restrictions.in("cust_id",params));
  18. // or 方法, 性别为女,或者 cust_id 大于 3
  19. criteria.add(Restrictions.or(Restrictions.eq("cust_gender","女"),Restrictions.gt("cust_id",3L)));

3.6 QBC 聚合函数查询

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

  1. Criteria criteria = session.createCriteria(Customer.class);
  2. // 设置聚合函数
  3. criteria.setProjection(Projections.rowCount());
  4. List<Number> list = criteria.list();
  5. Long count = list.get(0).longValue();
  6. // 注意问题
  7. pubic void fun(){
  8. Session session = HibernateUtils.getCurrentSession();
  9. Transaction tr = session.beginTransaction();
  10. // 创建 QBC 查询接口
  11. Criteria criteria = session.createCriteria(Customer.class);
  12. // 设置聚合函数
  13. criteria.setProjection(Projections.count("cust_id"));
  14. List<Number> list = criteria.list();
  15. Long count = list.get(0).longValue();
  16. // 因为此时的查询语句, 相当于 select count(cust_id) from 表
  17. // 如果想继续查询所有客户,需要 setProjection(null);
  18. criteria.setProjection(null);
  19. // 继续查询所有客户
  20. List<Customer> customers = criteria.list();
  21. for(Customer customer : customers){
  22. System.out.println(customer);
  23. }
  24. }

4. 离线条件查询

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

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

5. SQL 查询方式(了解)

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

6. HQL 多表查询

6.1 SQL 的多表查询

  1. // 内连接查询
  2. // 显示内连接
  3. select * from customer c inner join orders o on c.cid = o.cno;
  4. // 隐式内连接
  5. select * from customer c, orders o where c.cid = o.cno;
  6. // 外连接
  7. // 左外连接
  8. select * from customer c left outer join orders o on c.cid = o.cno;
  9. // 右外连接
  10. select * from customer c right outer join orders o on c.cid = o.cno;

6.2 HQL 的多表查询

  • 非迫切连接: 返回的结果是 Object[];
  • 迫切连接: 返回的结果是对象,
  1. // 使用内连接查询,默认返回的是 Object 数组
  2. Session session = HibernateUtils.getCurrentSession();
  3. Transaction tr = session.beginTransaction();
  4. List<Object[]> list = session.createQuery("from Customer c inner join c.linkmans").list();
  5. for(Object[] objects : list){
  6. System.out.println(Arrays.toString(objects));
  7. }
  8. // 使用 fetch 关键字, 会把返回结果封装到对象中
  9. // fetch 迫切连接
  10. List<Customer> list = session.createQuery("from Customer c inner join fetch c.linkmans").list();
  11. for(Customer customer : list){
  12. System.out.println(customer);
  13. }
  14. // 解决数据重复的问题, 因为 Customer 对象中存在 Set<Linkman> linkmans 集合
  15. // 所以返回的结果, 一个联系人对应一个客户.
  16. // 需要的结果: 一个客户中存在n个联系人. 自己手动 new Set 集合
  17. List<Customer> list = session.createQuery("from Customer c inner join fetch c.linkmans").list();
  18. Set<Customer> set = new HashSet<Customer>(list);
  19. for(Customer customer : set){
  20. System.out.println(customer);
  21. }
  22. // 迫切左外连接
  23. 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. Objective-C_Block

    一.Block语法 Block:块语法,本质上是匿名函数(没有名称的函数),Block变量存放函数的实现,通过Block变量能直接调⽤函数.标准C里面没有Block.C语言的后期扩展版本号.加⼊了匿名 ...

  2. C#Lpt端口打印类的操作浅析

    C#LPT端口打印类的操作是什么呢?首先让我们看看什么是LPT端口(打印机专用)?LPT端口是一种增强了的双向并行传输接口,在USB接口出现以前是扫描仪,打印机最常用的接口.最高传输速度为1.5Mbp ...

  3. makefile之命令包&多行变量

    define&endef 1. 命令包(canned recipes)&多行变量(muti-line variables) The define directive is follow ...

  4. ssh远程主机的免密登录配置

    ssh经常登录远程主机,需要输入密码,很麻烦,怎样变懒呢? test environment:      hostA:ubuntu14.04  username:frank ip:192.168.1. ...

  5. oracle序列在insert into 语句中的使用

    很多人创建了序列,但是在插入语句中不知道怎么使用,在此做个简单介绍. oracle序列有两个参数:nextval和currval,使用的时候,需要输入sequence_name.nextval或seq ...

  6. hadoop 调试mapperduce

    问题描述 运行hadoop的MapReduce示例,在running job卡住 在页面中显示一直处于 ACCEPTED Applications 状态 修改日志级别export HADOOP_ROO ...

  7. 类加载器与Web容器

    在关于类加载器中已经介绍了Jvm的类加载机制,然而对于运行在Java EE容器中的Web应用来说,类加载器的实现方式与一般的Java应用有所不同.不同的Web容器的实现方式也会有所不同. Tomcat ...

  8. APACHE支持.htaccess

    需要开启.htacess功能需要以下三步: 1 2 3 4 5 6 7 8 9 1.打开httpd.conf 将Options FollowSymLinks  AllowOverride None  ...

  9. pl/sql 实例精解 06

    1. 简单循环 1: LOOP 2: statement1; 3: statement2; 4: EXIT WHEN condition; 5: END LOOP; 6: statement3; 也可 ...

  10. C++ 函数模板一(函数模板定义)

    //函数模板定义--数据类型做参数 #include<iostream> using namespace std; /* 函数模板声明 1.函数模板定义由模板说明和函数定义组成,并且一个模 ...