HQL数据查询基础(三)

       继上回 (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());
        }
    }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值