一、Hibernate查询

1.Hibernate检索(查询)方式的分类

  • OID检索 :根据主键查询,get/load

  • 对象导航检索 :通过一个对象获得其关联对象.【重点】

    Category category = session.get(Category.class, 1);
    Set<Product> products = category.getProducts();
  • HQL检索 :HQL,Hibernate Query Language(Hibernate查询语言,语法与SQL类似,但是又是面向对象的 ) 【掌握】

  • QBC检索 :QBC,Query By Criteria(条件查询,更加面向对象的查询方式) 【掌握】

  • SQL检索 :SQL,使用原生SQL进行查询 【了解】

2.HQL查询

2.1概述

​   HQL:Hibernate Query Language。 是面向对象(在sql里面的列名在hql里面应该写属性名)的查询语言, 它和SQL查询语言有些相似。

​ 语法:

String hql =...

Query query = session.createQuery(hql);

  • list(); 查询多个

  • uniqueResult();查询一个

    ​原则: 把表名改成类名, 把数据库的列改成Java里面的属性名

2.2基本查询
2.2.1查询所有
  • 查询所有的分类

     //查询所有的分类
    @Test
    public void fun01(){
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction(); //String hql = "select c from Category c";
    String hql = "from Category";
    Query query = session.createQuery(hql);
    List<Category> list = query.list();
    for (Category category : list) {
    System.out.println(category.toString());
    } transaction.commit();
    session.close();
    }
2.2.2条件查询
  • 大于,小于,大于等于,大于小于查询

     //查询id大于1的分类
    @Test
    public void fun02(){
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction(); /*String hql = "from Category where cid > ?";
    Query query = session.createQuery(hql);
    query.setInteger(0, 1);*/ String hql = "from Category where cid > :类别id";
    Query query = session.createQuery(hql);
    query.setInteger("类别id", 1);
    List<Category> list = query.list();
    for (Category category : list) {
    System.out.println(category.toString());
    } transaction.commit();
    session.close();
    }
  • like查询

     //查询商品名包含iPhone的商品
    @Test
    public void fun03(){
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction(); String hql = "from Product where pname like ?";
    Query query = session.createQuery(hql);
    query.setString(0, "%iPhone%");
    List<Product> list = query.list();
    for (Product product: list) {
    System.out.println(product.toString());
    } transaction.commit();
    session.close();
    }
  • between and查询

    String hql = "from Product where price between ? and ?";
    Query query = session.createQuery(hql);
    query.setDouble(0, 2000);
    query.setDouble(1, 5000);
    List<Product> list = query.list();
  • in 查询

     @Test
    //查询pid在(2,8,11,12,100)的商品信息
    public void fun05(){
    Session session = HibernateUtils.getCurrentSession();
    Transaction transaction = session.beginTransaction(); //String sql = "select * from t_product where pid in(?,?,?,?)";
    String hql = "from Product where pid in(?,?,?,?)";
    Query query = session.createQuery(hql);
    //设置参数,查询
    List list = query.setInteger(0, 2).setInteger(1, 8).setInteger(2, 11).setInteger(3, 12).list(); System.out.println(list.toString()); transaction.commit();

    }
2.3.聚合查询
  • 统计类别的个数

    String hql = "select count(*) from Category";
    Query query = session.createQuery(hql);
    Long n = (Long) query.uniqueResult();
    System.out.println(n.intValue());
2.4分组查询
  • 统计各个类别的商品数量

    String hql = "select category.cid, count(*) from Product group by category.cid";
    Query query = session.createQuery(hql);
    List<Object[]> list = query.list();
    for (Object[] objects : list) {
    System.out.println(Arrays.toString(objects));
    }
2.5排序查询
  • 安照商品价格(升序)查询所有的商品

    String hql = "from Product order by price asc";
    Query query = session.createQuery(hql);
    List<Product> list = query.list();
    for (Product product : list) {
    System.out.println(product);
    }
2.6.分页查询

​ setFirstResult:设置开始查询的下标,最小取值是0,0代表第一条记录

​ setMaxResults: 设置查询结果显示的条数。

  • 显示第一页的数据,一页显示4条

    String hql = "from Product";
    Query query = session.createQuery(hql);
    query.setFirstResult(0);
    query.setMaxResults(4);
    List<Product> list = query.list();
    for (Product product : list) {
    System.out.println(product);
    }
