Hibernate(十二):HQL查询(一)
- 概述
Hibernate提供了以下几种检索对象的方式
1)导航对象图检索方式:根据已经加载的对象导航到其他对象;
2)OID检索方式:按照对象的OID来检索对象;
3)HQL检索方式:使用面向对象的HQL查询语言;
4)QBC检索方式:使用QBC(Query By Criteria)API来检索对象。这种API封装了基于字符串形式的查询语句,提供了更加面向对象的查询接口。
5)本地SQL检索的方式:使用本地数据的SQL查询语句。
HQL(Hibernate Query Language)面向对象的查询语言,它和SQL查询语言有些相似。在Hibernate提供的各种检索方式中,HQL是使用最广泛的一种检索方式。它有如下功能:
1)在查询语句中设定各种查询条件
2)支持投影查询,即仅检索出对象的部分属性
3)支持分页查询
4)支持连接查询
5)支持分组查询,允许使用“HAVING”和“GROUP BY”关键字
6)提供内置聚集函数,如:SUM()、MIN()、Max()
7)支持子查询
8)支持动态绑定参数
9)能够调用用户定义的SQL函数或标准的SQL函数。
HQL检索方式包括以下步骤
1)通过Session的createQuery()方法创建一个Query对象,它包括一个HQL查询语句。HQL查询语句中可以包括命名参数
2)动态绑定参数
3)调用Query相关方法执行查询语句
Query接口支持方法链编程风格
它的setXxx()方法返回自身实例,而不是void类型。
HQL vs SQL
1)HQL查询语句是面向对象的,Hibernate负责解析HQL查询语句,然后根据对象-关系映射文件中的映射信息,把HQL查询语句翻译成相应的SQL语句。HQL查询语句中的主题是域模型中的类与类的属性
2)SQL查询语句是与关系数据库绑定在一起的。SQL查询语句中的主体是数据库表及表的字段。
绑定参数
1)Hibernate的参数绑定机制依赖于JDBC API中的PreparedStatement的预定义SQL语句功能。
2)HQL的参数绑定两种形式:
按参数名称绑定:在HQL查询语句定义命名参数,命名参数以“.”开头
按参数位置绑定:在HQL查询语句中用“?”来定定义参数位置
3)相关参数
setEntity():把参数与一个持久类绑定
setParamenter():绑定任意类型的参数,该方式的第三个参数显式指定Hibernate映射类性。
HQL采用ORDER BY关键字对查询结果排序
在映射文件中定义命名查询语句
1)Hibernate允许在映射文件中定义字符串形式的查询语句
2)<query>元素用于定义一个HQL查询语句,它和<class>元素并列
<query name="findNewsByTitle">
<![CDATA[
FROM News n WHERE n.title LIKE :title
]]>
</query>
3)在程序中通过Session的getNameQuery()方法获取查询语句对应的Query对象。
- 新建项目
新建工程Hibernate09,在根目录导入hibernate(required)开发包及mysql驱动包,在src下新建hibernate.cfg.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE hibernate-configuration PUBLIC
"-//Hibernate/Hibernate Configuration DTD 3.0//EN"
"http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration>
<session-factory>
<property name="hibernate.connection.username">root</property>
<property name="hibernate.connection.password">123456</property>
<property name="hibernate.connection.driver_class">com.mysql.jdbc.Driver</property>
<property name="hibernate.connection.url">jdbc:mysql://localhost/hibernate_09</property> <!-- <property name="hibernate.dialect">org.hibernate.dialect.MySQLDialect</property>
<property name="hibernate.dialect">org.hibernate.dialect.MySQLInnoDBDialect</property> -->
<property name="hibernate.dialect">org.hibernate.dialect.MySQL5InnoDBDialect</property> <property name="hibernate.show_sql">true</property> <property name="hibernate.format_sql">true</property> <property name="hibernate.hbm2ddl.auto">update</property> <property name="hibernate.current_session_context_class">thread</property> <property name="hibernate.c3p0.max_size">500</property>
<property name="hibernate.c3p0.min_size">20</property>
<property name="hibernate.c3p0.max_statements">10</property>
<property name="hibernate.c3p0.timeout">2000</property>
<property name="hibernate.c3p0.idle_test_period">2000</property>
<property name="hibernate.c3p0.acquire_increment">10</property> <mapping resource="com/dx/hibernate09/hql01/Department.hbm.xml" />
<mapping resource="com/dx/hibernate09/hql01/Employee.hbm.xml" /> </session-factory>
</hibernate-configuration>
在src下新建包com.dx.hibernate09.hql01,在该包下新建:
Department.java
package com.dx.hibernate09.hql01; import java.util.HashSet;
import java.util.Set; public class Department {
private Integer id;
private String name;
private Set<Employee> employees = new HashSet<>(); public Department() { } public Department(String name) {
super();
this.name = name;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public Set<Employee> getEmployees() {
return employees;
} public void setEmployees(Set<Employee> employees) {
this.employees = employees;
} }
Department.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-6-9 23:13:49 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.dx.hibernate09.hql01.Department" table="DX_DEPARTMENT">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property> <set name="employees" table="DX_EMPLOYEE" inverse="true" lazy="true">
<key>
<column name="DEPARTMENT_ID" />
</key>
<one-to-many class="com.dx.hibernate09.hql01.Employee" />
</set>
</class>
</hibernate-mapping>
Employee.java
package com.dx.hibernate09.hql01; public class Employee {
private Integer id;
private String name;
private float salary;
private String email;
private Department department; public Employee() { } public Employee(String name, float salary, String email) {
super();
this.name = name;
this.salary = salary;
this.email = email;
} public Integer getId() {
return id;
} public void setId(Integer id) {
this.id = id;
} public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public float getSalary() {
return salary;
} public void setSalary(float salary) {
this.salary = salary;
} public String getEmail() {
return email;
} public Department getDepartment() {
return department;
} public void setDepartment(Department department) {
this.department = department;
} public void setEmail(String email) {
this.email = email;
} }
Employee.hbm.xml
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!-- Generated 2017-6-9 23:13:49 by Hibernate Tools 3.5.0.Final -->
<hibernate-mapping>
<class name="com.dx.hibernate09.hql01.Employee" table="DX_EMPLOYEE">
<id name="id" type="java.lang.Integer">
<column name="ID" />
<generator class="native" />
</id>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="salary" type="float">
<column name="SALARY" />
</property>
<property name="email" type="java.lang.String">
<column name="EMAIL" />
</property>
<many-to-one name="department" class="com.dx.hibernate09.hql01.Department">
<column name="DEPARTMENT_ID" />
</many-to-one>
</class>
</hibernate-mapping>
注意:
1)上边新建的类Employee与Department是多对一关系;
2)hbm.xml配置的是双向一对多映射关系。
新建测试类TestMain.java
package com.dx.hibernate09.hql01; import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Test; public class TestMain {
private SessionFactory sessionFactory = null;
private Session session = null;
private Transaction transaction = null; @Before
public void init() {
StandardServiceRegistry standardRegistry = new StandardServiceRegistryBuilder().configure().build();
Metadata metadata = new MetadataSources(standardRegistry).getMetadataBuilder().applyImplicitNamingStrategy(ImplicitNamingStrategyComponentPathImpl.INSTANCE).build(); sessionFactory = metadata.getSessionFactoryBuilder().build();
session = sessionFactory.getCurrentSession();
transaction = session.beginTransaction();
} @Test
public void test() { } @After
public void destory() {
transaction.commit();
session.close();
sessionFactory.close();
}
}
- 初始化数据库
执行空的测试函数test(),生成数据表,后台执行的sql:
Hibernate: create table DX_DEPARTMENT (
ID integer not null auto_increment,
NAME varchar(255),
primary key (ID)
) engine=InnoDB
Hibernate: create table DX_EMPLOYEE (
ID integer not null auto_increment,
NAME varchar(255),
SALARY float,
EMAIL varchar(255),
DEPARTMENT_ID integer,
primary key (ID)
) engine=InnoDB
Hibernate: alter table DX_EMPLOYEE
add constraint FKqv35rmky1hq7k2ovpiohhpmvh
foreign key (DEPARTMENT_ID)
references DX_DEPARTMENT (ID)
查询数据
添加testInsertData()测试函数,给数据表填充数据:
@Test
public void testInsertData() {
Department department1 = new Department("开发部门");
Department department2 = new Department("测试部门");
Department department3 = new Department("业务部门");
Department department4 = new Department("财务部门");
Department department5 = new Department("行政部门"); session.save(department1);
session.save(department2);
session.save(department3);
session.save(department4);
session.save(department5); department1.setId(1);
department2.setId(2);
department3.setId(3);
department4.setId(4);
department5.setId(5); for (int i = 0; i < 80; i++) {
Employee employee = new Employee("tommy" + i, 1000 * i, "tommy" + i + "@dx.com");
if (i % 5 == 0) {
employee.setDepartment(department1);
} else if (i % 5 == 1) {
employee.setDepartment(department2);
} else if (i % 5 == 2) {
employee.setDepartment(department3);
} else if (i % 5 == 3) {
employee.setDepartment(department4);
} else if (i % 5 == 4) {
employee.setDepartment(department5);
}
session.save(employee);
} }
执行结果查询
- HQL带参数查询:
1)基于位置的参数
/**
* 基于位置的参数
*/
@Test
public void testHQLPositionParameter() {
String hql = "From Employee e Where e.salary>? and e.name like ?"; Query query = session.createQuery(hql).setFloat(0, 6000).setString(1, "%1%"); List<Employee> employees = query.list();
System.out.println(employees.size());
System.out.println(employees);
}
2)基于命名的参数
/**
* 基于命名的参数
*/
@Test
public void testHQLNameParameter() {
String hql = "From Employee e Where e.salary>:salary and e.name like :name"; Query query = session.createQuery(hql).setFloat("salary", 6000).setString("name", "%1%"); List<Employee> employees = query.list();
System.out.println(employees.size());
System.out.println(employees);
}
- HQL Order By排序查询:
/**
* Order By
*/
@Test
public void testHQLOrderBy() {
String hql = "From Employee e Where e.salary>? and e.name like ? Order By e.salary Desc"; Query query = session.createQuery(hql).setFloat(0, 6000).setString(1, "%1%"); List<Employee> employees = query.list();
System.out.println(employees.size());
System.out.println(employees);
}
- HQL 设置实体参数查询:
/**
* 基于实体的查询
*/
@Test
public void testHQLEntity() {
String hql = "From Employee e Where e.salary>? and e.name like ? and e.department=? Order By e.salary Desc"; Department depart = new Department();
depart.setId(1); @SuppressWarnings("deprecation")
Query query = session.createQuery(hql).setFloat(0, 6000).setString(1, "%1%").setEntity(2, depart); List<Employee> employees = query.list();
System.out.println(employees.size());
System.out.println(employees);
}
Hibernate(十二):HQL查询(一)的更多相关文章
- Hibernate(十二)Criteria查询
一.简述 Criteria是一种比hql更面向对象的查询方式.Criteria 可使用 Criterion 和 Projection 设置查询条件.可以设置 FetchMode(联合查询抓取的模式 ) ...
- Hibernate中关于HQL查询返回List<Object>数据的结果集问题
---恢复内容开始--- 开发中遇到的一个小问题,使用Hibernate中的HQL查询时,使用query.list()查询出来的是一个List<Object>结果集 原来代码: publi ...
- (十二)数据库查询处理之Query Execution(1)
(十二)数据库查询处理之Query Execution(1) 1. 写在前面 这一大部分就是为了Lab3做准备的 每一个query plan都要实现一个next函数和一个init函数 对于next函数 ...
- 【Hibernate步步为营】--hql查询小介
HQL 是指Hibernate Query Language,它是Hibernate的查询语言,拥有一套自己的查询机制,它的查询语句和SQL非常类似.在使用的时候可以非常快上手.HQL提供了基本上SQ ...
- hibernate学习(7)——HQL查询
1.HQL查询定义 Hibernate查询分类: 1. get/load 根据OID检索 2. 对象视图检索 c.getOrders 3. Sql语句 createSqlQuery 4. Hql语句 ...
- Hibernate框架之HQL查询与Criteria 查询的区别
Hibernate框架提供了HQL查询和Criteria 查询.下面对这两种查询分别做个例子.也好对这两种查询方法有个大概的了解.就用房屋信息表做例子,查询所有房屋信息. HQL语句查询所有房屋信息: ...
- Hibernate用到HQL查询时的错误
Exception in thread "main" org.hibernate.hql.internal.ast.QuerySyntaxException: student is ...
- Hibernate中的HQL查询与缓存机制
HQL:完全面向对象查询 SQL的执行顺序: 1.From 2.Where 过滤基础数据 where与having的区别:1.顺序不同 2.where过滤基础数据 3. 过滤聚合函数 3.Group ...
- Hibernate学习之hql查询语句
* 页面上数据的字段和数据库中字段差不多,这个时候,采用迫切连接 结构比较好,如果页面上的字段很少,要按照需求加载数据,采用带构造函数的select查询 实例讲解:转自:http://www.cn ...
- Java_Web三大框架之Hibernate+jsp+selvect+HQL查询数据
俗话说:"好记性不如烂笔头".本人学习Hibernate也有一个星期了,对Hibernate也有一个初步的了解.下面对Hibernate显示数据做个笔记,使用租房系统的Hibern ...
随机推荐
- C语言第四次博客作业--嵌套循环
一.PTA实验作业 题目1:编程打印空心字符菱形 1. 本题PTA提交列表 2. 设计思路(流程图) 3.本题调试过程碰到问题及解决办法 思考过程:将问题拆解为菱形问题和字母变化问题两部分 1> ...
- 部署在eclipse上的Tomcat上的publish和clean的区别
publish:就是把自己的web应用发布到tomcat服务器上没这样才能通过浏览器查看浏览 clean: 就是先清除掉原先编译到tomcat上的程序(多个.class文件),之后再发布. 如:我建了 ...
- 笔记:Maven 项目目录结构
Maven提倡使用一个共同的标准目录结构,使开发人员能在熟悉了一个Maven工程后,对其他的Maven工程也能清晰了解.这样做也省去了很多设置的麻烦,以下的文档介绍是Maven希望的目录结构,并且也是 ...
- 总结的Javascript插件
1.很好用的弹窗 https://limonte.github.io/sweetalert2/ https://github.com/limonte/sweetalert2 import './unt ...
- 如何通过TortoiseGit(小乌龟)把本地项目上传到github上
1.第一步: 安装git for windows(链接:https://gitforwindows.org/)一路next就好了, 如果遇到什么问题可以参考我另外一篇文章~^ - ^ 2.第二步:安装 ...
- Tomcat下wtpwebapps文件夹 和 webapps文件夹区别
这两者其实没有区别.都是项目部署路径 webapps : tomcat默认部署路径 wtpwebapps : eclipse默认部署路径 只不过Tomcat6将wtpwebapps作为了默认路径,如果 ...
- [bzoj1497][NOI2006]最大获利_网络流_最小割
最大获利 bzoj-1497 题目大意:可以建立一个点,花费一定的代价:将已经建立的两个点之间连边,得到一定收益.有些节点之间是不允许连边的. 注释:1<=点数<=5,000,1<= ...
- MySQL的入门
SHOW VARIABLES LIKE 'storage_engine%' #查看引擎 ALTER TABLE `studten` RENAME `student1` #修改表名 ALTER TABL ...
- 关于redis数据库的简单思考
redis数据库中有以下几种数据类型: 字符串,哈希,列表,集合,有序集合 它们应用的场景如下: 字符串用法单一,用于存储一个key的值,用于一一对应的场合 列表作为数组来使用 对于哈希,特别适用于存 ...
- rtmp发布录制视频
本文描述了rtmp发布本地视频的流程 一.简要介绍 RTMP协议规定,播放一个流媒体有两个前提步骤:第一步,建立一个网络连接(NetConnection):第二步,建立一个网络流(NetStream) ...