HQL数据查询基础(三)

2023-05-16

       继上回 (HQL数据查询基础(二)),针对“网上商店”这个例子,来讲解一些HQL简单的子句用法。

(以下的所有测试方法均在 MyTest.java 测试类(在上文上有提到)中添加)

from子句
1)HQL语句最简形式;
2)from指定了HQL语句查询主体——持久化类及其属性

from子句中持久化类的引用

1)不需要引入持久化类的全限定名,直接引入类名;
2)auto-import(自动引入)缺省情况。
测试from子句的使用——获取customer表中的所有客户信息:
<span style="font-size:18px;">@Test
    public void testFromClause1() {
        String hql = " from Customer ";
        //创建Query实例对象
        Query query = session.createQuery(hql);
        List<Customer> customers = query.list();

        for(Customer customer : customers) {
            System.out.println("name: " + customer.getName());
        }
    }</span>

测试能否通过 商品对象 获得 商家信息:
<span style="font-size:18px;">/**
     * 测试能否通过 商品对象 获取 商家信息
     */
    @Test
    public void testFromClause2() {
        String hql = " from Commodity ";

        Query query = session.createQuery(hql);
        List<Commodity> commodities = query.list();

        for (Commodity c : commodities) {
            System.out.println("name: " + c.getName());
            System.out.println("seller's name: " + c.getSeller().getName());
        }
    }</span>

       Hibernate中默认是“懒”加载状态,只有需要到某些关联信息才进行查询。在这个例子中,我们先查询到所有商品信息,根据商品信息获取商家信息,获取商家信息的时候Hibernate才发起查询,并不是在查询到商品信息的同时也查询了商家信息。Hibernate做了延迟加载。

from子句中别名的应用
1)为被查询的类指定别名;
2)在HQL语句其他部分通过别名引用该类;
3)别名命名习惯:一般与持久类类名相同,使用小写。如:from Seller 中 Seller 别名可以为 seller,为了简洁,别名也可以取名为 s。在简洁的同时,需要保证代码的可读性。
具体如: from Seller as seller 或 from Seller as s 或 from Seller seller 或 from Seller s(as 关键字可以省略)
select子句
1)select子句中未指定返回数据类型,默认为Object[];(注意:当查询的字段只有一个时,返回的数据类型就不再是 Object[],而是Object)
测试select子句的Object[] 返回数据类型:
<span style="font-size:18px;">/**
     * 1. name 2.tel 3.address 4.star
     */
    @Test
    public void testSelectClauseObjectArray() {
        String hql = "select s.name, s.tel, s.address, s.star from Seller s ";

        Query query = session.createQuery(hql);
        List<Object[]> list = query.list();

        for(Object[] objs : list) {
            System.out.println("name: " + objs[0]);
            System.out.println("tel: " + objs[1]);
            System.out.println("address: " + objs[2]);
            System.out.println("star: " + objs[3]);
        }

        System.out.println();
        System.out.println("特殊实例:");

        //如果查询的字段只有一个的话,那么其返回类型是 Object 而不是Object[]。
        String hql2 = "select s.name from Seller s ";

        Query query2 = session.createQuery(hql2);
        List<Object> list2 = query2.list();

        for(Object objs : list2) {
            System.out.println("name: " + objs);
        }
    }</span>
2)以List形式返回查询结果——select子句中使用new list指定;
测试select子句的 List 返回数据类型:
<span style="font-size:18px;">    @Test
    public void testSelectClauseList() {
        String hql = "select new list(s.name, s.tel, s.address) from Seller s";
        Query query = session.createQuery(hql);
        List<List> lists = query.list();

        for(List list : lists) {
            System.out.println("name: " + list.get(0));
            System.out.println("tel: " + list.get(1));
            System.out.println("address: " + list.get(2));

        }
    }</span>
3)以Map形式返回查询结果——select子句中使用new map指定,key值为索引值,字符串类型;
测试select子句的 Map返回数据类型:
<span style="font-size:18px;">    @Test
    public void testSelectClauseMap() {
        String hql = "select new map(s.name, s.tel, s.address) from Seller s";
        Query query = session.createQuery(hql);
        List<Map> maps = query.list();

        for(Map map : maps) {
            System.out.println("name: " + map.get("0"));
            System.out.println("tel: " + map.get("1"));
            System.out.println("address: " + map.get("2"));
        }

        //除了通过序号来获取查询结果外,还可以使用别名来获取
        String hql2 = "select new map(s.name as name, s.tel as tel, s.address as address) from Seller s";
        Query query2 = session.createQuery(hql2);
        List<Map> maps2 = query2.list();

        for(Map map : maps2) {
            System.out.println("name: " + map.get("name"));
            System.out.println("tel: " + map.get("tel"));
            System.out.println("address: " + map.get("address"));
        }
    }</span>

