Hibernate共有三种查询方式:HQL、QBC和SQL
HQL
写起来灵活直观,而且与所熟悉的SQL的语法类似。
条件查询、分页查询、连接查询、嵌套查询,包括一些查询函数(count(),sum()等)、查询条件的设定等写起来与SQL语法一致,主要区别就是把表名换成了类或者对象。
注意:在hql中关键字不区分大小写,但是属性和类名区分大小写
static void query(String name){
Session s=null;
try{
s=HibernateUtil.getSession();
//from后面是对象,不是表名
String hql="from Admin as admin where admin.aname=:name";//使用命名参数,推荐使用,易读。
Query query=s.createQuery(hql);
query.setString("name", name);
List<Admin> list=query.list();
for(Admin admin:list){
System.out.println(admin.getAname());
}
}finally{
if(s!=null)
s.close();
}
}
QBC(Query By Criteria)
这种方式比较面向对象方式,重点是有三个描述条件的对象:Restrictions,Order,Projections。使用QBC查询,一般需要以下步骤:
1 使用Session实例的createCriteria()方法创建Criteria对象;
2 使用工具类Restrictions的方法为Criteria对象设置查询条件;
3 Order工具类的方法设置排序方式;
4 Projections工具类的方法进行统计和分组;
3 使用Criteria对象的list()方法进行查询并返回结果;
static void cri(String name,String password){
Session s=null;
try{
s=HibernateUtil.getSession();
Criteria c=s.createCriteria(Admin.class);
c.add(Restrictions.eq("aname",name));//eq是等于,gt是大于,lt是小于,or是或
c.add(Restrictions.eq("apassword", password));
List<Admin> list=c.list();
for(Admin admin:list){
System.out.println(admin.getAname());
}
}finally{
if(s!=null)
s.close();
}
}
SQL
就是采用原生SQL进行查询
static List sql() {
Session s = HibernateUtil.getSession();
Query q = s.createSQLQuery("select * from user").addEntity(User.class);
List<User> rs = q.list();
s.close();
return rs;
}
Query.iterator的N+1查询(基于一的HQL,多见于一对多、多对多的关联映射)
N + 1问题,在默认情况下,使用query.iterate查询,有可以能出现N+1问题;所谓的N+1是在查询的时候发出了N+1条sql语句
- 1: 首先发出一条查询对象id列表的sql
- N: 根据id列表到缓存中查询,如果缓存中不存在与之匹配的数据,那么会根据id发出相应的sql语句
list和iterate的区别?
- list每次都会发出sql语句,list会向缓存中放入数据,而不利用缓存中的数据
- iterate:在默认情况下iterate利用缓存数据,但如果缓存中不存在数据有可以能出现N+1问题
Query q=session.createQuery(“from UserInfo”);
Iterator<UserInfo> list=q.iterate();
While(list.hasNext()) {
UserInfo st = (UserInfo) it.next();
System.out.println(st.getName());
}
避免N+1查询解决方法:
1 可以将fetch抓取数据的属性改为“join”,来避免N+1次的查询;
2 使用二级缓存