前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >Hibernate对象导航语言

Hibernate对象导航语言

作者头像
爱撒谎的男孩
发布于 2019-12-31 06:56:18
发布于 2019-12-31 06:56:18
92400
代码可运行
举报
文章被收录于专栏:码猿技术专栏码猿技术专栏
运行总次数:0
代码可运行

文章目录

  1. 1. HQL - 对象导航语言
    1. 1.1. 简介
    2. 1.2. 步骤
    3. 1.3. 准备
    4. 1.4. 实体查询
      1. 1.4.1. 格式
      2. 1.4.2. 拓展
      3. 1.4.3. 实例
    5. 1.5. 部分字段的查询
      1. 1.5.1. 格式
      2. 1.5.2. 实例
    6. 1.6. 多表联合查询
    7. 1.7. 前提
      1. 1.7.1. 常见的联合查询方式
      2. 1.7.2. 对象方式关联查询
        1. 1.7.2.1. 实例
      3. 1.7.3. join方式查询
        1. 1.7.3.1. 左外连查询
          1. 1.7.3.1.1. 格式
          2. 1.7.3.1.2. 实例
        2. 1.7.3.2. 右外连接查询
          1. 1.7.3.2.1. 格式
          2. 1.7.3.2.2. 实例
        3. 1.7.3.3. 迫切左外连接
        4. 1.7.3.4. 迫切右外连接
        5. 1.7.3.5. select子句关联查询
          1. 1.7.3.5.1. 格式
          2. 1.7.3.5.2. 实例
    8. 1.8. 去除重复的数据
    9. 1.9. 聚合函数的查询
      1. 1.9.1. 常见的聚合函数
    10. 1.10. order by子句
    11. 1.11. group by 子句
    12. 1.12. 参考文章

HQL - 对象导航语言

简介

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

步骤

  1. 获取Session对象
  2. 编写hql语句
  3. 使用session.createQuery(String hql)创建Query对象
  4. 使用session.setXX(index,Object)设置占位符的值
  5. 执行query.list()获取实体对象即可

准备

  • 创建Husband实体类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
package cn.tedu.hibernate.entity;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

@Entity
@Table(name="husband")
public class Husband implements Serializable{
	private static final long serialVersionUID = 7403209578400736239L;
	private Integer id;
	private String name;
	private int age;
	private Wife wife;
	
	@Id
	@GeneratedValue   //主键自增长
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	@Column(length=10)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	
	@OneToOne(fetch=FetchType.LAZY) 
	@JoinColumn(name="wife_id")   //设置外键名称为wife_id
	public Wife getWife() {
		return wife;
	}
	public void setWife(Wife wife) {
		this.wife = wife;
	}
	
	@Override
	public String toString() {
		return "Husband [id=" + id + ", name=" + name + ", age=" + age
				+ ", wife=" + wife + "]";
	}
}
  • 创建Wife的实体类
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name="wife")
public class Wife implements Serializable {
	private static final long serialVersionUID = -7203920255946679244L;
	private Integer id;
	private String name;
	private int age;
	@Id
	@GeneratedValue
	public Integer getId() {
		return id;
	}
	public void setId(Integer id) {
		this.id = id;
	}
	
	@Column(length=10)
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	@Override
	public String toString() {
		return "Wife [id=" + id + ", name=" + name + ", age=" + age + "]";
	}
}
  • 创建工具类,用来生成Session
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
public class HibernateUtil {
	private static Configuration configuration;
	private static SessionFactory sessionFactory;
	/*
	 * 静态语句块中的内容只是在类加载的时候只创建一次,因此这里的大大减少了资源的消耗
	 */
	static {
		// 加载核心配置文件hibernate.cfg.xml
		configuration = new Configuration();
		configuration.configure();
		// 创建SessionFactotry对象
		sessionFactory = configuration.buildSessionFactory();
	}
	//创建session对象,在测试类中可以使用这个静态方法获取session
	public static Session getSession() {
		return sessionFactory.openSession();
	}
}

实体查询

  • 查询结果返回的是一个List<>的集合。其中的泛型为实体类
  • 相当于sql语句中的select * from husband;
  • 使用的hql语句是from Husband where id=?,这里还可以和sql语句一样使用别名来获取其中的值,比如: from Husband h where h.id=?