2.7 投影查询

​ 查询指定字段

  • 查询商品的名字和价格

    String hql = "select pname, price from Product";
    Query query = session.createQuery(hql);
    List<Object[]> list = query.list();
    for (Object[] objects : list) {
    System.out.println(Arrays.toString(objects));
    }

3.QBC查询

3.1概述

​   QBC,Query By Criteria(条件查询,更加面向对象的查询方式)

3.2常见的条件查询
  • 语法

    //创建QBC条件查询
    Criteria criteria = session.createCriteria(Class);
    //添加条件
    criteria.add(Restrictions.api...);
    //查询多个
    List list = criteria.list();
    //或者查询一个
    Object object = criteria.uniqueResult();
运算符 条件API 描述
= Restrictions.eq() 等于
> Restrictions.gt() 大于
< Restrictions.lt() 小于
>= Restrictions.ge() 大于等于
<= Restrictions.le() 小于等于
between Restrictions.between() 在某个范围内
like Restrictions.like() 模糊查询
in Restrictions.in() 在...中
and Restrictions.and() 并且
or Restrictions.or() 或者
  • Java代码

     // 条件查询
    @Test
    public void fun01() {
    Session session = HibernateUtils.openSession();
    Transaction transaction = session.beginTransaction();

    Criteria criteria = session.createCriteria(Product.class);
    List<Product> list = criteria.add(Restrictions.between("price", 2000.0, 3000.0)).list();
    for (Product product : list) {
    System.out.println(product.toString());
    } transaction.commit();
    session.close();
    }
    //and 查询; 查询商品名以iP开头的并且价格大于4000的商品
    Criteria criteria = session.createCriteria(Product.class);
    List<Product> list = criteria.add(Restrictions.like("pname", "iP%")).add(Restrictions.gt("price", 4000.0)).list();
    //or查询;  查询价格大于3000的或者pid=1的商品
    Criteria criteria = session.createCriteria(Product.class);
    List<Product> list = criteria.add(Restrictions.or(Restrictions.gt("price", 3000.0)).add(Restrictions.eq("pid", 1))).list();
3.3.聚合查询
  • 语法

    //创建QBC条件查询
    Criteria criteria = session.createCriteria(Class);
    //设置聚合
    criteria.setProjection(Projections.api...);
    //查询出结果
    long result = (long) criteria.uniqueResult();
    运算符 条件API 描述
    sum Projections.sum() 求和
    count Projections.count() 计数
    max Projections.max() 最大值
    min Projections.min() 最小值
    avg Projections.avg() 平均值
  • 统计商品的数量

    Criteria criteria = session.createCriteria(Product.class);
    Object result = criteria.setProjection(Projections.count("pid")).uniqueResult();
    System.out.println("result="+result);
  • 多项聚合

  • //创建QBC条件查询
    Criteria criteria = session.createCriteria(Class);
    //添加多种聚合
    ProjectionList list = Projections.projectionList();
    list.add(Projections.api...);
    ...
    //设置聚合
    criteria.setProjection(list);
    //查询出结果
    Object[] result = (Object[]) criteria.uniqueResult(); //实例
    //统计每一个类别下的商品数量 cid count(pid) 两个聚合条件
    Criteria criteria = session.createCriteria(Product.class);
    ProjectionList projectionList = Projections.projectionList();
    projectionList.add(Projections.groupProperty("category.cid"));
    projectionList.add(Projections.count("pid"));
    List<Object[] > list = criteria.setProjection(projectionList).list();
3.4分组查询
  • 统计不同类别下商品的数量

    Criteria criteria = session.createCriteria(Product.class);
    ProjectionList projectionList = Projections.projectionList();
    projectionList.add(Projections.count("pid")).add(Projections.groupProperty("category.cid"));

    List<Object[]> list = criteria.setProjection(projectionList).list();
    for (Object[] objects : list) {
    System.out.println(Arrays.toString(objects));
    }
3.5排序查询
  • 语法

    //创建QBC条件查询
    Criteria criteria = session.createCriteria(Class);
    //添加排序
    criteria.addOrder(Order.api...);
    //查询出结果
    List list = criteria.list();
    运算符 条件API 描述
    desc Order.desc() 降序
    asc Order.asc() 升序
