一、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();
}
}