java hql 查询所有内容,HQL查询语言转载

 2023-09-11 阅读 14 评论 0

摘要:上一章介绍了Hibernate的关联映射,在11章的例子中接触到了Hibernate的添加、查询和删除的操作。这一章将介绍Hibernate。Hibernate查询语言为HQL(HibernateQueryLanguage),可以直接使用实体类名及属性。HQL语法类似于SQL,有SQL的关键词如select、from、o

上一章介绍了Hibernate的关联映射,在11章的例子中接触到了Hibernate的添加、查询和删除的操作。这一章将介绍Hibernate。Hibernate查询语言为HQL(Hibernate Query Language),可以直接使用实体类名及属性。HQL语法类似于SQL,有SQL的关键词如select、from、order by、count()、where等等。

12.1 HQL语言基础

Hibernate查询语言为HQL(Hibernate Query Language),可以直接使用实体类名及属性。HQL语法类似于SQL,有SQL的关键词如select、from、order by、count()、where等等。不同的是HQL是一种完全面向对象的语言,能够直接查询实体类及属性。

JAVA语言?12.1.1 HQL语法

HQL语法类似于SQL,是一种select...from...的结构。其中,from后跟的是实体类名,而不是表名。select后面跟的可以是实体对象,也可以使实体对象的属性或者其他值,例如:

Query query = session.createQuery(" select * from Users as users ");// 查询所有的Users

List list = query.list();

用java查询数据库表中的数据。// 执行查询,返回List

其中,Users为实体类Users,users为Users对象,关键词as用法同SQL,可以省略。Query是Hibernate的查询对象,query.list()将以List类型返回查询结果。上述查询也可以简写为:

Query query = session.createQuery(" from Users ");

// 查询所有的Users

java获取数据库表字段。List list = query.list();

// 执行查询,返回List

12.1.2 HQL中的大小写

HQL语言大小写不敏感,“select * from Users as users”也可写作“SELECT * FROM Users as users”。但是涉及到Java类名、package名、属性名时,需要区分大小写,因此Users必须与类名一致。

java语言属于什么语言,12.1.3 查询中使用包名

一个工程中,如果不存在相同的实体类名,查询语句中实体类所在的package可省略。Hibernate会能够根据类名检索到实际的t实体类。但如果有相同的实体类名,查询时必须携带package信息,否则Hibernate不知道使用哪一个实体类。使用包名的查询语句实例代码如下:

SELECT users FROM com..java.vo.Users users

12.1.4 查询结果的返回类型

jdbctemplate.query、Hibernate使用Query对象进行查询。Session的createQuery方法能够创建Query实例,参数为HQL。Query对象能够返回各种类型的查询结果,例如long、String、List<实体类名>、List、POJO等。最常用的查询方法有uniqueResult()与list()等。其中uniqueResult()返回单个值,而list()返回零个或者多个值。下面分别介绍uniqueResult()与list()。

1. uniqueResult()返回单个值

Query的unique()返回单个的对象。使用unique()获取返回值时,HQL语句查询到的结果最多只能有一个,如果结果多于一个,unique()方法会抛出异常。如果没有,会返回null。这个方法常常用来查询记录总数,因为总会返回一个对象,并且也只有一个。例如:

Query q = session.createQuery(" select count(*) from Users ");

java.sql?// 创建查询对象

Number num = (Number)q.uniqueResult();

// 返回单个实例

int count = num.intValue();

编程语言有哪些。// 返回数值

查询总数时,HQL格式必须为“select count(*) from Users”的格式。返回值可能为Short、Integer、Long、BigInteger等各种类型,具体返回类型根据主键的类型而定。这里可以用所有数值类型的父类Number类型。

2. list()返回集合

Query的list()方法是最常用的方法。实际上,unique()方法也是在list()方法得到返回数据后执行的。list()总是返回一个java.util.List对象,里面有零个或者多个值。list()可以返回实体对象,也可以返回实体对象的某属性或者某些属性。例如:

java重写。List<Users>list1 = session.createQuery(" select*fromUsers").list();

Listlist2= session.createQuery(" selectusers.name fromUsers users").list();

List nlist3= session.createQuery(" selectusers.name,users.dept.namefromUsers users").list();

List<Users>list4= session.createQuery(" selectusers.deptfromUsers users").list();

sql query?第一个查询返回存储着Users对象的List。第二个查询返回存储着Users的name值(String类型)的List。第三个查询返回存储着由Users的name值、Users对应的Dept的name值组成的字符串数组(String[]类型)的List。第四个查询返回存储着Users对应的Dept的List,虽然是Users的一个属性,但仍然是Users类型。

