HQL语句详解-程序员宅基地

技术标签: hql  解决周问题  周总结  hibernate  

什么是HQL呢?

 HQL是Hibernate Query Language的缩写,提供更加丰富灵活、更为强大的查询能力;HQL更接近SQL语句查询语法。同时也提供了更加面向对象的封装。

完整的HQL语句形势如下:
Select/update/delete…… from …… where …… group by …… having …… order by …… asc/desc 非常类似标准的SQL语句。

1、 实体查询:
String hql = "from Customer c"; //查询admin实体类所有的数据
List<Customer> list = session.createQuery(hql).list(); //

可以看到所有的关联信息全部查出来了。

上面的代码执行结果是,查询出Customer实体对象所对应的所有数据,而且将数据封装成Admin实体对象,并且放入list中返回。

 因为HQL语句与标准SQL语句相似,所以我们也可以在HQL语句中使用where字句,并且可以在where字句中使用各种表达式,比较操作符以及使用“and”,”or”连接不同的查询条件的组合。
看下面的一些简单的例子:

from User user where user.age=20; //查询年龄为20的用户
from User user where user.age between 20 and 30;//查询年龄在20~30的用户
from User user where user.age in(20,30);//查询年龄为20,或30的用户
from User user where user.name is null;//查询用户姓名为空的用户
from User user where user.name like%zx%;//模糊查询带有“zx”的用户
from User user where (user.age%2)=1;//查询用户年龄为奇数的用户
from User user where user.age=20 and user.name like%zx%;//查询年龄为20,并且姓名带有“zx”的用户
2.实体的更新与删除

  如果我们想将数据库中所有18岁的用户的年龄全部改为20岁,那么我们要首先将年龄在18岁的用户检索出来,然后将他们的年龄修改为20岁,最后调用Session.update()语句进行更新。如下面的代码:

Transaction trans=session.beginTransaction();//创建事务对象
String hql=”update User user set user.age=20 where user.age=18;
Query queryupdate=session.createQuery(hql);
int ret=queryupdate.executeUpdate();//执行更新
trans.commit();//提交任务
3. 属性查询

 很多时候我们在检索数据时,并不需要获得实体对象所对应的全部数据,而只需要检索实体对象的部分属性所对应的数据。这时候就可以利用HQL属性查询技术,如下面程序示例:
1)返回默认查询出来的list里存放的是一个Object数组,还需要转换成对应的javaBean。

String hql = "select c.name,c.account  from Customer c";//查询客户姓名和账号名
Query query = session.createQuery(hql);
List list = query.list();//得到一个list集合
String string = JSON.toJSONString(list);//为了方便直接输出为字符串
System.out.println(string);

如下图:
和上面的实体查询结果对比就知道了,这一次没有把所有的级联数据查出来。

2)第二种方式是通过HQL语句new POJO()实现,方法如下:
注意:创建一个对象必须有对应的构造器,要不然会报错。

String hql = "select new Customer(c.name,c.account,c.password,c.gender,c.identityId,c.tel) from Customer c"

这样就可以直接用对象调用属性打印了。

结果图:

4.分组与排序

 与SQL语句相似,HQL查询也可以通过order by子句对查询结果集进行排序,并且可以通过asc或者desc关键字指定排序方式,和标准的SQL一样默认升序排列,如下面的代码:

String hql = "from Line L order by L.price ";
5.参数绑定

在Hibernate中共存在4种参数绑定的方式,下面我们将分别介绍:
1)按参数名称绑定:
在HQL语句中定义命名参数要用”:”开头,形式如下:

String hql = "from Line L where L.days=:days";//根据天数查询
		Query query = session.createQuery(hql);
		query.setInteger("days",1);//按名字天数绑定
		List<Line> list = query.list();
		for (int i = 0; i < list.size(); i++) {
    //循环打印
			System.out.println("线路名称:"+list.get(i).getLineName()+"|线路点数:"+list.get(i).getDays()+"|线路价格:"+list.get(i).getPrice());
		}

2)按参数位置邦定:
在HQL查询语句中用”?”来定义参数位置,形式如下:

String hql = "from Line L where L.days=?";//根据天数查询,用?占位符
Query query = session.createQuery(hql);
query.setInteger(0,1);//按名字天数绑定

大家可以看出和1)的方式不同的地方就是参数是用一个==?==占位符代替;然后query方法两个参数第一个是占位符的位置,(从0开始)。如果有多个占位符,那么就他们的位置就是0,1,2,3…

3)setParameter()方法:
在Hibernate的HQL查询中可以通过setParameter()方法邦定任意类型的参数,如下代码:

String hql = "from Line L where L.days=:days";
		Query query = session.createQuery(hql);
		query.setParameter("days", "1");

和第一种的方式区别在于,只能写String类型的数值setParameter(属性名,属性值);