格式

  • from Husband where id=? ,其中的Husband是实体类的名字,而不是表的名称,后面的属性实体类中的属性名称,而不是表中字段的名称,区分大小写

拓展

  • where子句中只要是sql语句被能够满足的都是可以写的,比如=, , <, >, <=, >=, between, not between, in ,not in, is, like,同时也是可以写算术表达式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
FROM User user WHERE user.age<20
FROM User user WHERE user.name IS null
FROM User user WHERE user.name LIKE 'Er%'
FROM User user WHERE (user.age % 2 = 1)
FROM User user WHERE (user.age<20) AND (user.name LIKE '%Er')

实例

  • 查询husband这张表,其中对应的实体类是Husband
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Test
	public void test1() {
		Session session = null;
		Transaction transaction = null;
		try {
			// 创建session
			session = HibernateUtil.getSession();
			// 开始事务
			transaction = session.beginTransaction();
            
			//编写hql语句
			String hql="from Husband where id=?";
            //String hql="from Husband h where h.id=?";
            
			//创建Query
			Query query=session.createQuery(hql);
			//设置占位符的值,这里的用法和PreparedStatement一样的用法
			query.setInteger(0,1);
			List<Husband> husbands=query.list();  //执行查询语句,返回的是list集合
			
			for (Husband husband : husbands) {
				System.out.println(husband);
			}
			
			// 提交事务
			transaction.commit();
		} catch (Exception exception) {
			transaction.rollback(); // 事务回滚
		} finally {
			if (session != null) {
				session.close();
			}
		}
	}

部分字段的查询

  • 实体对象的查询返回的是一个实体对象的List<>集合,我们这里需要查询的是表中的执行字段,而不是全部的字段

格式

  • select 实体类属性名 from 实体类名字 where 条件语句

实例

  • 查询出id=1的所有的husband中的name和age
    • sql语句:select name,age from husband where id=1
    • hql语句: select name,age from Husband h where h.id=?,此时的占位符id的值为1
  • 此时查询返回的结果List是一个Object[],其中的元素是nameage,并且是按照hql的语句的查询顺序存储的
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//编写hql语句,只查询name和age属性字段
String hql="select name,age from Husband where id=?";
//创建Query
Query query=session.createQuery(hql);
//设置占位符的值,这里的用法和PreparedStatement一样的用法
query.setInteger(0,1);

//这里返回的是一个List集合,但是其中的每一个元素都是一个Object数组
List<Object[]> lists=query.list(); 
//遍历List集合
for (Object objects : lists) {
	//遍历数组,[0]的元素是name,[1]的元素是age
	for(int i=0;i<objects.length;i++){
		System.out.println(objects[i]);
	}
}
  • 这里查询的是两个字段,返回的结果List中存放的是Object[]但是如果我们查询的只有一个字段,那么返回的结果List中存放的是Object,这个值是你查询的字段的值

多表联合查询

前提

  • 必须存在关联关系,比如一对一,一对多,多对多

常见的联合查询方式

  1. 对象方式的关联查询
    1. 这个是HQL所特有的,因为这个需要用到对象之间的关系
  2. join方式关联
  3. select子句关联

对象方式关联查询

  • 假设我们需要查询wifeid值为1的husband表中指定的字段,我们除了使用多表联合查询,我们也可以使用关联查询,因为在Husband的实体类中有Wife这个对象
    • hql语句: select name,age from Husband h where h.wife.id=?
实例
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//编写hql语句,where字句中的条件是wife的id
	String hql="select h.name,w.name from Husband h,Wife w where h.wife.id=? ";
	//创建Query
	Query query=session.createQuery(hql);
	//设置占位符的值,这里的用法和PreparedStatement一样的用法
	query.setInteger(0,1);
	
	List<Object> lists=query.list();
	
	//遍历查询结果
	for (Object object : lists) {
		Object[] objects=(Object[])object;
		for (int i = 0; i < objects.length; i++) {
			System.out.println(objects[i]);
		}
	}

join方式查询