3.6.分页查询

​ setFirstResult:设置开始查询的下标,最小取值是0,0代表第一条记录 设置a

​ setMaxResults: 设置查询结果显示的条数。 设置 b

3.7离线条件查询

​   我们之前也执行过条件查询,不过这些条件查询都是先创建了Criteria对象,然后再不断的追加条件。这种情况在提交比较少的时候,看上去是还不错的。 假如我们这些参数都是要上层service 传递过来的,那么显得就不是那么好看了。所以我们想想能否在外面先封装好了,然后直接给我一个总的条件即可。 这个总的条件,就是包含了前面的所有的条件。这就是离线条件查询。 意思是,可以现在前面先封装条件, 脱离session 创建出Criteria这个情况。

  • 语法

    //创建离线的DetachedCriteria对象
    DetachedCriteria detachedCriteria = DetachedCriteria.forClass(User.class);
    //设置条件
    detachedCriteria.add(Restrictions.like("u_name", "%奥%"));
    //转成可执行状态
    Criteria criteria = detachedCriteria.getExecutableCriteria(session); List<User> list = criteria.list();

4,SQL查询【了解】

  • Eg

    String sql = "select * from t_product";
    SQLQuery sqlQuery = session.createSQLQuery(sql);
    sqlQuery.addEntity(Product.class);

    List<Product> list = sqlQuery.list(); for (Product product : list) {
    System.out.println(product.toString());
    }

5.连接查询

5.1MySql里面的多表查询
5.1.1交叉查询
  • 语法

    select * from A,B
5.1.2内连接查询
  • 隐式内连接查询

     select * from A ,B where A.id = B.id;
  • 显示内连接

    select * from A inner join B on A.id = B.id;
5.1.3外连接查询
  • 左外连接

     select * from A left outer join B on A.id = B.id;
  • 右外连接

     select * from A right outer join B on A.id = B.id;
5.2 HQL连接查询
5.2.1类别
  • 交叉连接

  • 内连接:内连接、迫切内连接

  • 外连接:​左外连接、右外连接

    连接类型 语法
    内连接 inner join 或者 join
    迫切内连接 inner join fetch 或者 join fetch
    左外连接 left outer join 或者 left join
    迫切左外连接 left outer join fetch 或者 left join fetch
    右外连接 right outer join 或者 right join
    迫切右外连接 right outer join fetch 或者 right join fetch
5.2.2内连接

​ 内连接查询可以获取两表的公共部分的记录。

  • HQL内连接(发送三条查询语句)

    String hql = "from Category c inner join c.products";
    Query query = session.createQuery(hql);
    List<Object[]> list = query.list();
  • HQL迫切内连接(发送一条查询语句)

    //String hql = "from Category c inner  join fetch c.products";
    String hql = "select distinct c from Category c inner join fetch c.products";
    Query query = session.createQuery(hql);
    List<Category> list = query.list();
5.2.3外连接
  • HQL左外连接

    String hql = "from Category c left outer join  c.products";
    List<Object[]> list = session.createQuery(hql).list();
  • HQL迫切左外连接

    String hql = "from Category c left outer  join fetch c.products";
    List<Category> list = session.createQuery(hql).list();

  总结:

    • ​ 迫切连接是Hibernate独有的查询方式,迫切内连接比内连接多一个关键字fetch
    • ​ 内连接查询结果中为Object[]数组
    • ​ 迫切内连接查询结果为具体对象

二、查询优化

1、类级别延迟加载

1.1 描述

​ 懒加载默认是开启的.一般不需要修改

​ session.get(): 非懒加载方法

​ session.load(): 默认就是是懒加载

1.2使load懒加载失效

​  在映射配置文件的<class>标签上配置lazy=”false”

<class name="com.pri.bean.Category" table="t_category" lazy="false">

2.关联级别的懒加载

2.1 概述

​   当查询对应的对象时候, 是否立即查询出其关联的对象; eg: 查询id的为1分类,是否立即查询出是该类别下的商品

​   一般通过 '抓取策略' 和 '懒加载' 配合起来优化查询.抓取策略:意思是抓取其关联对象,在<set>和<many-to-one>标签上有一个fetch属性,fetch控制发送什么类型的语句来抓取其关联的对象