4)setProperties()方法:
在Hibernate中可以使用setProperties()方法,将命名参数与一个对象的属性值绑定在一起,如下程序代码:

Customer customer = new Customer("tz", "111");//
		String hql = "from  Customer c where c.account=:account and c.password=:password ";
		Query query = session.createQuery(hql);
		query.setProperties(customer);
		List<Customer> list = query.list();
		for (int i = 0; i < list.size(); i++) {
			System.out.println("游客id:"+list.get(i).getCustomerId());
		}

setProperties()方法会自动将customer对象实例的属性值匹配到命名参数上,但是要求命名参数名称必须要与实体对象相应的属性同名。

5)setEntity()方法
这里还有一个特殊的==setEntity()==方法,它会把命名参数与一个持久化对象相关联,如下面代码所示:

Customer customer = (Customer)session.get(Customer.class, 1);//获取游客ID为1的持久化对象
		String hql = "from Cart c where c.customer=:customer";
		Query query = session.createQuery(hql);
		query.setEntity("customer", customer);
		List<Cart> list = query.list();
		for (int i = 0; i < list.size(); i++) {
			System.out.println("购物车id:"+list.get(i).getCartId());
		}

总结:对于查询,相比较之下,实体查询属性查询将属性封装成对象的查询方式,前者查询结果会被保存在session的缓存区,只有事务提交过后才会被清除。后者就不存在这种机制,只要系统不在需要它了就会被回收。因此在开发统计查询系统时,尽量使用通过select语句,写出需要查询的属性的方式来返回关系数据,而避免使用第一种查询方式返回持久化对象(这种方式是在有修改需求时使用比较适合),这样可以提高运行效率并且减少内存消耗。


SQL Injection
SQL Injection是一种专门针对SQL语句拼装的攻击方式。之前一直不知道还有这种东西,看完了介绍后自己尝试了一下:

上图是不久前写的一个小项目的客户验证代码截图,也是用的字符串拼接方式。也没与做任何其他的安全措施。
只要能够在库中查询到一个对象就说明验证成功,可是这样就给别人一个sql注入的契机了。
请看下图:我在登录名处输入" tz’ or account ='x ",密码随便打的,因为加了or我的密码就相当于可有可无了,不需要密码正确页可以登录成功。
在这里插入图片描述
debug进入可以看到拼接成了一个只需查用户名就可以登录的sql语句。
在这里插入图片描述
当我们用绑定参数的方式就可以避免这种漏洞了,因为用参数绑定的方式单引号会被当成一个字符串。
下面是我的后台登录,采用绑定参数的方式验证,发现单引号被当成了一个字符,并且被转义了。这样就得不到正确的数据了。
在这里插入图片描述

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/qq_40688398/article/details/90739606

智能推荐

[ubuntu 14.04] android 编译环境搭建_ubuntu20.4编译android8.1-程序员宅基地

文章浏览阅读544次。最近想学习下自己搭建编译安卓源码的服务器。安装了ubuntu 14.04 64位桌面版操作系统。我下载的是 jdk1.7.0_71版本的。下面安装参考:http://www.cnblogs.com/fangbo/p/3941816.html1、下载最新的jdk安装,地址:http://www.oracle.com/technetwork/java/javase/download_ubuntu20.4编译android8.1

[Haskell] CodeWars|Sum of Digits_codewars who likes it?-程序员宅基地

文章浏览阅读326次。https://www.codewars.com/kata/541c8630095125aba6000c00/haskell题目本题你需要写一个Digital Root函数。 Digital root是一个数字所有位的递归和。给定n,算出n各位的和n′n',继续这个操作直到n(p)=n(p−1)n^{(p)}=n^{(p-1)}。以下是范例:digital_root(16)=> 1 + 6=>_codewars who likes it?

练习1-程序员宅基地

文章浏览阅读964次。实现以下需求: 1、baidu公司提供www.baidu.com网站服务,页面显示内容“It’s www.baidu.com”,网站根目录在/www/html目录,网站通过www2.baidu.com也可以正常访问; 2、baidu公司同时提供邮件服务,邮件服务器地址为mail.baidu.com; 3、baidu公司有三个用户,xixi,maomao和haha可以和qq公司的邮件互相收发。...

Java GUI编程的几种常用布局管理器_java为gui提供了哪些布局管理器?-程序员宅基地

文章浏览阅读7.3k次,点赞9次,收藏27次。Java GUI编程的几种常用布局管理器 本人是一个大二的学生。因为最近有做JavaGUI界面的需求,因此重新开始熟悉JavaGUI的各种控件和布局。然后以次博文为笔记,总结、完善以及发表最近学习的一些技术要点。希望各位支持和指正。目录Java GUI编程的几种常用布局管理器目录一BorderLayout默认布局管理器二FlowLayout布局管理器三GridLayout布局管理器四G_java为gui提供了哪些布局管理器?