左外连查询
  • 这个是等值连接的一种,即使两张表中的某一条数据不存在关联关系,那么也会全部查询出左边的那张表的全部数据
  • sql语句:select * from husband h left join wife w on h.wife_id=w.id,查询丈夫的所有数据并且和其对应妻子的信息,其中husbandwife这两张表是通过wife_id这个外键关联的
  • hql语句: select h.name,h.age,w.name,w.age from Husband h left join h.wife w,这条语句和上面的sql语句是一样的功能
格式
  • select 实体类属性 from 实体类名 [as] 别名 left join 别名.关联对象名 [as] 别名
    • 其中的as可以省略
    • 如果不需要查询关联对象的属性,那么后面的别名可以省略
    • left join后面跟的是实体类的关联对象,比如Husband中的Wife对象h.wife,这里就相当sql中的on h.wife_id=w.id
实例
  • 查询所有丈夫的信息和其对应的妻子的所有信息
  • hql: from Husband h left join h.wife,虽然这里的使用的是实体查询的方式,但是返回的却是Object[],其中的第一个元素是Husband对象,第二个是Wife对象
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//编写hql语句
String hql="from Husband h left join h.wife";
//创建Query
Query query=session.createQuery(hql);

//执行查询,这里返回的是一个Object数组,其中数组的第一个元素是husband的数据,第二个是wife的数据
List<Object[]> list=query.list();
for (Object[] objects : list) {
	Husband husband=(Husband) objects[0];  //获取Husband对象
	Wife wife=(Wife)objects[1];  //获取Wife对象
}
  • 查询所有的丈夫信息和起对应的妻子的所有信息,这个和上面的例子一样,只不过是另外一种hql语句方式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//编写hql语句
String hql="select h,w from Husband h left join h.wife w";
//创建Query
Query query=session.createQuery(hql);

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

for (Object[] objects : list) {
	Husband husband=(Husband) objects[0];  //获取Husband对象
	Wife wife=(Wife)objects[1];  //获取Wife对象
}
  • 查询所有丈夫的nameage和其对应的妻子的的nameage信息
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//编写hql语句
String hql="select h.name,h.age,w.name,w.age from Husband h left join h.wife w";
//创建Query
Query query=session.createQuery(hql);

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

for (Object object : list) {
	Object[] objects=(Object[])object;
	for (int i = 0; i < objects.length; i++) {
		System.out.print(objects[i]+"\t");
	}
	System.out.println();
}
  • 查询丈夫的所有信息
右外连接查询
  • 右外链接查询和左外连接查询的方式是一样的,只是此时如果出现两条记录没有关联关系的话,那么保留的是右边的表中的数据,即是查询右边表的所有数据和其对应的左边表的数据
格式
  • select 实体类属性 from 实体类名 [as] 别名 right join 别名.关联对象名 [as] 别名
    • 其中的as可以省略
    • 如果不需要查询关联对象的属性,那么后面的别名可以省略
    • right join后面跟的是实体类的关联对象,比如Husband中的Wife对象h.wife,这里就相当sql中的on h.wife_id=w.id
实例
  • 查询所有妻子的信息和其对应的丈夫的信息: select h,w from Husband h right join h.wife w
迫切左外连接
迫切右外连接
select子句关联查询
格式
  • select 对象.属性名,.... from 类名
    • 其中的对象实体类中的对象属性,比如Husband类中的Wife对象
实例
  • select h.wife.name,h.wife.age,h.name from Husband h
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
//编写hql语句,where字句中的条件是wife的id
String hql="select h.wife.name,h.wife.age,h.name from Husband h";
//创建Query
Query query=session.createQuery(hql);
//设置占位符的值,这里的用法和PreparedStatement一样的用法

List<Object> lists=query.list();

//遍历查询结果
for (Object object : lists) {
	Object[] objects=(Object[])object;
	for (int i = 0; i < objects.length; i++) {
		System.out.println(objects[i]);
	}
}

去除重复的数据

  • sql语句一样,使用distinct即可
  • 比如: select distinct name,age from Husband where id=?

聚合函数的查询

  • hql语句和sql一样,都是可以使用聚集函数查询
  • select count(*) from Husband where id=? 根据id查询出对应的人数