12.2 查询结果同时返回多个对象

Query的list()方法返回java.util.List对象。List中一般存储完整的实体类对象。例如“select * from Users”,会将所有的Users都查询出来,包含Users类的所有即时加载的属性。

对于有些查询,只需要查询几个属性就够了,而不需要查询所有的实体类属性。这时候可以在HQL中指定要返回的部分。查询部分属性时,返回结果仍然是List类型,里面可能是单个的对象Object,也可能是对象数组Object[],还可能是List对象与Map对象。返回什么样的类型数据,由HQL语句决定。

12.2.1 返回List集合

返回结果还可以放到List中。查询时HQL采用“select new List(name1, name2, name3) from...”的形式。同样需要遍历List来获取返回的List,再遍历返回的List获取查询结果,实例代码如下:

// 查询三个字段,放入一个新的List集合中,再返回List集合对象list1

List list1 = session.createQuery(

" select new List(u.name, u.address,u.password) from Users u").list();

for (List li : list1) {

// 遍历第一层List集合

for (Object o : li) {

// 遍历第二层List集合(保存3个字段的集合)

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

// 输出对象Object

}

}

上述的代码中,在查询语句中把查询的字段放入List集合中,再把createQuery()查询的结果放入到List集合中。通过for循环两次遍历,把集合中的对象遍历出来。

12.2.2 返回对象数组Object[]

查询多个属性时,Hibernate将同时返回多个对象(以Object[]类型返回)。返回的数组是放到List中的,得到返回的数组需要遍历List对象,示例代码如下:

Listlist = session.createQuery(

" select u.name, u.address,u.password from Users u ").list();

// 查询Users中的多个属性值,返回list

for (Object[] obj : list) {

// 遍历装有数组的list集合

for (Object object : obj) {

// 遍历数组

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

// 输出遍历结果Object

}

}

上述代码查询多个属性,返回的是数组,如果只查询一个属性,则不会返回数组,而直接返回该类型数据。例如“select u.name from Users u”,将返回List。

12.2.3 返回实体类对象

这里说的实体类对象是指Java的实体类对象。如果只查询部分属性,返回数组、List、Map时很方便,但是操作Object[]数组、List、Map等不如操作实体对象方便。所以实际上查询部分属性时,可以返回实体对象。HQL中也可以使用构造函数。示例代码如下:

List<Users>list = session.createQuery(

“ select newUsers(u.name, u.password) from Users u”).list();// HQL中使用Users类的构造函数

HQL中使用Users类的构造函数时,Users类中必须存在一个public Users(String name, String password)的构造函数。因为Hibernate是通过调用该构造函数完成返回值从Object[]数组转化到Users实体类的。

说明:HQL中使用构造函数时,对应的实体类中也必须有同样参数特征的构造函数。

12.2.4 返回Map集合

更实用的是返回Map类型。Map中将包含查询的列名、值。遍历List获得Map,从Map中直接取值就可以了,或者遍历Map,例如:

// 把需要查询的字段放到Map集合中,把查询的Map集合再返回List集合

List map = session.createQuery(

" select newMap(u.name as name,u.addressasaddress,u.passwordaspassword) "

+ " from Users u ").list();

for (Map map1 : (List) map) {

// 遍历List集合

System.out.println("Name: " + map1.get("name"));

// 输出Map集合中的name属性

System.out.println("Password: " + map1.get("password"));

// 输出Ma集合中的password属性

System.out.println("Address: " + map1.get("address"));

// 输出Map集合address属性

}

12.3 HQL的高级应用

这一节将介绍HQL语言中的一些常用的高级应用,包括HQL中的条件查询、分页显示查询结果、级联查询以及其他的应用。

12.3.1 条件查询

HQL用where连接条件子句,语法类似于SQL。大部分SQL的规则对于HQL都适用,例如等于(=)、大于(>)、小于(<)等。HQL的where子句中使用的是实体类的属性,或者是属性的属性。查询条件可以写在HQL中,也可以通过Query设置参数,示例代码如下:

