eclipse学习(第三章:ssh中的Hibernate)——8.Hibernate里面的查询语言(使用hql帮助开发)

1 前言

本文参考自https://www.w3cschool.cn/hibernate/hvqb1ie5.html后做的一个实践日志记录。

2 什么叫Hibernate查询语言(hql)

Hibernate 查询语言(HQL)是一种面向对象的查询语言,类似于 SQL但不是去对表和列进行操作,而是面向对象和它们的属性。 HQL 查询被 Hibernate 翻译为传统的 SQL 查询从而对数据库进行操作。

尽管你能直接使用本地 SQL 语句,但我还是建议你尽可能的使用 HQL 语句,以避免数据库关于可移植性的麻烦,并且体现了 Hibernate 的 SQL 生成和缓存策略。

在 HQL 中一些关键字比如 SELECT ,FROM 和 WHERE 等,是不区分大小写的,但是一些属性比如表名和列名是区分大小写的

3 实际使用示例

我这里不打算上我写的全部代码,如果你看不是很懂在考虑下载问题吧,因为其实每个方法就修改了一个内部内容罢了。基本上看一下就能看懂了。

3.1 FROM 语句

使用FROM语句,这是全部查询,全部获取一般就用这种直接from +实体类即可,不需要搞select *这种操作,搞了反而出问题,多数情况下直接from+实体类名即可,如果你想完全限定类名也可以,from + 实体类项目路径

