Hibernate 框架(二)—— SQL 查询、HQL 查询

一、SQL 查询

1、SQL 查询概述

(1)SQLQuery 是 Hibernate 提供的SQL查询对象(5.2以前)
(2)NativeQuery 是 Hibernate 提供的SQL查询对象,通过 sql 语句执行查询,可查询一个集合或者一个对象。(5.2以后)

2、SQL 查询应用

(1)创建 NativeQuery 对象

第一种
NativeQuery query=session.createNativeQuery(sql,Class c);

第一个参数 sql:表示本次查询执行的sql语句。
第二个参数 Class:表示本次执行查询结果封装的实体类对象。

第二种
NativeQuery query=session.createNativeQuery(sql);
query.addEntity(Class c);

参数 sql:表示本次执行查询的 sql 语句。
addEntity :指定本次查询结果封装的实体类对象。

Demo:

Session session = sessionFactory.openSession();
//使用第一种
NativeQuery<Products> query = session.createNativeQuery("select * from products", Products.class);
//使用第二种
NativeQuery<Products> query1 = session.createNativeQuery("select * from products");
query.addEntity(Products.class);
List<Products> list = query.list();
for(Products p: list) {
	System.out.println(p);
}
session.close();

(2)SQL 语句中的动态参数处理
SQL语句可以采用?或者:参数名称的方式来为动态参数占位,例如:

String sql = "select * from student where name like ? and age > ?";
  • 使用?作为占位符以后可以使用query.setParameter(序号,值);的方式来为占位符赋值,占位符从1开始。(推荐)
  • 使用?作为占位符以后可以使用query.setXxx(序号,值);的方式来为占位符赋值,占位符从1开始。
  • 使用:参数名称作为占位符以后可以使用query.setXxx(“参数名称”,值);的方式来为占位符赋值
  • 使用:参数名称作为占位符以后还可以使用query.setProperties(Map map);的方式来为所有命名参数同时赋值,需要保证键值对和命名参数名称一致。(推荐)

Demo

Session session = sessionFactory.openSession();
NativeQuery<Products> query = session.createNativeQuery("select * from products where p_price < ? and p_count < ?", Products.class);
query.setParameter(1, 2000);
query.setParameter(2, 1000);
List<Products> list = query.list();
for(Products p: list) {
	System.out.println(p);
}

(3)分页查询
如果要分页查询,需要在执行查询前需要先执行两个方法:

query.setFirstResult(); 设置查询起始位置
query.setMaxResult(); 设置查询总行数

Demo

Session session = sessionFactory.openSession();
//分页查询
NativeQuery<Products> query = session.createNativeQuery("select * from products", Products.class);
//设置起始位置从0开始
query.setFirstResult(0);
//设置每页显示条数
query.setMaxResults(10);
List<Products> list = query.list();
for(Products p: list) {
	System.out.println(p);
}

查询数据并将查询出的结果封装为集合:query.getResultList();
查询数据并将查询出的数据封装为一个实体类对象:query.uniqueResult();

Demo:多表联合查询

Session session = sessionFactory.openSession();
NativeQuery<Object[]> query = session.createNativeQuery("select p.*,l.lt_pid from products as p inner join ltype as l on p.p_typeid = l.lt_id;");
List<Object[]> list = query.list();
for(Object[] row: list) {
	for(Object p: row) {
		System.out.print(p);
	}
	System.out.println("");
}

在这里插入图片描述

二、HQL 查询

1、HQL 查询概述

(1)HQL 全称 Hibernate Query Language,是 Hibernate 设计的面向对象的查询语言,使用HQL查询数据时与数据库的种类和版本无关,Hibernate 最终会根据方言将 HQL 转为SQL去数据库中执行查询。同时HQL语法和SQL非常类似,非常易于学习和使用,是 Hibernate 推荐的查询方式之一。
(2)HQL 查询语句中只能出现类名和属性名(类名区分大小写),不能出现表名和字段名,不能出现*号,HQL 中查询语句中出现的类名必须是进行了对象关系映射的类,没有映射的类不能出现在HQL语句中。
(3)HQL 查询语句中如果要使用别名必须使用as关键字,不能省略。

2、HQL 语法结构

(1)语法结构

select 
属性列表、聚合函数、投影查询 
from  类名  
inner join 类
where 条件  
group  by 属性名称 having 条件 
order by 属性名称 desc/asc  

(2)查询语句示例
① 查询所有数据
查询学生表的所有学生对象:

from Student (不能写成select * from Student)

② 投影查询(查询表的一部分字段或者聚合函数)
查询学生表中的学生姓名属性:

select name from Student;
当查询的是单个属性时,查询的集合中保存的就是该属性值

查询学生表中的学生姓名和年龄:

selectname,age from Student ;
当查询的是多个属性时,查询的集合中保存的是Object 数组,一个数组表示一行数据

查询学生表中的学生姓名和年龄并封装为学生类对象:

select new Student(name,age)from Student
学生类中需要提供对应的带参构造函数