4)以自定义类型返回查询结果——持久化类中定义对应的构造器,构造器的参数就是我们选择返回的属性信息;select子句中调用定义的构造器来完成相应的查询,以自定义类型来返回查询的结果
测试select子句中以自定义类型返回查询结果:
        需要我们在查询类中添加自定义的构造方法,本次查询的类为 Seller类,我们需要在Seller类中自定义构造方法,而构造方法中的参数就是我们需要查询返回的信息:
    public Seller(String name, String tel, String address) {
        this.name = name;
        this.tel = tel;
        this.address = address;
    }
测试方法如下:
@Test
    public void testSelectClauseSelf() {
        String hql = "select new Seller(s.name, s.tel, s.address) from Seller s";
        Query query = session.createQuery(hql);
        List<Seller> sellers = query.list();
        for(Seller seller :sellers) {
            System.out.println("name: " + seller.getName());
            System.out.println("tel: " + seller.getTel());
            System.out.println("address: " + seller.getAddress());
        }
    }
注:当我们自定义了构造方法之后,还需要定义无参的构造方法吗?答案是肯定的。我们先来回顾一下之前定义的一个测试方法testSeller:
    @Test
    public void testSeller() {
        String hql = " from Seller s";
        //创建Query实例对象
        Query query = session.createQuery(hql);
        List<Seller> sellers = query.list();

        for(Seller seller : sellers) {
            System.out.println(seller);
        }
    }
这里并未使用到select子句,那么默认返回的是所有Seller的所有属性信息,它此时调用的无参构造方法。如果我们不提供默认的无参构造方法的话,执行上面的测试方法,将出现 没有找到 Seller 实体的错误提示。
所以我们需要在自定义构造方法后,在类中同样增加无参的构造方法。
distinct 关键字
使用distinct关键字去除查询结果中的重复元素
测试使用distinct关键字,消除结果集中重复的元素:
    @Test
    public void testDistinct() {
        String hql = "select distinct c.sex from Customer c";
        Query query = session.createQuery(hql);
        List<Object> list = query.list();
        for(Object obj : list) {
            System.out.println(obj);
        }
    }
where子句
我们可以通过where子句设置查询条件,限制返回结果。
(1)比较运算
1. = 、<> 、< 、> 、>= 、<=
2.null值判断——is [not] null,在HQL中可使用 = null 或 <> null 来表示 is [not] null
测试使用比较运算符:
    @Test
    public void testWhere1() {
        String hql = " from Commodity c where c.price > 400";
        Query query = session.createQuery(hql);
        List<Commodity> commodities = query.list();
        for(Commodity c : commodities) {
            System.out.println("name: " + c.getName());
            System.out.println("price: " + c.getPrice());
        }
    }
测试null值判断:
    @Test
    public void testWhere2() {
        //is null 的判断
        //String hql = " from Commodity c where c.description is null";
        //String hql = " from Commodity c where c.description = null";
        //is not null 的判断
        //String hql = " from Commodity c where c.description is not null";
        String hql = " from Commodity c where c.description <> null";

        Query query = session.createQuery(hql);
        List<Commodity> commodities = query.list();
        for(Commodity c : commodities) {
            System.out.println("name: " + c.getName());
            System.out.println("description: " + c.getDescription());
        }
    }

(2)范围运算
1. [not] in(列表);
2. [not] between 值1 and 值2
测试:
    @Test
    public void testWhere3() {
        //String hql = " from Customer c where c.age in(20, 40)";
        //String hql = " from Customer c where c.age not in(20, 40)";
        //String hql = " from Customer c where c.age between 20 and 40";
        String hql = " from Customer c where c.age not between 20 and 40";
        Query query = session.createQuery(hql);
        List<Customer> customers = query.list();
        for(Customer c : customers) {
            System.out.println("name: " + c.getName());
            System.out.println("age: " + c.getAge());
        }
    }

(3)字符串模式匹配
1、like关键字;
2、通配符 %、_ (%:任意个字符;_:一个字符)
测试:
@Test
    public void testWhere4() {
        //String hql = " from Customer c where c.name like '张_'";
        String hql = " from Customer c where c.address like '%北京%'";
        Query query = session.createQuery(hql);

        List<Customer> customers = query.list();
        for(Customer c : customers) {
            System.out.println("name: " + c.getName());
            System.out.println("address: " + c.getAddress());
        }
    }

