Hibernate 与 HQL
HQL:Hibernate Query Language:hibernate查询语言;
Sql:语句针对的是数据库中的表的查询,而Hql是对类中的对象进行查询;
HQL的介绍最好是在代码中去解释:
Hql查询案例:查询所有的 list( ) 方法
@Test
public void test01() {
//由于session是使用的getCurrentSession()获取的到的,必须在事务的环境下执行
//获取session
Session session = HbnUtil.getSession();//HbnUtil是一个工具类
//开启事务
session.getTransaction().begin();
//创建hql
String hql="from Student";
//获取query查询对象
Query query = session.createQuery(hql,Student.class);
//执行全部查询操作
List <Student>list = query.list();
//执行一项效果
for (Student student : list) {
System.out.println(student);
}
//提交事务
session.getTransaction().commit();
}
//原生态sql实现
@Test
public void test02() {
//由于session是使用的getCurrentSession()获取的到的,必须在事务的环境下执行
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
//SQL是面向表的
List<Student> list = session.createSQLQuery("select * from t_student").addEntity(Student.class).list();
//执行一项效果
for (Student student : list) {
System.out.println(student);
}
//提交事务
session.getTransaction().commit();
}
Hql查询,查询一条记录uniqueResult()方法
@Test
public void test03() {
//由于session是使用的getCurrentSession()获取的到的,必须在事务的环境下执行
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
Student stu = session
.createQuery("from Student as stu where stu.sid=:mysid",Student.class)
.setParameter(“mysid”, 3)//绑定参数
.uniqueResult();//执行唯一查询
//提交事务
session.getTransaction().commit();
}
//原生sql
@Test
public void test0032() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
Student stu = (Student) session.createSQLQuery("select * from t_student where sid=?")
.setParameter(1, 3)//第一个?,赋值
.addEntity(Student.class)
.uniqueResult();
//展示一下情况
System.out.println(stu);
//提交事务
session.getTransaction().commit();
}
Hql查询,条件查询
- 使用别名占位,setXxx ()绑定参数:setXxx (String name, Object value)。别名的命名。规则为,冒号后跟别名,别名可是任意名称。
@Test
public void test004() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="from Student as stu where stu.score>:score and stu.age>=:age";
List<Student> list = session.createQuery(hql,Student.class)
.setParameter("score", 95.0)
.setParameter("age", 22)
.list();
//遍历一下
for (Student stu : list) {
//展示一下情况
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}
//原生sql
@Test
public void test0042() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="select * from t_student where score>? and age>=?";
List<Student> list = session.createSQLQuery(hql)
.addEntity(Student.class)
.setParameter(1, 95.0)
.setParameter(2, 22)
.list();
//遍历一下
for (Student stu : list) {
//展示一下情况
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}
Hql查询,之排序查询 order by asc,升序,desc降序’;
@Test
public void test005() {//hql查询
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="from Student order by score asc";
List<Student> list = session.createQuery(hql).list();
//遍历一下
for (Student stu : list) {
//展示一下情况
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}
Hql查询,之分页查询
- Query 接口中具有 setFirstResult()方法,用于设置从总查询结果集的第几条记录作为本查询结果子集的开始,即本页的开始。总查询结果集从 0 开始记数。而 setMaxResults()方法用于设置该页所包含的记录数。
- 分页查询的 SQL 语句:select * from … where …limit startIndex, pageSize;
- startIndex 为开始索引,设置从总查询结果集的第几条记录作为本查询结果子集的开始,即本页的开始。总查询结果集从 0 开始记数。
- pageSize 为该页所包含的记录数。
@Test
public void test006() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="from Student";
List<Student> list = session.createQuery(hql)
.setFirstResult(1)
.setMaxResults(2)
.list();
//遍历一下
for (Student stu : list) {
//展示一下情况
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}
//原生态 查询
@Test
public void test0062() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="select * from t_student limit ?,?";
List<Student> list = session.createSQLQuery(hql)
.setParameter(1, 0)
.setParameter(2, 2)
.addEntity(Student.class)
.list();
//遍历一下
for (Student stu : list) {
//展示一下情况
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
模糊查询 like
- 通过like后面使用占位符,:sname,冒号固定,后面的字符随意,但是兼顾见名知意;
@Test
public void test007() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="from Student as stu where stu.sname like:sname";
List<Student> list = session.createQuery(hql)
.setParameter("sname", "%哈%")
.list();
//遍历一下
for (Student stu : list) {
//展示一下情况
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}
//原生态的模糊查询
@SuppressWarnings("unchecked")
@Test
public void test0072() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="select * from t_student where sname like ?";
List<Student> list = session.createSQLQuery(hql)
.addEntity(Student.class)
.setParameter(1, "%哈%")
.list();
//遍历一下
for (Student stu : list) {
//展示一下情况
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}
BQL查询,Critertie 查询,不需要sql语句,只需要记住Restrictions添加条件,单词”Restrictions”约束,管制的意思;
@Test
public void test008() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
List<Student> list = session.createCriteria(Student.class)
.add(Restrictions.like("sname", "%哈%"))
.list();
//遍历一下
for (Student stu : list) {
//展示一下情况
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}
聚合函数查询,注意区分 count(*)与 count(name)的不同。count(*)与 count(id)等价,均表示未空记录数。而 count(name)则表示字段 name 的非空记录数。
@Test
public void test009() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="select count(sid) from Student";
Object x = session.createQuery(hql).uniqueResult();
//遍历一下
System.out.println(x);
System.out.println("count(sid) vs count(*)");
String hql1="select count(*) from Student";
Object y = session.createQuery(hql1).uniqueResult();
System.out.println(y);
//提交事务
session.getTransaction().commit();
}
通过QBC查询实现聚合函数查询,投影查询
Projection,中文意思:投影。Projections 中包含很多聚合函数的静态方法。
//投影查询
@Test
public void test0010() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
Object y = session.createCriteria(Student.class)
.setProjection(Projections.count("sid"))
.uniqueResult();
System.out.println(y);
//提交事务
session.getTransaction().commit();
}
投影查询
(1 )SQL 查询
要求查询的字段的别名要与实体类的属性名相同,这样才能将结果转换为相应类的对象。
(2)HQL 查询
该查询要求实体类中具有相同投影作为参数的带参构造器。所以,首先要在 Student 类中添加相应的带参构造器
public Student(String sname, int age) {
this.sname = sname;
this.age = age;
}
@Test
public void test0012() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="select new Student(sname,age) from Student";
List<Student> list = session.createQuery(hql).list();
//遍历集合
for (Student stu : list) {
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}
Hql:分组查询,select * from student group by age having ?
(1 )SQL 查询
having,对分组结果进行筛选。下面代码实现的功能是,查询出所有年龄段,及人数多于 1 人的年龄段。
@Test
public void test0013() {//查询出来的是年龄段
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="select age from Student group by age";
List<Integer> list = session.createQuery(hql)
.list();
//遍历
for (Integer i : list) {
System.out.println(i);
}
String hql2="select age from Student group by age having count(age)>:age";
List list2 = session.createQuery(hql2)
.setParameter("age", 1L)
.list();
//遍历
for (Object o : list2) {
System.out.println(o);
}
//提交事务
session.getTransaction().commit();
}
(2)QBC,hibernate不支持having操作:
@Test
public void test0014() {//查询出来的是年龄段
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
List list = session.createCriteria(Student.class)
.setProjection(Projections.groupProperty("age"))
.list();
for (Object object : list) {
System.out.println(object);
}
//提交事务
session.getTransaction().commit();
}
Query中list() vs iterate区别它们的区别:
使用 Query 接口的 list()与 iterate()进行查询,查看其控制台的 SQL 语句的输出情况,可以看到它们的区别主要有两点:
A、使用 list(),会一次性将所有符合条件的记录查询出来;而使用 iterate(),则首先会查询出所有符合条件的记录的 id,然后再根据这些 id 逐个查询出记录的具体内容。
B、使用 list(),不会使用缓存机制,即每执行一次查询代码,控制台均会执行一次 SQL查询语句;而使用 iterate(),则会使用缓存机制,只有第一次会执行 SQL 查询,再往后的查询会直接从缓存中读取。
public void test0015() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="from Student";
//执行查询
//第一次查询
System.out.println("第一次查询");
List<Student> list = session.createQuery(hql).list();
for (Student stu : list) {
System.out.println(stu);
}
//第二次查询
System.out.println("第二次查询");
List<Student> list2 = session.createQuery(hql).list();
for (Student stu : list2) {
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}
@Test
@SuppressWarnings({ "unchecked", "deprecation" })
public void test0016() {
//获取session
Session session = HbnUtil.getSession();
//开启事务
session.getTransaction().begin();
String hql="from Student";
//执行查询
//第一次查询
System.out.println("第一次查询");
Iterator<Student> it = session.createQuery(hql).iterate();
while(it.hasNext()) {
Student stu = it.next();
System.out.println(stu);
}
//第二次查询
System.out.println("第二次查询");
Iterator<Student> it1 = session.createQuery(hql).iterate();
while(it1.hasNext()) {
Student stu = it1.next();
System.out.println(stu);
}
//提交事务
session.getTransaction().commit();
}