Hibernate检索(Hql)

编程

ps :

一 : 概述

  • HQL是我们在hibernate中最常用的一种检索方式。
  • HQL(Hibernate Query Language)提供更加丰富灵活、更为强大的查询能力
  • 因此Hibernate将HQL查询方式立为官方推荐的标准查询方式,HQL查询在涵盖Criteria查询的所有功能的前提下,提供了类似标准SQL语句的查询方式,同时也提供了更加面向对象的封装。
  • 完整的HQL语句形式如下:

select/update/delete…… 

from ……

where ……

group by ……

having ……

order by …… asc/desc

  • 其中的update/delete为Hibernate3中所新添加的功能,可见HQL查询非常类似于标准SQL查询。
  • 基本步骤:

    1. 得到Session
    2. 编写HQL语句
    3. 通过session.createQuery(hql)创建一个Query对象
    4. 为Query对象设置条件参数
    5. 执行list()查询所有,它返回的是List集合, uniqueResut()返回一个查询结果。

二 : 单表操作

(一) 基本检索

  • From 类名

// 基本检索

@Test

public void test() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

//1.编写HQL

String hql = "from Customer";//from是关键字,后面是类名,关键字不区分大小写,但类名区分

//2.通过session.createQuery(hql)

//Query query = session.createQuery(hql);

//3.通过list()方法得到数据

//List<Customer> list = query.list();

List<Customer> list = session.createQuery(hql).list();

System.out.println(list);

session.getTransaction().commit();

session.close();

}

(二) 排序检索

// 排序检索---查询订单,根据订单的价格进行排序

@Test

public void test2() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

//1.定义hql

String hql = "from Order order by money";

//执行hql查询订单,根据价格进行排序

List<Order> list = session.createQuery(hql).list();

System.out.println(list);

session.getTransaction().commit();

session.close();

}

(三) 条件检索

// 条件查询---价格要大于2000

@Test

public void test3() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

//根据位置类绑定参数

// 1.定义hql--

//String hql = "from Order where money > ?";

// 2.执行hql

//List<Customer> list = session.createQuery(hql).setParameter(0, 2000d).list();

//可以使用例如setString(),setDouble这样的方法区添加参数,参数的序号是从0开始

//根据名称来绑定

// 1.定义hql--根据位置类绑定参数

String hql = "from Order where money > :mymoney";

// 2.执行hql

List<Customer> list = session.createQuery(hql).setParameter("mymoney", 2000d).list();

//可是使用例如setString(),setDouble这样的方法去添加参数,参数的序号是从0开始

System.out.println(list);

session.getTransaction().commit();

session.close();

}

(四) 分页检索

// 分页检索

@Test

public void test4() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

// 1.定义hql

String hql = "from Order";

// 执行hql查询订单,根据价格进行排序

Query query = session.createQuery(hql);

//每页显示6条,要得到第二页数据

query.setFirstResult((2-1)*6);//设定开始的位置

query.setMaxResults(6);//设置条数

List<Customer> list = query.list();

System.out.println(list);

session.getTransaction().commit();

session.close();

}

(五) 分组统计检索

  • 分组:group by
  • 统计:count,max,min,avg,sum

//分组统计

@Test

public void test5(){

Session session = HibernateUtils.openSession();

session.beginTransaction();

//统计操作---统计一共有多少订单count

// String hql="select count(*) from Order";

// Object count = session.createQuery(hql).uniqueResult();

// System.out.println(count);

//分组统计---每一个人的订单总价

String hql="select sum(money) from Order group by c";

List list = session.createQuery(hql).list();

System.out.println(list);

session.getTransaction().commit();

session.close();

}

(六) 投影检索

  • 关于部分属性查询,可以使用投影将部分属性封装到对象中。
  • 注意 : 我们必须在PO类中提供对应属性的构造方法,也要有无参数构造。

//投影检索

@Test