(4)逻辑运算
1、and(逻辑与)、or(逻辑或)
2、not(逻辑非)
测试:
    @Test
    public void testWhere5() {
        //String hql = " from Commodity c where c.price between 100 and 5000 and c.category like '%电脑%'";
        String hql = " from Commodity c where c.price between 100 and 5000 or c.category like '%电脑%'";
        Query query = session.createQuery(hql);
        List<Commodity> commodities = query.list();
        for(Commodity c : commodities) {
            System.out.println("name: " + c.getName());
            System.out.println("category: " + c.getCategory());
            System.out.println("price: " + c.getPrice());
        }
    }

(5)集合运算
1、is [not] empty 集合[不]为空,不包含任何元素;
2、member of 元素属于集合;
测试:
    @Test
    public void testWhere6() {
        //查询订单信息不为空的有效订单
        String hql = " from Order o where o.orderItems is not empty";
        Query query = session.createQuery(hql);
        List<Order> orders = query.list();
        for(Order order : orders) {
            System.out.println(order.getCustomer().getName());
            System.out.println(order.getAmount());
            System.out.println(order.getTradeDate());
        }
    }

(6)四则运算
1、HQL语句中也可以使用 + - x / 四则运算
2、四则运算可以在where子句和select子句中使用
测试:
    @Test
    public void testWhere7() {
        String hql = " from Commodity c where c.price * 5 > 3000";
        Query query = session.createQuery(hql);
        List<Commodity> commodities = query.list();
        for(Commodity c : commodities) {
            System.out.println("name: " + c.getName());
            System.out.println("price: " + c.getPrice() * 5);
        }
    }

(7)查询单个对象
1、Query接口的uniqueResult方法;
2、where子句条件的设置,我们需要确保where子句设置的条件查询出来的结果只有一条数据或没有数据,否则使用uniqueResult方法过程中会抛出异常 org.hibernate.NonUniqueResultException: query did not return a unique result,中止运行。
测试:
    @Test
    public void testWhere8() {
        //String hql = " from Customer c where c.name = '张三'";
        String hql = " from Customer c where c.age > 20";
        Query query = session.createQuery(hql);

        Customer c = (Customer) query.uniqueResult();
        System.out.println(c.getName());
    }

排序——order by子句
使用order by子句对查询结果排序
1、升序排序 asc;2、降序排序 desc;
测试:
    @Test
    public void testOrderBy() {
        //String hql = " from Commodity order by price asc";
        //String hql = " from Commodity order by price desc";
        String hql = " from Commodity order by seller.id asc, price desc, name asc";
        Query query = session.createQuery(hql);
        List<Commodity> commodities = query.list();
        for(Commodity c : commodities) {
            System.out.println("name: " + c.getName());
            System.out.println("sellerId: " + c.getSeller().getId());
            System.out.println("sellerName: " + c.getSeller().getName());
            System.out.println("price: " + c.getPrice());
        }
    }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

HQL数据查询基础(三) 的相关文章

