HQL数据查询基础(三)
2016-05-20 12:00
453 查看
继上回 (HQL数据查询基础(二)),针对“网上商店”这个例子,来讲解一些HQL简单的子句用法。
(以下的所有测试方法均在 MyTest.java 测试类(在上文上有提到)中添加)
from子句
1)HQL语句最简形式;
2)from指定了HQL语句查询主体——持久化类及其属性
from子句中持久化类的引用
1)不需要引入持久化类的全限定名,直接引入类名;
2)auto-import(自动引入)缺省情况。
测试from子句的使用——获取customer表中的所有客户信息:
测试能否通过 商品对象 获得 商家信息:
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[] 返回数据类型:
2)以List形式返回查询结果——select子句中使用new list指定;
测试select子句的 List 返回数据类型:
3)以Map形式返回查询结果——select子句中使用new map指定,key值为索引值,字符串类型;
测试select子句的 Map返回数据类型:
4)以自定义类型返回查询结果——持久化类中定义对应的构造器,构造器的参数就是我们选择返回的属性信息;select子句中调用定义的构造器来完成相应的查询,以自定义类型来返回查询的结果
测试select子句中以自定义类型返回查询结果:
需要我们在查询类中添加自定义的构造方法,本次查询的类为 Seller类,我们需要在Seller类中自定义构造方法,而构造方法中的参数就是我们需要查询返回的信息:
测试方法如下:
注:当我们自定义了构造方法之后,还需要定义无参的构造方法吗?答案是肯定的。我们先来回顾一下之前定义的一个测试方法testSeller:
这里并未使用到select子句,那么默认返回的是所有Seller的所有属性信息,它此时调用的无参构造方法。如果我们不提供默认的无参构造方法的话,执行上面的测试方法,将出现 没有找到 Seller 实体的错误提示。
所以我们需要在自定义构造方法后,在类中同样增加无参的构造方法。
distinct 关键字
使用distinct关键字去除查询结果中的重复元素
测试使用distinct关键字,消除结果集中重复的元素:
where子句
我们可以通过where子句设置查询条件,限制返回结果。
(1)比较运算
1. = 、<> 、< 、> 、>= 、<=
2.null值判断——is [not] null,在HQL中可使用 = null 或 <> null 来表示 is [not] null
测试使用比较运算符:
测试null值判断:
(2)范围运算
1. [not] in(列表);
2. [not] between 值1 and 值2
测试:
(3)字符串模式匹配
1、like关键字;
2、通配符 %、_ (%:任意个字符;_:一个字符)
测试:
(4)逻辑运算
1、and(逻辑与)、or(逻辑或)
2、not(逻辑非)
测试:
(5)集合运算
1、is [not] empty 集合[不]为空,不包含任何元素;
2、member of 元素属于集合;
测试:
(6)四则运算
1、HQL语句中也可以使用 + - x / 四则运算
2、四则运算可以在where子句和select子句中使用
测试:
(7)查询单个对象
1、Query接口的uniqueResult方法;
2、where子句条件的设置,我们需要确保where子句设置的条件查询出来的结果只有一条数据或没有数据,否则使用uniqueResult方法过程中会抛出异常 org.hibernate.NonUniqueResultException: query did not return a unique result,中止运行。
测试:
排序——order by子句
使用order by子句对查询结果排序
1、升序排序 asc;2、降序排序 desc;
测试:
(以下的所有测试方法均在 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()); } }
相关文章推荐
- sql2008 hql语句翻译过来的分页语句介绍
- Hibernate Oracle sequence的使用技巧
- jsp Hibernate批量更新和批量删除处理代码
- jsp hibernate的分页代码第1/3页
- Struts2+Hibernate实现数据分页的方法
- Hibernate环境搭建与配置方法(Hello world配置文件版)
- JAVA+Hibernate 无限级分类
- SSH整合中 hibernate托管给Spring得到SessionFactory
- jsp hibernate 数据保存操作的原理
- hibernate中的增删改查实现代码
- 解决hibernate+mysql写入数据库乱码
- java优化hibernate性能的几点建议
- java Hibernate延迟加载
- hibernate 常用方法介绍
- 详解Java的Hibernate框架中的注解与缓存
- 浅析Java的Hibernate框架中的继承关系设计
- Hibernate实现批量添加数据的方法
- JQuery+Ajax+Struts2+Hibernate框架整合实现完整的登录注册
- 深入理解Hibernate中的flush机制
- 简要分析Java的Hibernate框架中的自定义类型