​   fetch: 抓取策略 :控制发送什么类型的Sql语句 sql语句:就是对表查询(连接)

​   lazy: 懒或者不懒

2.2set的懒加载
2.2.1描述

在一的一方操作,即在set标签上配置 fetch 和 lazy

  • fetch:控制的是查询其关联对象的时候采用的SQL语句的格式.

    fetch的取值 发送的SQL语句类型
    select:默认值 发送一条select语句查询其关联对象.
    join 发送一条迫切左外连接查询关联对象.
    subselect 发送一条子查询查询其关联对象.
  • lazy:控制的是查询其关联对象的时候是否采用延迟加载的策略.

    lazy的取值 含义
    true(默认值) 默认查询关联对象的时候采用延迟加载.
    false 查询关联对象的时候 不采用延迟加载
    extra 及其懒惰. 查询关联对象的时候 采用比延迟加载更懒惰的方式进行查询.
2.2.2例子

​ 下面的操作都是在在一的一方操作,即在set标签上配置 fetch 和 lazy

  • 当fetch取值为select的时候

    fetch的取值 lazy的取值 结果
    select true 多方在使用时才进行加载(懒加载) 注: 默认值
    select false 多方在一方加载时就加载(不是懒加载)
    select extra 多方在使用时才进行加载,如果使用时的操作是聚合类型,那么只会进行聚合查询。
  • 当fetch取值为join的时候

    fetch的取值 lazy的取值 结果
    join lazy失效(不管是true还是false) fetch采用的是迫切左外连接查询,将两张表的结果全部查询出来。lazy失效。
  • 当fetch取值为subselect的时候

    fetch的取值 lazy的取值 结果
    subselect true 多方在使用时才进行加载,发送的是子查询语句
    subselect false 多方在一方加载时就加载,发送的是子查询语句
    subselect extra 多方在一方加载时就加载,如果使用时的操作是聚合类型,那么只会进行聚合查询发送的是子查询语句

    注意: 使用Hibernate子查询时候,不能查一个. Hibernate如果发现in() 的值是一个,把in变成=

2.3many-to-one懒加载
2.3.1描述

在多的一方操作,即在many-to-one标签上配置 fetch 和 lazy

  • fetch:控制的是查询其关联对象的时候采用的SQL语句的格式.

    fetch的取值 发送的SQL语句类型
    select:默认值 发送一条select语句查询其关联对象.
    join 发送一条迫切左外连接查询关联对象.
  • lazy:查询其关联对象的时候是否采用延迟加载.

    lazy的取值 含义
    proxy 默认值.是否采用延迟 取决于 一的一方的class上的lazy的值.
    false 不采用延迟加载其关联对象.
    no-proxy(了解) 不用研究是否采用延迟
2.3.2例子

​ 下面的操作都是在多的一方操作,即在many-to-one标签上配置 fetch 和 lazy

  • 当select为fetch的时候,发送的是普通的sql语句

    fetch的取值 lazy的取值 结果
    select proxy 如果一的一方的class上的lazy的值为true,使用一的一方再加载(懒加载); 如果一的一方的class上的lazy的值为false,一方在多方加载时就加载(不是懒加载)
    select false 一方在多方加载时就加载(不是懒加载)
  • 当select为join的时候,是迫切左外连接

    fetch的取值 lazy的取值 结果
    join 失效 发送左外连接查询,不是懒加载

3 批量抓取(了解)

  • 在set标签上配置 batch-size = num

     Criteria criteria = session.createCriteria(Category.class);
    List<Category> list = criteria.list();

    for (Category category : list) {
    Set<Product> products = category.getProducts();
    for (Product product : products) {
    System.out.println(product.toString());
    }
    }

同时抓取多方表中指定的条数的数据

												