随机推荐

  • 伸缩自如的时光轴实现_样式改版

    针对前几篇文章中实现的 伸缩自如 的时光轴 xff0c 对时光轴的样式进行又一次修改 xff0c 效果如下 xff1a 点击 收起 后 xff1a 修改后的 timeline css xff0c 如下 xff1a vertical time
  • ThinkPHP中的create方法与自动令牌验证

    转载自 xff1a Thinkphp中Create方法深入探究 ThinkPHP中的create方法与自动令牌验证实例教程 Thinkphp中Create方法深入探究 由于工作原因在thinkPHP的create 方法上遇到了问题 xff0
  • web安全之token和CSRF攻击

    上文我转载了两篇关于ThinkPHP令牌验证的文章 xff08 ThinkPHP中的create方法与自动令牌验证 xff09 其中提及到了 token xff0c 这里针对 token 的作用 xff0c 转载了另外两篇文章 xff08
  • java中的==、equals和hashCode以及hashCode生成

    转载自 xff1a xff08 点击打开链接 xff09 前言 java中 61 61 equals hashCode 都和对象的比较有关 xff0c 在java中这三者各有什么用处呢 xff0c 即java中为什么需要设计这三种对象的比较
  • javascript调用微信或QQ扫一扫

    项目里为了体验做的好点 xff0c 想直接通过js调用手机的扫一扫 xff1a 服务的用户主要是通过 xff1a 微信或QQ 之前使用过 微信或QQ的分享 腾讯移动WEB开发平台的 39 对外分享组件接口文档 39 http open mo
  • Java中的反射机制

    获取类的类类型的3种方式 xff0c 以及如何通过类的类类型创建实例对象 xff1f ClassDemo1 java package com reflect public class ClassDemo1 public static voi
  • Java中的自定义注解

    自定义注解 Description java xff08 这里自定义Description注解 xff09 package com ann test import java lang annotation Documented import
  • Java中自定义注解的应用

    来自 慕课网 的学习 我们可以使用自定义注解 xff0c 实现ORM xff0c 即对象 关系的映射 通过自定义注解 xff0c 定义对象对应数据表的属性 xff0c 如表名 xff0c 表字段等 Table java xff08 Tabl
  • Intellij IDEA下的第一个Hibernate项目

    参考 xff1a intellij配置hibernate自动生成hbm xml文件 从零开始用Intellij idea14创建hibernate项目 下面我要讲的创建方式 xff0c 可能更加原生态 xff0c 更加类似于Eclipse下
  • Intellij IDEA使用注解创建Hibernate项目中的OR映射类

    上回说到 xff1a Intellij IDEA下的第一个Hibernate项目 我们需要创建 对象到关系的映射配置文件 xff0c 如 entity hbm xml xff08 其中 entity 是我们将要创建的实体 xff09 下面讲
  • Hibernate中Blob对象类型的使用

    使用Intellij IDEA创建Hibernate项目 xff0c 目录结构如下 xff1a 其中 assets app png 为将要存储的照片 xff0c src hibernate cfg xml 为Hibernate的配置文件 x
  • Hibernate组件映射

    转载自 xff1a 点击打开链接 在Hibernate中 component 是某个实体的逻辑组成部分 xff0c 它与实体的根本区别是没有oid xff08 对象标识符 xff09 xff0c component是一个被包含的对象 它作为
  • Hibernate中的单向一对多关联

    源自 imooc 中的学习 Hibernate中的单向一对多关联 xff0c 这里举例 班级对学生 的单向一对多关联 xff0c 即一个班级可以有多个学生 那么在Hibernate中实体对象间如何体现出单向一对多的关联关系呢 xff1f 如
  • Hibernate中的单向多对一关联

    继上回讲到 Hibernate中的单向一对多关联 xff0c 这次来实现一下Hibernate中的单向多对一关联 对原来的项目修改如下 xff1a Hibernate中的单向多对一关联 xff0c 需要我们在多方增加一个一方的属性 xff0
  • Hibernate中的双向多对一关联以及 inverse属性、cascade属性的用法

    上回 说了 Hibernate中的单向一对多关联 和 Hibernate中的单向多对一关联 这次针对这两个 单向 进行整合即可实现双向的多对一关联 如 xff1a 学生与班级的关系 在Grade类中需要添加 Set集合保存Student对象
  • 优化器 optimizer

    优化器 optimizer optimizer 优化器 xff0c 用来根据参数的梯度进行沿梯度下降方向进行调整模型参数 xff0c 使得模型loss不断降低 xff0c 达到全局最低 xff0c 通过不断微调模型参数 xff0c 使得模型
  • Hibernate中的多对多关联

    源自 imooc 的学习 多对多关联是一种常见的关联关系 多对多关联关系一般采用中间表的形式来实现 xff0c 即新增一张包含关联双方主键的关联表 那么 xff0c 在Hibernate中如何实现多对多的关联关系呢 xff1f 多对多关联可
  • HQL数据查询基础(一)

    源自 imooc 的学习 什么是HQL呢 xff1f HQL 是Hibernate Query Language xff0c Hibernate查询语言 xff1b 同时HQL是一种面向对象的查询语言 xff0c HQL查询的主体是映射配置
  • HQL数据查询基础(二)

    继上回 xff08 HQL数据查询基础 xff08 一 xff09 xff09 说到的例子 网上商店 xff0c 来继续完善持久化类和配置文件的创建 上回 在 com imooc model 包中创建 Seller java 持久化类 xf
  • HQL数据查询基础(三)

    继上回 xff08 HQL数据查询基础 xff08 二 xff09 xff09 xff0c 针对 网上商店 这个例子 xff0c 来讲解一些HQL简单的子句用法 xff08 以下的所有测试方法均在 MyTest java 测试类 xff08