为了账号安全,请及时绑定邮箱和手机立即绑定

Hibernate Hql查询语句总结

标签:
Java
hql

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 关键词

使用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]);

}
点击查看更多内容
4人点赞

若觉得本文不错,就分享一下吧!

评论

作者其他优质文章

正在加载中
PHP开发工程师
手记
粉丝
6
获赞与收藏
60

关注作者,订阅最新文章

阅读免费教程

感谢您的支持,我会继续努力的~
扫码打赏,你说多少就多少
赞赏金额会直接到老师账户
支付方式
打开微信扫一扫,即可进行扫码打赏哦
今天注册有机会得

100积分直接送

付费专栏免费学

大额优惠券免费领

立即参与 放弃机会
意见反馈 帮助中心 APP下载
官方微信

举报

0/150
提交
取消