public void test6(){

Session session = HibernateUtils.openSession();

session.beginTransaction();

//1.查询出所有Customer的name

// String hql="select name from Customer";

// List list = session.createQuery(hql).list();

// System.out.println(list);

//如果只查询一个列,得到的结果是List<Object>

//2.查询所有的Customer的id,name

// String hql="select id,name from Customer";

// List<Object[]> list = session.createQuery(hql).list();

// System.out.println(list);

// for (Object[] objs : list) {

// for (Object obj : objs) {

// System.out.println(obj+" ");

//

// }

//

// }

//如果是查询多列,得到的结果是List<Object[]>

//3.使用投影将查询结果封装到Customer对象

String hql="select new Customer(id,name) from Customer";//必须在PO类中提供对象的构造方法

List<Customer> list = session.createQuery(hql).list();

System.out.println(list);

session.getTransaction().commit();

session.close();

}

(七) 命名检索

  • 我们可以将hql语句先定义出来,在使用时通过session.getNamedQuery(hqlName);得到一个Query,再执行.

1.hql定义位置

1)hbm配置文件

  • 当前的hql操作是对哪一个实体进行操作,就在哪一个实体的配置文件中声明。

<query name="myHql">

from Customer

</query>

2)如果是使用注解来描述PO的配置

  • 直接在PO类中使用

@NamedQuery(name="myHql",query="from Customer")

public class Customer{

2.如何使用?

// 命名检索

@Test

public void test7() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

Query query = session.getNamedQuery("myHql");

List list = query.list();

System.out.println(list);

session.getTransaction().commit();

session.close();

}

三 : 多表操作

  • 注意:在hibernate中有迫切连接的概念,而sql中没有。

(一) 内连接

1.显式内连接

  • 显式内连接 : inner join ... with + 单独条件**(仅HQL中使用)**

// 测试显式内链接

@Test

public void test1() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

// sql连接select * from t_customer inner join t_order on 条件

String hql = "from Customer c inner join c.orders with c.id=1";

Query query = session.createQuery(hql);

/ *

* 结果是List<Object[]>

* 而Object[]中装入的是Customer与Order对象

* /

List<Object[]> list = query.list();

for (Object[] objects : list) {

for (Object obj : objects) {

System.out.println(obj + " ");

}

}

session.getTransaction().commit();

session.close();

}

2.隐式内连接

  • 隐式内连接与我们在sql中操作不一样,它是通过"."运算符来关联
  • from Order o where o.c.id=1
  • o.c.id : order中customer的id(这个屌了)

// 隐式内连接

@Test

public void test2() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

//sql连接select * from t_customer,t_order where 条件

String hql = "from Order o where o.c.id=1";

Query query = session.createQuery(hql);

List list = query.list();

System.out.println(list);

session.getTransaction().commit();

session.close();

}

3.迫切内连接(*****)

  • 迫切内连接**inner join fetch**
  • 得到的结果直接封装到PO类中,而内连接得到的是Object[]数组,数组中封装的是PO类对象。
  • 注意 : 使用迫切连接结果可能出现重复,所以要使用distinct来去重

// 迫切内链接

@Test

public void test3() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

/*

* 迫切内链接inner join fetch

* 注意:使用迫切连接结果可能出现重复,用distinct去重

*/

String hql = "select distinct c from Customer c inner join fetch c.orders where c.id=1";

//底层也是执行inner join,只不过结果封装到对象中

Query query = session.createQuery(hql);

// 结果是List<> 集合中装入的是from后面的对象

List<Customer> list = query.list();

for (Customer c : list) {

System.out.println(c);

}

session.getTransaction().commit();

session.close();

}

(二) 外连接

1.左外连接

// 测试外连接--左外连接

@Test

public void test4() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

List<Object[]> list = session.createQuery("from Customer c left outer join c.orders").list();

for (Object[] objects : list) {

for (Object obj : objects) {

System.out.println(obj + " ");

}

System.out.println();

}

session.getTransaction().commit();

session.close();

}

2.右外连接

3.迫切左外连接(*****)

  • select distinct c from Customer c left outer join fetch c.orders where c.id=1
  • 注意 : fetch不可以与单独条件with一起使用

// 迫切左外连接

@Test

public void test5() {

Session session = HibernateUtils.openSession();

session.beginTransaction();

//注意:fetch不可以与单独条件with一起使用

List<Customer> list = session.createQuery("select distinct c from Customer c left outer join fetch c.orders where c.id=1").list();

for (Customer c : list) {

System.out.println(c);

}

session.getTransaction().commit();

session.close();

}

  • 注意 : 没有迫切右外连接

以上是 Hibernate检索(Hql) 的全部内容, 来源链接: utcz.com/z/511323.html

回到顶部