Quartz在Spring中设置动态定时任务_spring quartz 动态配置-程序员宅基地

文章浏览阅读1w次。什么是动态定时任务: 是由客户制定生成的,服务端只知道该去执行什么任务,但任务的定时是不确定的(是由客户制定)。这样总不能修改配置文件每定制个定时任务就增加一个trigger吧,即便允许客户修改配置文件,但总需要重新启动web服务啊,研究了下Quartz在Spring中的动态定时,发现: cronExpression是关键,如果可以动态设置cronExpression的值,也就说如果我们可以直_spring quartz 动态配置

中南大学c语言程序设计2013年下学期期末考试,2013级计算机专业本科生C语言程序设计期末考试资料.doc...-程序员宅基地

文章浏览阅读87次。中南大学考试试卷—2014学年第 1 学期期末考试试题 时间95分钟计算机与程序设计语言基础 课程40学时 2.5学分 考试形式:闭卷专业年级:计算机科学与技术2013级 总分 100分,占总评成绩70 %注:此页不作答题纸,请将答案写在答题纸上判断对错(101分。对的划“√”,错的划“×”)1.表达式1/4+2.75的值是3。( )函数无返回值,它形参。( )在Turbo C中,实型数据在内..._中南大学c++期末考试

随便推点

IDEA 不自动复制资源文件到编译目录 classes 的问题_idea不会自动复制web文件-程序员宅基地

文章浏览阅读5.8k次。问题:当引入jQuery.js资源文件时,一直报资源文件未找到的问题,在排除路径错误后,再次去target目录下查看,发现target目录下根本没有我所引入的文件。解决方法:1.手动复制文件及目录到target对应目录下,一开始我是这么做的---不建议,更不是长久之计2.推荐,重构项目,会把所有资源文件映射到target目录下..._idea不会自动复制web文件

802.1Q帧格式_画出 802.1q 协议的帧格式-程序员宅基地

文章浏览阅读1.8w次,点赞2次,收藏14次。802.1Q帧格式802.1QTag的长度是4bytes,它位于以太网帧中源MAC地址和长度/类型之间。802.1QTag包含4个字段。Type:长度为2bytes,表示帧类型,802.1Qtag帧中type字段取固定值0x8100,如果不支持802.1Q的设备收到802.1Q帧,则将其丢弃。PRI:priority字段,长度为3bit,表示以太网帧的优先级,取值范围是0~7,数值越大_画出 802.1q 协议的帧格式

CQRS 架构-程序员宅基地

文章浏览阅读2.7k次。CQRS 是一个读写分离的架构思想,全称是:Command Query Responsibility Segregation,即命令查询职责分离,表示在架构层面,将一个系统分为写入(命令)和查询两部分。一个命令表示一种意图,表示命令系统做什么修改,命令的执行结果通常不需要返回;一个查询表示向系统查询数据并返回。读写两边可以用不同的架构实现,方便实现 CQ 两端的分别优化。CQRS 架构里通常读..._cqrs 架构

efishell无法开机shell_电脑出现EFIshellversion解决方法W1048/海尔青春小蓝-程序员宅基地

文章浏览阅读1.2w次,点赞2次,收藏4次。Haier W1048 海尔青春小蓝由于Bios设置错误。UEFI设置为第一启动项后,电脑出现 EFI shell version 2.50 如图。无法进入BIOS也无法操作,到处看帖一遍一遍的尝试终于解决了。方法见文末亲测方法有效。建议回到BIOS恢复最优的BIOS原始设置。进入方法我的机器WIN10系统。长按Shift键,然后开始菜单那里电源重启。请选择疑难解答-高级选项-UEFI固件设置-重..._efi shell version

PHP等级水平评定标准_php 质量级别-程序员宅基地

文章浏览阅读7.1k次。《PHP等级水平评定标准》,又看到了前进的方向。分享下,这样和我曾经一样迷茫的phper不用迷茫了。 0级:(没有计算机编程基础,在培训学校里培训了三个月会php或者以前搭建过网站,又有很长一段时间没写过代码的社会人员)。特点:懂一大堆东西都说学过,实际测试的时候,机试写程序上反应半天,笔试的时候,题目鲜有答对。 入门级: 可以完整的搭建自己的网站和进行域名_php 质量级别

matlab图像处理实现简单机器视觉_matlab机器视觉算子有多少-程序员宅基地

文章浏览阅读6.6k次,点赞7次,收藏77次。使用matlab对图像进行简单处理并分析不同处理方法的特点对不同曝光程度的图像进行均衡化处理数据代码段%直方图均衡化figure;srcimage=imread('C:\Users\27019\Desktop\机器视觉\图1-2.jpg');info=imfinfo('C:\Users\27019\Desktop\机器视觉\图1-2.jpg');subplot(2,3,1);ims..._matlab机器视觉算子有多少

推荐文章

热门文章

相关标签