session.createQuery(" select*fromUsers"

+ " whereu.dept.name = null andu.age

.setParameter("age",23).list();

HQL的where子句中可以使用的运算符如下:

q数学运算符:+、-、*、/。

q比较操作符:=、!=、<>、>=、<=、like。

q逻辑计算法:and、or、not。

qSQL操作符:in、not in、between、is null、is not null、is empty、number of等。

q字符串连接:...||...或者concat(..., ...)。

q时间日期函数:current_date()、current_time()、current_timestamp()。

q时间日期函数:second(...)、minute(...)、hour(...)、day(...)、month(...)、year(...)。

qJPA定义的操作:substring()、trim()、lower()、upper()、length()、locate()、abs()、sqrt()、bit_length()、coalesce()、nullif()。

q数据库支持的SQL标量函数:sign()、trunc()、rtrim()、sin()。

q简单的跳转语句:case ... when ... then ... else ... end。

例如字符串连接:

Listlist = session.createQuery(

" select u.name || '所在部门为' || u.dept.name from Users u where u.dept != null ").list();

in子句查询:

List<Users>list = session.createQuery(“ fromUserswhere lower(trim(uu.name)) in (‘Jack’, ‘Macle’, ‘李四’) ”).list();

集合查询:

List<Users>list = session.createQuery(“ fromUsers uwhere size(u.events) > 5 ”).list();

设置查询条件时,应尽量使用setParameter()传递参数,而不是将参数写进HQL语句。第一次执行SQL语句时,数据库会将该SQL语句进行编译,供下次查询使用。对于参数不同的相同查询,数据库将直接调用编译后的SQL,提高查询效率。

12.3.2 HQL中的统计函数

跟SQL一样,Hibernate也提供一系列的统计函数。Hibernate会把HQL的统计函数转化为底层数据库SQL支持的函数。

SQL里的常用统计函数比如count()、sum()、min()、max()、avg()、count(distinct ...)等也都能用在HQL里,语法与SQL一样,例如:

Number num = (Number) session.createQuery(

" select count(*) fromUsers uwhereu.name != null ")

.uniqueResult();

int count = num.intValue();

查询总数时并不总是返回Long类型。返回值类型由实体类的主键类型决定的。如果实体类的主键为short类型,则返回值可能为Integer类型。

12.3.3 HQL分页显示查询结果

分页显示是web数据库程序必备的功能。不同的数据库使用不同的方式实现分页,例如MySQL使用limit,Oracle使用rownum。Hibernate隐藏了所有的细节,只需要设置当前页数即可。

分页显示一般先查询记录总数,然后查询本页显示的记录。Hibernate通过Query查询记录,Query通过setFirstResult()设置分页的第一条记录,通过setMaxResults()设置取本页的数据数,示例代码如下:

//HQL的分页查询

Query q2 = session.createQuery("from Employees");//查询所有记录

intpage=1;

//设置默认的页数为1

q2.setFirstResult((page-1)*2);//每页起始数

q2.setMaxResults(5);//每页最最多显示的页数

List emps = q2.list();//返回list集合

for (Employees emp:emps) {

System.out.println(emp.getEmployeeId());//打印输出属性

}

分页显示一般会封装成Pagination组件。Pagination负责计算每页的起始记录、总页数等。使用实例见Servlet章节。

查询总数时并不总是返回Long类型。返回值类型由实体类的主键类型决定的。如果实体类的主键为short类型,则返回值可能为Integer类型。

12.3.4 HQL跨表查询

对于一般的跨表查询,表连接就足够了。Hibernate支持用“.”作为操作符获取属性,用法类似于JSP中的EL表达式。表连接查询适用于非集合属性,对于一般的跨表查询,只需要简单的使用属性就可以了。例如Users的name属性,Dept的name属性等,示例代码如下:

List<Users>list= session.createQuery(

" select*fromUsers uwhereu.dept.name= 'Java开发部' ").list();

表面上该查询只涉及Users表,但实际上因为where子句条件用到了u.dept.name,将会查询Dept表与Users表。

12.3.5 HQL级联查询

有些查询需要使用级联查询。HQL支持SQL的级联查询,包括inner join、left join、right join、full join等。级联查询适用于集合属性,例如Users的dept集合属性。例如查询events集合属性中有“迟到”事件的cat,查询语句为:

List<Users>list= session.createQuery(

" select*fromUsers uleft joinu.events e where e.description like :description ")

.setParameter("description", "%迟到%").list();

12.3.6 使用数据库SQL

HQL可以看作是是对所有数据库SQL的封装。HQL提供的功能是底层数据库SQL支持的,HQL只是将功能“翻译”成了底层SQL的功能。有些情况下,底层数据库会提供某种功能,但是可能HQL不支持。这时可以使用底层SQL,在专业术语上叫做本地SQL(Native SQL)。

使用数据库SQL查询时不能使用Query,要使用SQLQuery对象。例如在MySQL数据库中查询所有的变量:

SQLQuery sqlQuery = session.createSQLQuery(" show variables ");

// 使用本地SQL查询所有的变量

Listlist = sqlQuery.list();

// 执行查询,把查询结果放到List集合中

for (Object[] object : list) {

// 遍历集合中所有的属性

System.out.println(object [0] + ", " + object [1] + ", ");

// 输出对象属性值

}

SQLQuery与Query一样,都也可以设置参数、分页显示等。SQLQuery返回的结果为List类型。也可以设置为实体类,使查询结果直接返回实体类对象,示例代码如下:

SQLQuery sqlQuery = session.createSQLQuery(" select * from users");

// 使用本地SQL查询

sqlQuery.addEntity(Users.class);

// 设置输出类型括号中是实体类名

List list = sqlQuery.list();

// 返回List

如果设置的实体类与查询结果不一致,会抛出异常。

12.3.7 使用@注解配置命名查询

有些查询是常用的,Hibernate中可以把常用的查询命名,需要使用查询时只需要引用名称就可以了。命名查询一般配置在实体类中。有使用@注解配置命名查询和使用XML配置命名查询。

使用@注解配置实体类时,要使用@注解配置命名查询,用到的Java注解为@NamedQuery与@NamedNativeQuery。其中,@NamedQuery用于配置命名的HQL查询,@NamedNativeQuery用于配置命名的底层数据库SQL查询,实体类中的代码如下:

import javax.persistence.*;

@NamedQuery(name = "all users", query = " select * from Users")// 命名查询,name是查询语句的名称

@NamedNativeQuery(name = "all users", query = "select * from users")

// 命名本地查询

@Entity

// Entity配置

@Table(name = "users")

// Table配置

public classUsers{

//这里省略了类中的内容

}

上述代码中,命名查询的查询语句中Users是实体类的名称,命名本地查询的查询语句中users是数据库表名。

12.3.8 使用@QueryHint扩展查询

命名查询中,允许使用@QueryHint对命名查询设置JPA扩展。JPA规范允许对JPA进行一些功能上的扩展,以加速查询性能、提供其他功能等。示例代码如下:

@NamedQuery(name = "all usersname", query = " select*fromUsers uwhereu.name = :name ", hints = { @QueryHint(name = "org.hibernate.callable", value = "true") })

使用@QueryHint时,要把@QueryHint写在hints中,hints的格式是“hints={}”,需要写的@QueryHint内容写在大括号中。org.hibernate.callable的布尔变量值表明这个查询是否是一个存储过程。value=”true”表示这个查询是存储过程。

12.3.9 同时设置多个命名查询

一个实体类不能配置多个@NamedQuery。如果有多个命名查询,需要使用@NamedQueries配置。@NamedQueries中可以配置多个@NamedQuery,示例代码如下:

@NamedQueries(value = {

@NamedQuery(name = "allusers", query = " selectufromUsersu"),

@NamedQuery(name="usersname", query=" selectufromUsersuwhereu.name = :name ",),

@NamedQuery(name="usersfor dept",query="selectufromUsers uwhereu.dept.name = :dept") })

当需要使用到命名查询的时候,直接在程序中调用,程序中这样使用命名查询,如果有参数,需要设置参数,示例代码如下:

Queryquery= session.getNamedQuery("usersname ").setParameter(“name”, “Jack”);

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

12.3.10 在XML中配置命名查询

如果实体类使用XML文件配置映射关系时,命名查询需要配置在hbm.xml实体类映射文件中。命名查询使用配置,要配置中实体类的后面,name配置查询的名称,可配置返回数据的类型。示例代码如下:

hibernate-mapping PUBLIC

"-//Hibernate/Hibernate Mapping DTD 3.0//EN"

"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">

package="com. java.vo">

selectefrom Employeeewheree. empname = :name

]]>

selectefrom Employeeewheree.dept.name = :name

]]>

12.4 本章小结

Hibernate使数据持久层以面向对象的方式编程,直接存储、操作Java对象,使用HQL查询数据。Hibernate也实现了跨数据库,同一套程序可以运行在多种数据库上,如果更换数据库,只需要更换数据库驱动,并更改Hibernate的Dialect即可。Hibernate会将HQL翻译成不同数据库的SQL。

版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。

原文链接:https://hbdhgg.com/5/49691.html

发表评论:

本站为非赢利网站,部分文章来源或改编自互联网及其他公众平台,主要目的在于分享信息,版权归原作者所有,内容仅供读者参考,如有侵权请联系我们删除!

Copyright © 2022 匯編語言學習筆記 Inc. 保留所有权利。

底部版权信息