前两次课,主要讲了使用hibernate建模,配置文件的编写。本节课,主要讲解,当hibernate架构已经搭建完成之后。如何使用框架。
该框架的使用,主要就是对数据的读写。简化之前写sql语句的问题。
使用最多的查询种类
- 简单查询
- 带条件查询
- 分页查询
- sql语句查询
简单查询
框架中的查询,面向的是实体对象,而不是数据库表。所以只需要指定要查询的字段即可:
Criteria criteria=session.createCriteria(类名.class);
criteria.add(Expression.like("要查询的属性名","*"));
List lst=criteria.list();
或使用hql语句查询:
Query query=session.createQuery("from 类名");
List lst=query.list();
当然以上两种查询,也可以添加参数。这样就可以精确查询了。
带参数的查询
这一类的查询方法,与上面不同的就是,需要添加参数。有两种做法,一是拼接sql语句,然后执行。二是使用占位符。
第一种:
List students=session.createQuery("select s.id,s.name from Student s where s.name like '%0%' ").list();
第二种:
Query query=session.createQuery("select s.id,s.name from Student s where s.name like ? ");
query.setParameter(0, "%0%");
List students=query.list();
为了避免sql注入的问题,我们常使用第二种方式。
分页查询
hibernate的分页查询,可以说是非常方便的。如果是自己写sql语句,需要计算起始位置、查询条数。
List students= session.createQuery("from Student")
.setFirstResult(1) //从哪里开始
.setMaxResults(2) //每页显示的记录数
.list();
hql分页查询,只需要指出,从哪里开始,每页查询的记录数。就可以查询到需要的数据。
sql语句查询
hibernate没有关闭使用sql语句查询。对于一些复杂的查询方法。我们仍然可以写sql语句进行查询。
Query query=session.createQuery("sql语句 ");
查询中遇到的问题
N+1问题:
先看一个实例,有这样一组数据。班级和学生。 班级是一,学生是多。
这样的话,班级中的实体,大致应该如下:
public class Classes {
private int id;
private String name;
private Set students; //存放学生的集合
}
现在要做的操作是,查询某个班下的所有学生。按照正常的查询方式,查询大致如下:
//使用hql的迭代器
Iterator iter= session.createQuery("from Student").iterate();
//打印 学生列表
while(iter.hasNext()){
Student student=(Student)iter.next();
System.out.println("student.name="+student.getName());
}
执行以上的语句。可以查询到正确的结果。但是当你打印输出之后,你会发现。他发出的sql语句很多。如下:
首先,发出一条语句,查询班级。然后在打印学生列表的时候,分别发出一条根据学生id查询学生的语句。共发出N+1条记录。所以说,这个问题,会影响效率。
解决方法:
//不实用hql迭代器,使用list()查询
List students= session.createQuery("from Student").list();
for(Iterator iter=students.iterator();iter.hasNext();){
Student student=(Student)iter.next();
System.out.println("student.name="+student.getName());
}
唯一差别的地方就是,第一种方式使用的Iterate()查询,第二种方式是使用list()查询。
list()和iterate()有哪些区别呢?
list:默认情况下list每次都会发出sql语句,list会讲数据放到缓存中,而不利用缓存
Iterate:默认情况下Iterate利用缓存,如果缓存中不存在会先N+1问题
hibernate是一个ORM框架。主要负责 实体对象与数据库的关系。为了提高查询效率,hibernate中支持延迟加载策略。即用的时候在发出sql查询。这样的话,才会出现N+1问题。
当然也可以取消延迟加载,来避免N+1问题。只需要在相应标签中加一项配置 lazy=”false”即可。
<class name="com.test.vo.Classes" table="t_classes">
<id name="id">
<generator class="native"/>
</id>
<property name="name"/>
//取消延迟加载,即查询班级的同时 连通 所有学生都查询出来
<set name="students" lazy="false">
<key column="classesid"/>
<one-to-many class="com.test.vo.Student"></one-to-many>
</set>
</class>
去除延迟加载,的确可以避免这种问题。但是,对于仅仅查询班级信息 来说,这样花费的代价 又太大了。
针对不同的需求。hibernate提供了不同的方法。如:list()和Iterate() get()和load()等
他们的区别在于,对缓存的利用。
总结
在学习Hibernate的时候,最好将hibernate.show_sql属性配置上。这样就可以在控制台上看到hibernate生成的sql语句。这样配置,可以调试自己程序,进而优化查询效率。

本文详细介绍了Hibernate框架的基本使用方法,包括简单查询、带条件查询、分页查询及SQL语句查询等多种查询方式,并探讨了查询过程中可能遇到的问题及解决方案。
271

被折叠的 条评论
为什么被折叠?



