Hibernate中使用Query方法进行hql语句进行数据库查询
hql语法跟sql语法类似,学起来很容易
下面结合例子进行演示
案例说明
表一Commodity
| Id | name | price | unit | category | description | seller |
| 1 | 中式童装 | 120.00 | 套 | 童装 | 中式童装 | 4 |
| 2 | 女士套装 | 200.00 | 套 | 女装 | 女士职业套装 | 1 |
| 3 | 男士西服 | 200.00 | 套 | 男装 | 男士西服套装 | 1 |
| 4 | 笔记本电脑 | 4000.00 | 台 | 电脑 | 双核笔记本电脑 | 2 |
| 5 | 移动硬盘 | 400.00 | 块 | 电脑周边 | 1t移动硬盘 | 2 |
| 6 | 液晶电视 | 5000.00 | 台 | 电视 | 4k高清液晶电视 | 3 |
| 7 | 滚筒洗衣机 | 4000.00 | 台 | 洗衣机 | 滚筒洗衣机 | 3 |
| 8 | 《hibernate编程》 | 30.00 | 本 | 实体书 | 介绍hibernate编程 | 4 |
| 9 | 《Java核心》 | 50.00 | 本 | 实体书 | 介绍Java编程核心 | 4 |
| 10 | 《海底两万里》 | 40.00 | 本 | 电子书 | 经典科幻小说 | 4 |
| 11 | 优盘 | 30.00 | 个 | 电脑周边 | 16G优盘 | 2 |
表一中 最后一个字段是seller, 是外键关联seller表主键
以下是seller表
+----+------------+-------------+------------------------------+-----------+------+-----------------------------------+
| Id | name | tel | address | website | star | business |
+----+------------+-------------+------------------------------+-----------+------+-----------------------------------+
| 1 | A服装店 | 13000000000 | 中国北京××区 | www.a.com | 5 | 经营各式服装 |
| 2 | B数码店 | 15800000000 | 中国浙江杭州市××区 | www.b.com | 4 | 经营各类数码电子产品 |
| 3 | C电器店 | 13012341234 | 中国广东深圳市××区 | www.c.com | 4 | 经营各类家电 |
| 4 | D书店 | 18600000000 | 中国陕西西安市××区 | www.d.com | 5 | 经营各类实体书与电子书 |
+----+------------+-------------+------------------------------+-----------+------+-----------------------------------+
分别建立两个表的实体类和xml映射文件
建立一个Junit测试类
init方法为创建一个Session对象
destory方法为关闭session
使用from关键词查询出Commodity中所有数据
// hql语句
String hql = " from Commodity ";
//创建一个Query对象
Query query = session.createQuery(hql);
//调用list方法,查询出数据,保存到commodities中
List<Commodity> commodities = query.list();
//foreach方法遍历查询出的数据
for(Commodity commodity : commodities){
System.out.println(commodity.getName());
}
可能出现的问题:
-
from 后跟的是需要查询的实体类的名字,而不是数据库中对应表的名字,这点需要特别注意
-
类名错误的trace
org.hibernate.hql.ast.QuerySyntaxException: commodity is not mapped [ from commodity ] -
另外,
java.lang.IllegalArgumentException: node to traverse cannot be null!这个错误是hql语句语法错误导致的
查询结果返回List<T>数组
select 关键词单纯使用from语句会将所有字段都查询出来,我们可以通过select语句控制具体需要查询字段
基本用法:
String hql = "select name,price from Commodity";
Query query = session.createQuery(hql);
List<Object[]> commodities = query.list();
for(Object[] commodity : commodities){
System.out.println("商品名:"+commodity[0]);
System.out.println("价格:"+commodity[1]);
}
通过select关键词,我们将查询的字段设定为name和price, 通过query.list()方法查询后返回一个类型为Object数组的List集合
在foreach中,通过数组下标的方式取得查询的数据
别名String hql = "select c.name as n,c.price as p from Commodity as c";
可以省略as
- select 基本用法就是这些,额外补充下面的内容
基本方法中调用query.list()方法返回的是一个Object[] 类型的List集合,我们可以更改List()方法返回的数据类型
query.list()返回List<List> ,一个类型为List的List集合
用法如下
String hql = "select new list(c.name,c.sex,c.age,c.tel) from Customer c ";
Query query = session.createQuery(hql);
List<List> lists = query.list();
for(List list : lists){
System.out.println("name:"+list.get(0));
System.out.println("sex:"+list.get(1));
System.out.println("age"+list.get(2));
System.out.println("tel:"+list.get(3));
}
query.list()返回Set集合
通过as方法给字段添加别名后,再在外面加个new map()
具体代码如下
String hql = "select new map(name as name,price as price) from Commodity";
Query query = session.createQuery(hql);
List<Map> commodities = query.list();
for(Map map : commodities){
System.out.println("商品名:"+map.get("name"));
System.out.println("价格:"+map.get("price"));
}
通过as关键词设置字段别名后,用set集合get("key")获得到数据
- 注意:不使用as别名的话不能通过get(String key)方法获得数据,但是可以通过get(0)
,这中下标的方式获取数据String hql = "select new map(name,price) from Commodity"; Query query = session.createQuery(hql); List<Map> commodities = query.list(); for(Map map : commodities){ System.out.println("商品名:"+map.get("0")); System.out.println("价格:"+map.get("1")); }
List,Set 集合的方法与基本方法中返回List<Object[]>没有什么区别,根据习惯选用
select 只查询一个字段的情况如果你在select中只查询一个字段,那么query.list()返回的就是List<Object>类型,而不是List<Object[]>类型
String hql = "select name from Commodity";
Query query = session.createQuery(hql);
List<Object> commodities = query.list();
for(Object commodity : commodities){
System.out.println(commodity.toString());
}
distinct 过滤重复数据
熟悉sql语句的同学都应该认识这个,过滤掉多余的重复记录只保留一条
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 条件查询
跟sql语法一模一样
比较运算符 >大于 , < 小于 , >= 大于等于, <= 小于等于, <>不等于, = 等于, is null, is not null
查询女客户
String hql = " from Customer c where c.sex<>'男'";
Query query = session .createQuery(hql);
List<Customer> customers = query.list();
for(Customer c : customers){
System.out.println("name:"+c.getName());
System.out.println("sex:"+c.getSex());
}
in,between
查询年龄是20或者40的顾客
String hql = " from Customer c where c.age not in(20,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());
}
查询年龄在20到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());
}
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());
}
limit 与 uniqueResult
hql中不支持limit 语法
String hql = " from Customer";
Query query = session.createQuery(hql);
//设置从第几条开始查询(开始检索的位置)
query.setFirstResult(0);
//设置查询出多少条(返回最大记录行)
query.setMaxResults(1);
演示
String hql = " from Customer";
Query query = session.createQuery(hql);
query.setFirstResult(0);
query.setMaxResults(1);
List<Customer> lists = query.list();
for(Customer customer : lists){
System.out.println(customer.getName());
}
例子中,只查询了一条,所以lists中只有一个Customer对象,我们可以使用uniqueResult改进下
String hql = " from Customer";
Query query = session.createQuery(hql);
query.setFirstResult(0);
query.setMaxResults(1);
Customer customer = (Customer) query.uniqueResult();
System.out.println(customer.getName());
query.uniqueResult()只能用于查询一条数据,如果查询结果是多条则报错
排序asc 正序
desc 倒序
支持逗号分隔,二次排序
String hql = " from Customer order by age desc,id asc ";
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());
}
group by
支持group by语法
String hql = "select name,address from Customer group by sex";
Query query = session.createQuery(hql);
List<Object[]> customers = query.list();
for(Object[] customer : customers){
System.out.print(customer[0]+ " ");
System.out.println(customer[1]);
}