Hibernate入门(四)—— 查询的更多相关文章

  1. Hibernate入门(四)---------一级缓存

    Hibernate一级缓存 Hibernate的一级缓存就是指Session缓存,Session缓存是一块内存空间,用来存放相互管理的java对象,在使用Hibernate查询对象的时候,首先会使用对 ...

  2. Hibernate第四天——查询方式

    Hibernate入门最后一天第四天,我们进行查询方式的更进一步的细化: 先看一下大致的Hibernate的提供的查询的方式: 1.对象导航查询 2.OID查询 3.HQL查询 4.QBC查询 5.本 ...

  3. SSH框架之hibernate《四》

    hibernate第四天     一.JPA相关概念         1.1JPA概述             全称是:Java Persistence API.是sun公司推出的一套基于ORM的规范 ...

  4. 三大框架之hibernate入门

    hibernate入门   1.orm      hibernate是一个经典的开源的orm[数据访问中间件]框架           ORM( Object Relation Mapping)对象关 ...

  5. Hibernate入门详解

    学习Hibernate ,我们首先要知道为什么要学习它?它有什么好处?也就是我们为什么要学习框架技术? 还要知道    什么是Hibernate?    为什么要使用Hibernate?    Hib ...

  6. Hibernate入门案例及增删改查

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

  7. Hibernate原生SQL查询

    最近在做一个较为复杂的查询,hibernate基本的查询不能满足,只好使用其提供的原生sql查询.参考网上的一些资料,做一些总结. 对原生SQL查询执行的控制是通过SQLQuery接口进行的,通过执行 ...

  8. Hibernate入门案例 增删改

    一.Hibernate入门案例剖析: ①创建实体类Student 并重写toString方法 public class Student { private Integer sid; private I ...

  9. Hibernate入门6.Hibernate检索方式

    Hibernate入门6.Hibernate检索方式 20131128 代码下载 链接: http://pan.baidu.com/s/1Ccuup 密码: vqlv Hibernate的整体框架已经 ...

随机推荐

  1. java后台简单从阿里云上传下载文件并通知前端以附件的形式保存

    一. 首先开通阿里的OSS 服务 创建一个存储空间在新建一个Bucket 在你新建的bucket有所需的id和key 获取外网访问地址或者是内网 看个人需求 我使用的是外网(内网没用过 估计是部署到阿 ...

  2. 本机号码认证黑科技:极光(JG)开发者服务推出“极光认证”新产品

    近日,中国领先的大数据服务商极光(JG)推出全新产品--极光认证JVerification.极光认证是极光针对APP用户注册登陆,二次安全验证等身份验证场景打造的一款本机号码认证SDK,验证用户提供的 ...

  3. 3.3.1 Validations

    摘要: 出处:黑洞中的奇点 的博客 http://www.cnblogs.com/kelvin19840813/ 您的支持是对博主最大的鼓励,感谢您的认真阅读.本文版权归作者所有,欢迎转载,但请保留该 ...

  4. scrapy框架安装及使用

    一.Windows安装 Twisted下载及安装 在https://www.lfd.uci.edu/~gohlke/pythonlibs/ 下载对应的Twisted的版本文件 在命令行进入到Twist ...

  5. thinkphp5.0 微信扫码支付模式二

    仅供个人参考,方便大家. 一.1)https://pay.weixin.qq.com/index.php/core/home/login  复制此地址 打开微信商户平台. 2)下载安全操作证书(最好在 ...

  6. 洛谷p1208 水题贪心 思想入门

    题目描述 由于乳制品产业利润很低,所以降低原材料(牛奶)价格就变得十分重要.帮助Marry乳业找到最优的牛奶采购方案. Marry乳业从一些奶农手中采购牛奶,并且每一位奶农为乳制品加工企业提供的价格是 ...

  7. 【App测试】:Monkey测试App稳定性

    一,前提搭建android studio的环境中: 二,CMD进入到AndroidSDK\platform-tools路径下:输入adb shell 这个提示就是表示手机未连接 三.连接安卓手机,手机 ...

  8. [转] Scala 的集合类型与数组操作

    [From] https://blog.csdn.net/gongxifacai_believe/article/details/81916659 版权声明:本文为博主原创文章,转载请注明出处. ht ...

  9. winform两个窗体之间传值(C#委托事件实现)

    委托 定义一个委托,声明一个委托变量,然后让变量去做方法应该做的事. 委托是一个类型 事件是委托变量实现的 经典例子:两个winform窗体传值 定义两个窗体:form1和form2 form1上有一 ...

  10. Linux启动与关闭WIndows服务记录

    启动: mono-service -l:/var/run/Myservice-lock.pid MyService.exe (这个-l参数一定要加上) 控制服务: 暂停: kill -USR1 `ca ...