常见的聚合函数

  • count(*): 计算数量
    • select count(*) from Husband where id=?
  • sum() :求和
    • select sum(age) from Husband h where h.wife.id=?
  • AVG(): 求平均值
    • select avg(age) from Husband where age>10
  • MAX(): 求最大值
    • select max(age) from Husband where age>10 and age<90
  • MIN(): 求最小值
    • select min(age) from Husband where age>10 and age<100

order by子句

  • from Husband where id=? order by name desc,age asc 按照姓名将序排列,年龄升序排列

group by 子句

  • hql中也是可以使用group by子句进行分组的,比如select count(*),sum(age),max(age) from Husband h where h.age>? group by h.name
  • 同时也是可以使用having子句进行聚合函数的条件过滤,比如select count(*),sum(age),max(age) from Husband h where h.age>? group by h.name having count(*)>?

参考文章

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-04-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
Hibernate检索1
Hibernate 的关联关系,通过关联关系能够对数据库表进行简单的操作。在大多数应用中,查询属于最重要的部分,而目前我们只能使用get方法和 load方法进行简单的查询,本章将主要讲解Hibernate的查询操作。
张哥编程
2024/12/19
1260
《Java从入门到放弃》框架入门篇:hibernate查询——HQL
不知不觉又到了hibernate的最后一篇了,只感觉时光飞逝~,岁月如梭~! 转眼之间,我们就···························,好吧,想装个X,结果装不下去了,还是直接开始吧· 前面我们已经把hibernate中添加、删改、修改和根据ID得到对象的方法都学习了,但如何才能查询出多条记录呢?比如我想查询所有姓黄的作者,查询标题包含“中”字的博客等。这一篇就来介绍查询。 hibernate有两种检索(查询)数据的方式,分别是HQL(Hibernate Query Language)和QBC
十方上下
2018/06/14
8570
Hibernate HQL详解
HQL(Hibernate Query Language) 是Hibernate框架提供的一种查询机制,它和 SQL 查询语言很相似。不同的是HQL是面向对象的查询语言,让开发者能够以面向对象的思想来编写查询语句,对Java编程来说是很好的一种方式。
南风
2019/04/22
2.4K0
Hibernate HQL详解
Hibernate HQL查询
Hibernate Query Language(HQL)是Hibernate框架中使用的一种面向对象的查询语言。它类似于SQL,但更关注对象和实体的属性而不是表和列。HQL允许您在不依赖特定数据库的情况下执行查询操作,并提供了一种强大而灵活的方式来检索、操作和管理持久化对象。
堕落飞鸟
2023/05/16
8340
SSH框架之旅-hibernate(4)
QBC 查询是通过 Restrictions 类的静态方法来实现的,具体的方法如下表所示。
Wizey
2018/08/30
1.7K0
SSH框架之旅-hibernate(4)
Hibernate查询方式
load它不会去立刻查询而是生成一个代理对象由于没有去查询它只包含你给的OID,直到你用到其他属性才会去查询给你
木瓜煲鸡脚
2019/09/17
8520
Hibernate查询方式
Hibernate_day03总结
Hibernate_day03总结 今日内容 l Hibernate的检索方式 l Hibernate的抓取策略 l Hibernate的批量检索 l 事务的并发问题 1.1 上次课内容回顾: Hibernate的持久类三种状态: * 瞬时态:没有唯一标识OID,没有被session管理 * 持久态:有唯一标识OID,被session管理 * 脱管态:有唯一标识OID,没有被session管理. * 状态转换: 瞬时态:new 获得. * 瞬时à持久:save/saveOrUpdate * 瞬时à脱管:
Java帮帮
2018/03/19
1.1K0
Hibernate_day03总结
Hibernate第四天:Hibernate的查询方式、抓取策略
在Hibernate中提供了很多种的查询的方式。Hibernate共提供了五种查询方式。
AlbertYang
2020/09/08
1.7K0
Hibernate第四天:Hibernate的查询方式、抓取策略
Hibernate关联关系
文章目录 1. Hibernate关联关系 1.1. 一对一 1.1.1. 背景 1.1.2. 准备 1.1.3. 单向外键关联 1.1.3.1. 通过丈夫访问妻子 1.1.3.2. 通过妻子访问丈夫 1.1.3.3. 总结 1.1.4. 双向外键关联(@OneToOne(mappedBy=””) 1.1.4.1. 问题 1.1.4.2. 解决办法 1.1.4.3. 实现 1.1.4.4. 测试 1.2. 一对多 1.2.1. 准备 1.2.2. 前提须知 1.2.3. 单向外键关联 1.2.3.1.
爱撒谎的男孩
2019/12/31
6.3K1
Hibernate查询技术之HQL语句
1、session中的get( )和load( )方法来查询对象。但其查询功能有限。
大黄大黄大黄
2018/09/14
1.6K0
【框架】[Hibernate]构架知识点常见操作
配置文件、JavaBean、HibernateSessionFactory等代码,请看上一篇: 【框架】[Hibernate]构架知识点详解入门与测试实例
谙忆
2021/01/21
6980
Hibernate学习笔记 查询简介
在介绍Hibernate查询语言之前,首先我们来建立一下数据库。这里直接使用了MySQL自带的样例数据库world。如果你没有安装MySQL那么需要安装一下,并且在安装的时候选择安装样例数据库。
乐百川
2022/05/05
4180
Hibernate框架HQL语句
这篇随笔将会记录hql的常用的查询语句,为日后查看提供便利。 在这里通过定义了三个类,Special、Classroom、Student来做测试,Special与Classroom是一对多,Classroom与Student是一对多的关系,这里仅仅贴出这三个bean的属性代码: Special类: public class Special { private int id; private String name; private String type; private S
二十三年蝉
2018/02/28
1.1K0
day31_Hibernate学习笔记_03
在数据库表中如何表达多对多关系:   使用中间表,分别引用两方的ID。 在对象中如何表达多对多关系:   两方都使用集合表达。 在配置文件中如何表达一对多关系:
黑泽君
2018/10/11
2.5K0
day31_Hibernate学习笔记_03
Hibernate详细教程
一、搭建Hibernate环境 1.在src目录下创建hibernate.cfg.xml配置文件 PS:文件的名字不能改! <?xml version="1.0" encoding="UTF-8"?>
庞小明
2018/03/07
1.3K0
Hibernate详细教程
hibernate 检索方式[通俗易懂]
HQL(Hibernate Query Language) 是面向对象的查询语言, 它和 SQL 查询语言有些相似. 在 Hibernate 提供的各种检索方式中, HQL 是使用最广的一种检索方式. 它有例如以下功能:
全栈程序员站长
2022/07/08
1K0
hibernate 检索方式[通俗易懂]
Hibernate_day01总结
第1章 Hibernate_day01总结 今日内容 Hibernate框架的概述 Hibernate的快速入门 Hibernate核心API的介绍 Hibernate的持久化类 主键的生成策略 1.
Java帮帮
2018/03/19
1.3K0
Hibernate_day01总结
Hibernate查询方式之:HQL查询(需要使用的类是:Query)
hibernate查询方式之:HQL查询方式: HQL语句正对的是实体类的名称和实体类的属性进行操作 1.查询所有 格式:from 实体类名称 Query query = session.createQuery(“from User”); List<User> list = query.list(); for(User u :list){ System.out.println(u); } 2.条件查询 (1)from 实体类名称 where 实体类的属性名称=
全栈程序员站长
2022/06/30
9370
Java-SQL注入
JDBC使用Statement是不安全的,需要程序员做好过滤,所以一般使用JDBC的程序员会更喜欢使用PrepareStatement做预编译,预编译不仅提高了程序执行的效率,还提高了安全性。
UzJu@菜菜狗
2023/10/20
5560
Java-SQL注入
Hibernate【查询详解、连接池、逆向工程】
前言 在Hibernate的第二篇中只是简单地说了Hibernate的几种查询方式….到目前为止,我们都是使用一些简单的主键查询阿…使用HQL查询所有的数据….本博文主要讲解Hibernate的查询操
Java3y
2018/03/15
1.3K0
Hibernate【查询详解、连接池、逆向工程】
相关推荐
Hibernate检索1
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验