(3)where子句:别名需要加as
where子句可以对数据进行筛选,查询出满足条件的数据,具体的条件判断方式和SQL类似。

><>=<==<>、is null、 is not null、 in、 between and、like

group by having子句:分组子句用法和SQL一致
order by子句:排序子句用法和SQL一致

3、HQL 使用过程

(1)创建Query对象:

Query query=session.creatQuery(hql);
  • 使用:参数名称作为占位符以后可以使用query.setParameter(“参数名称”,值)或者query.setXxx(“参数名称”,值);的方式来为占位符赋值
  • 使用:参数名称作为占位符以后还可以使用query.setProperties(Map map)以及query.setProperties(实体类对象)的方式来为所有命名参数同时赋值,使用键值对需要保证键和命名参数名称一致,使用实体类需要保证命名参数名称与实体类属性一致。

(2)分页查询
如果要分页查询在执行查询前需要先执行两个方法:

query.setFirstResult(); 设置起始查询位置
query.setMaxResult(); 设置每页显示总数

查询数据并将查询出的结果封装为集合:

query.getList();

查询数据并将查询出的数据封装为一个实体类对象:

query.uniqueResult();

Demo:HQL 查询示例

public class HQLQuery {
	public static void main(String[] args) {
		Session session = SessionUtil.openConnection();
		
		//1、查询所有数据
		Query<Products> query = session.createQuery("from Products", Products.class);
		List<Products> list = query.list();
		for(Products p: list) {
			System.out.println(p);
		}
		//2、投影查询:查询单个字段
		Query<String> query1 = session.createQuery("select p_name from Products", String.class);
		List<String> list1 = query1.list();
		for(String p: list1) {
			System.out.println(p);
		}
		//3、投影查询:查询单个对象封装成类对象
		Query<Products> query2 = session.createQuery("select new Products(p_name) from Products", Products.class);
		List<Products> list2 = query2.list();
		for(Products p: list2) {
			System.out.println(p);
		}
		//4、投影查询:查询聚合函数单个结果
		Query<Long> query3 = session.createQuery("select count(p_id) from Products", Long.class);
		Long list3 = query3.uniqueResult();
		System.out.println(list3);
		
		//5、投影查询:查询多个字段,封装成Object数组
		Query<Object[]> query4 = session.createQuery("select p_name, p_price from Products", Object[].class);
		List<Object[]> list4 = query4.list();
		for(Object[] p: list4) {
			System.out.println(p[0] + "," + p[1]);
		}
		//6、查询多个结果封装成键值对(必须要给属性取别名)
		Query query5=session.createQuery("select p_name as name,p_price as price from Products");
		query5.unwrap(QueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		List<Map> list5 = query5.list();
		for(Map row:list5) {
			for(Object key:row.keySet()) {
				System.out.print(key+":"+row.get(key));
			}
			System.out.println("");
		}
		//7、将投影查询的多个结果封装为实体类对象
		Query<Products> query6 = session.createQuery("select new Products(p_name, p_price) from Products",Products.class);
		List<Products> list6 = query6.list();
		for(Products p: list6) {
			System.out.println(p);
		}
		//8、条件查询:查询价格在200块以下,库存在1000以下的商品
		Query<Products> query7 = session.createQuery("from Products where p_price < :p_price and p_count < :p_count", Products.class);
		//第一种给命名参数赋值的方式
		query7.setParameter("p_price", 2000.0);
		query7.setParameter("p_count", 1000);
		//第二种给命名参数赋值的方式
//		Map<String,Object> map = new HashMap<String, Object>();
//		map.put("p_price", 2000.0);
//		map.put("p_count", 1000);
//		query7.setProperties(map);
		List<Products> list7 = query7.list();
		for(Products p: list7) {
			System.out.println(p);
		}
		//9、将查询结果排序
		Query<Products> query8 = session.createQuery("from Products where p_price < :price and p_count < :count order by p_id desc", Products.class);
		query8.setParameter("price", 2000.0);
		query8.setParameter("count", 1000);
		List<Products> list8 = query8.list();
		for(Products p: list8) {
			System.out.println(p);
		}
		//10、分页查询
		Query<Products> query9 = session.createQuery("from Products where p_price < :price and p_count > :count order by p_id desc", Products.class);
		query9.setParameter("price", 2000.0);
		query9.setParameter("count", 1000);
		query9.setFirstResult(0);
		query9.setMaxResults(5);
		List<Products> list9 = query9.list();
		for(Products p:list9) {
			System.out.println(p);
		}
		//11、多表联合查询
		Query query10=session.createQuery("select p.p_id as id, p.p_name as name, p.p_price as price, p.p_count as count, t.lt_name as tname from Products as p inner join LType as t on p.p_typeid = t.lt_id");
		query10.unwrap(QueryImpl.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);
		List list10 = query10.list();
		System.out.println(JSONArray.fromObject(list10).toString());
		
		session.close();
	}
}
发布了75 篇原创文章 · 获赞 10 · 访问量 2904

猜你喜欢

转载自blog.csdn.net/baidu_27414099/article/details/104440151