HQL

HQL简介

HQL(Hibernate Query Language) 是面向对象的查询语言, 它和 SQL 查询语言有些相似. 在 Hibernate 提供的各种检索方式中, HQL 是使用最广的一种检索方式. 它有如下功能:
在查询语句中设定各种查询条件(条件查询)
支持投影查询, 即仅检索出对象的部分属性
支持分页查询
支持连接查询
支持分组查询, 允许使用 HAVING 和 GROUP BY 关键字
提供内置聚集函数, 如 sum(), min() 和 max()
支持子查询
支持动态绑定参数
能够调用 用户定义的 SQL 函数或标准的 SQL 函数


说一下hql与sql的不同之处:最大的不同之处就是HQL 查询语句是面向对象的, Hibernate 负责解析 HQL 查询语句, 然后根据对象-关系映射文件中的映射信息, 把 HQL 查询语句翻译成相应的 SQL 语句. HQL 查询语句中的主体是域模型中的类及类的属性。

HQL入门

首先我们来看一下HQL的使用格式:

//进行HQL入门测试
	public void test1() {
		//创建hql查询语句
		String hql = "";
		//生成Query对象
		Query query = session.createQuery(hql);
		
		//执行hql语句返回结果
		
		List<Kind> list = query.list();
		//或
		Kind result = (Kind) query.uniqueResult();
	}

条件查询

下面我们先来看一下条件查询:

条件查询基本上sql语句没有什么差别,只是把主体换成域模型中的类及类的属性,还有一点是在动态绑定参数时可以使用?占位符还可以使用命名占位符。

下面我们写一段代码测试一下:

        @Test
	//HQL的条件查询之?占位符动态绑定参数
	public void test1() {
		//创建hql查询语句
		String hql = "from Kind where kid = ?";
		//生成Query对象
		Query query = session.createQuery(hql);
		
		//设置占位符参数
		query.setParameter(0,"1");
		
		//执行hql语句返回结果
		Kind result = (Kind) query.uniqueResult();
		System.out.println(result);
	}
	
	@Test
	//HQL的条件查询之命名占位符动态绑定参数
	public void test2() {
		//创建hql查询语句
		//命名占位符格式:“:占位符名称”
		String hql = "from Kind where kid = :kid";
		//生成Query对象
		Query query = session.createQuery(hql);
		
		//设置占位符参数
		query.setParameter("kid","1");
		
		//
		//执行hql语句返回结果
		Kind result = (Kind) query.uniqueResult();
		System.out.println(result);
	}


排序

下面我们来使用一下排序功能,排序功能的hql实现和sql实现相同,只不过得将排序对象换成属性。

@Test
	//HQL的条件查询之排序
	public void test3() {
		//order by 属性名 排序规则
		String hql = "from Kind order by kid desc";
		Query query = session.createQuery(hql);
		List<Kind> list = query.list();
		for (Kind kind : list) {
			System.out.println(kind);
		}
	}

分页的实现

哦了,下面我们来看一下分页查询的实现代码:

	@Test
	//HQL的条件查询之分页查询
	public void test4() {
		String hql = "from Kind";
		Query query = session.createQuery(hql);
		//从第几行查询,从0行开始
		query.setFirstResult(0);
		//查询几行
		query.setMaxResults(2);
		List<Kind> list = query.list();
		for (Kind kind : list) {
			System.out.println(kind);
		}
	}


投影查询

投影查询,乍一听挺高大上,其实就是他妈的检索部分属性,话不多说,看看他是如何使用的吧!

@Test
	//HQL的投影查询
	public void test5() {
		//由于我们的Kind类就两个属性,所以我就以这种形式进行投影查询了,看着还复杂一点
		String hql = "select kid,kname from Kind where kid = :kid";
		Query query = session.createQuery(hql);
		query.setParameter("kid","1");
		Object[] kind = (Object[]) query.uniqueResult();
		System.out.println(kind[0]);
		System.out.println(kind[1]);
	}

@Test
	//HQL的投影查询
	public void test6() {
		//由上例可以看出,使用这种方式的投影查询不是很方便,
		//我们期望的时返回一个封装到kind对象中的属性,为达到这一点就得看我们hql的了
		//以这种方式创建kind对象,并且确保在该类中有其构造函数(注意要写无参构造函数)
		String hql = "select new Kind(kname) from Kind where kid = :kid";
		Query query = session.createQuery(hql);
		query.setParameter("kid","1");
		Kind result = (Kind) query.uniqueResult();
		System.out.println(result);
		
	}

连接查询

连接查询分类

1)内连接

1内连接

2迫切内连接

2)外链接

1左外连接与迫切左外连接

2右外连接与右外迫切连接


我们先来看一下内连接的知识吧!

先看一个普通内连接的代码演示:

@Test
	//HQL的内连接查询
	public void test7() {
		//Kind k 看似是给Kind起的别名,实则是创建的对象的对象名,且必须设置
		//inner join 后面在sql中跟的是另一个表,hql里面是对象.属性 ,当然了,
		//这个属性必须在hbm.xml里面是一对多,或多对多。
		String hql = "from Kind k inner join  k.products where k.kid = :kid";
		Query query = session.createQuery(hql);
		query.setParameter("kid","1");
		//返回值肯定不是一个对象即Object[] 中包含kind对象和product对象
		List<Object[]> list = query.list();
		for (Object[] object : list) {
			System.out.print(object[0].getClass().toString());
			System.out.println(object[1].getClass().toString());
		}
		
	}



我们在来看一下hibernate为我们编译的sql查询语句吧!


我们再来看一下查询结果的到的数组的类型:


好了,我们在来看一下迫切内连接的代码演示吧!

	@Test
	//HQL的迫切内连接查询
	public void test8() {
		//和普通内连接唯一的不同就是加了fetch
		String hql = "from  Kind k  inner join fetch k.products";
		Query query = session.createQuery(hql);
		//迫切内连接多做了什么工作呢?就多做了一步,
		//就是讲我们查询到的product对象封装到了kind对象中
		List<Kind> list = query.list();
		for (Kind kind : list) {
			System.out.println(kind);
		}
		
	}

至于外连接我就不说了,和内连接没有什么差别,就是把几个关键字换一换。

其实我挺不明白这些什么连接的,既然是连接就一定是由某种关联关系,而hibernate会为我们级联查找,我很奇怪这个连接查询有什么用呢,可能是我经历太少的原因,这一点日后再来解答。

注意我们使用HQL查询到的对象,也放入了session的二级缓存中了。什么意思呢?就是你也可以对其进行直接修改hibernate会在提交事物时自动刷新缓存的内容到更新到数据库中。

代码证明:

@Test
	//证明HQL查询出来的对象放入了二级缓存中
	public void test8() {
		String hql = "from  Kind where kid = :kid";
		Query query = session.createQuery(hql);
		query.setParameter("kid","5");
		Kind object = (Kind) query.uniqueResult();
		System.out.println(object);
		object.setKname("情趣生活");
		
	}

上面的kid查询kind的sql语句我就不截图了,我们只看剩下的:


看到了吧! 


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值