HQL数据查询基础(三)

来源:互联网 发布:公司起名软件免费 编辑:程序博客网 时间:2024/06/14 05:28

       继上回 (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
原创粉丝点击