List<Mark> markList = null;
		try {
			transaction = session.beginTransaction();
			String hql = "from Mark";
			//你也可以选择下面这种方式来设置hql,这是完全限定类名
//			String hql = "from com.czx.hql.pojo.Mark";
			Query q = session.createQuery(hql);
			markList = q.getResultList();
			transaction.commit();

3.2 AS语句

使用AS语句,我这里还多做了一个获取数目处理,其实在这个as加不加都可

List<Mark> markList = null;
		try {
			transaction = session.beginTransaction();
//			String hql = "from Mark as m";
			//你也可以选择下面这种方式来设置hql,不需要加入as也可以直接指定别名
			String hql = "from Mark m";
			Query q = session.createQuery(hql);
			//设置起始的结果
			q.setFirstResult(0);
			//设置一共多少条结果
			q.setMaxResults(1);
			markList = q.getResultList();
			transaction.commit();

3.3 select语句

这里获取数据,也是要对应实体类的属性要注意一下。带_为数据库的属性,不带大写为实体类属性

List<Object[]> markList = null;
		try {
			transaction = session.beginTransaction();
			//一定要记住,这里使用select获取单个属性数据,这里语句写的对应的是类属性
			String hql = "select m.studentName , m.subject from Mark m";
			Query q = session.createQuery(hql);
			markList = q.getResultList();
			transaction.commit();

3.4 WHERE 语句(使用命名参数)

where语句,做一个条件判断,注意这里防止了sql注入,所以hql语句并没直接写值。
Hibernate 的 HQL 查询功能支持命名参数。这使得 HQL 查询功能既能接受来自用户的简单输入,又无需防御 SQL 注入攻击。

List<Object[]> markList = null;
		try {
			transaction = session.beginTransaction();
			//一定要记住,这里使用select获取单个属性数据,这里语句写的studentName对应的是类属性
			String hql = "select m.studentName , m.subject from Mark m where student_name = :studentName";
			Query q = session.createQuery(hql);
			q.setParameter("studentName", name);
			markList = q.getResultList();
			transaction.commit();

3.5 ORDER BY 语句

倒序为desc,升序为asc,默认使用的是升序asc,你也可以使用多属性排序,先按第一个属性排序,如果第一个属性相同,那么在按照第二个属性排序,用逗号分隔

List<Mark> markList = null;
		try {
			transaction = session.beginTransaction();
			//这里以得分倒序为例子desc,升序为asc,默认使用的是升序asc
//			String hql = "from Mark m order by score desc";
			//使用多属性排序,在这里得分使用升序,id使用降序
			String hql = "from Mark m order by score asc , id desc";
			Query q = session.createQuery(hql);
			markList = q.getResultList();
			transaction.commit();

3.6 GROUP BY 语句

group by语句,进行分组处理,一般来说这种会跟聚合方法联系起来。

List<Object[]> markList = null;
		try {
			transaction = session.beginTransaction();
			//这里以聚合老师名称为例子
			String hql = "select teacherName , count(*) from Mark m group by teacher_name";
			Query q = session.createQuery(hql);
			markList = q.getResultList();
			transaction.commit();

3.7 UPDATE 语句

这里也是update + 实体类名称这种格式

Integer flag = null;
		try {
			transaction = session.beginTransaction();
			//这里尝试着修改一下数据,这里的update后面也是只能写实体类名称
			String hql = "update Mark set subject = :subject where id = :id";
			Query q = session.createQuery(hql);
			q.setParameter("subject", "历史");
			q.setParameter("id", "1");
			flag = q.executeUpdate();
			transaction.commit();

3.8 DELETE 语句

这里也是delete from + 实体类名

Integer flag = null;
		try {
			transaction = session.beginTransaction();
			//这里尝试着删除数据,这里的delete from后面要跟实体类名称
			String hql = "delete from Mark where id = :id";
			Query q = session.createQuery(hql);
			q.setParameter("id", "1");
			flag = q.executeUpdate();
			transaction.commit();

3.9 INSERT 语句(这个加入有限制条件)

先说一句,你不要以为这个insert可以用来直接加一条数据,如果你要这么做推荐你使用save方法,这个hql里面使用insert语句是用来将另一个表数据插入到当前表的。
HQL 只有当记录从一个对象插入到另一个对象时才支持 INSERT INTO 语句。我们如果你要增加数据调用save方法即可。

Integer flag = null;
		try {
			transaction = session.beginTransaction();
			//这里尝试着修改一下数据,这里的update后面也是只能写实体类名称
			String hql = "INSERT INTO Mark(id , studentName, subject , score , teacherName)"+
			"SELECT id, studentName, subject , score , teacherName FROM OldMark";
			Query query = session.createQuery(hql);
			flag = query.executeUpdate();
			transaction.commit();

3.10 聚合方法(去重也在里面)

聚合方法一览

方法描述
avg(property name)属性的平均值
count(property name or *)属性在结果中出现的次数
max(property name)属性值的最大值
min(property name)属性值的最小值
sum(property name)属性值的总和

distinct 关键字表示只计算行集中的唯一值,这里写了两个不同的hql,你们可以看看

List<Object> markList = null;
		try {
			transaction = session.beginTransaction();
			//这里使用一下去重,这里是获取到不重复的老师名字
//			String hql = "select distinct teacherName from Mark";
			//这里使用一下聚合方法的去重,先获取到去重后的老师名字行,然后在计算有多少条
			String hql = "select count(distinct teacherName) from Mark";
			Query q = session.createQuery(hql);
			markList = q.getResultList();
			transaction.commit();

3.11 分页查询

下面这个是获取到一条数据。

List<Mark> markList = null;
		try {
			transaction = session.beginTransaction();
			//分页查询
			String hql = "from Mark";
			Query q = session.createQuery(hql);
			//设置起始的位置
			q.setFirstResult(0);
			//设置获取显示的条数
			q.setMaxResults(1);
			markList = q.getResultList();
			transaction.commit();

中途不小心出现的异常

1、Caused by: java.sql.SQLSyntaxErrorException: Table ‘student.hibernate_sequence’ doesn’t exist

这里显示你缺少了一个student.hibernate_sequence的表,我想了很久终于找到了问题在哪。
你在设置实体类主键上面加入了这个

@GeneratedValue

里面有个属性,我来说一下
strategy:表示主键生成策略,有AUTO,INDENTITY,SEQUENCE 和 TABLE 4种,分别表示让ORM框架自动选择,
根据数据库的Identity字段生成,根据数据库表的Sequence字段生成,以有根据一个额外的表生成主键,默认为AUTO
这里我们没声明,所以默认变成了AUTO,那么就需要根据一个额外的表来生成主键这个我们就实现不了。所以报错。

2、Caused by: org.hibernate.QueryException: No data type for node: org.hibernate.hql.internal.ast.tree.IdentNode ±[IDENT] IdentNode: ‘teacher_name’ {originalText=teacher_name}

出现这个问题的主要原因是因为select里面写的也要是对应类里面的属性才行
如果你写成select teacher_name,那就报错了,要写成跟类对应上的select teacherName这种才行

3、主要的问题

这里多数就是有些地方需要写上实体类修改后的属性名,如果出现问题基本都是这里,当然了这个hql没有增加的选项,建议直接调用save方法。这个insert into在这里只能用于旧表数据导入进新表。

项目地址

不是很建议看,因为其实看上面的基本能看懂,看不懂在下载看看吧。数据库数据也在里面了。
https://gitee.com/mrchen13427566118/ssh_hibernate_learn.git
里面的ssh_hibernate_hql项目。
怎么下载到本地运行可以看这里的第三点https://blog.csdn.net/weixin_43987277/article/details/116936221

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值