博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Hibernate查询
阅读量:5162 次
发布时间:2019-06-13

本文共 6539 字,大约阅读时间需要 21 分钟。

Hibernate总的来说共有三种查询方式:HQL、QBC和SQL三种。但是细分可以有如下几种:

一、HQL查询方式

    这一种我最常用,也是最喜欢用的,因为它写起来灵活直观,而且与所熟悉的SQL的语法差不太多。条件查询、分页查询、连接查询、嵌套查询,写起来与SQL语法基本一致,唯一不同的就是把表名换成了类或者对象。其它的,包括一些查询函数(count(),sum()等)、查询条件的设定等,全都跟SQL语法一样。
###注意:
     在hql中关键字不区分大小写,但是属性和类名区分大小写
示例1:

 

1 static void query(String name){ 2   Session s=null; 3  4   try{ 5  6    s=HibernateUtil.getSession(); 7  8    //from后面是对象,不是表名 9 10    String hql="from Admin as admin where admin.aname=:name";//使用命名参数,推荐使用,易读。11 12    Query query=s.createQuery(hql);13 14    query.setString("name", name);15 16    List
list=query.list();17 18 for(Admin admin:list){19 20 System.out.println(admin.getAname());21 }22 23 }finally{24 25 if(s!=null)26 27 s.close();28 }29 }

######!!!!!!!!!!!!!对于多对一关系查询:

 String hql = "from Student where Class.className = '二班'";
(Student实体类中含有Class对象的引用。这样相当于两张表的联合查询

示例2(分页查询):

 

1 Query query = session.createQuery("from Customer c order by c.name asc");2 query.setFirstResult(0);3 query.setMaxResults(10);4 List result = query.list();

 

说明:

   –setFirstResult(int firstResult):设定从哪一个对 象开始检索,参数firstResult表示这个对象在查询结果中的索引位置,索引位置的起始值为0。默认情况下,Query和Criteria接口从查 询结果中的第一个对象,也就是索引位置为0的对象开始检索。 

    –setMaxResult(int maxResults):设定一次最多检索出的对象数目。默认情况下,Query和Criteria接口检索出查询结果中所有的对象。

 

适用情况:常用方法,比较传统,类似jdbc。缺点:新的查询语言,适用面有限,仅适用于Hibernate框架。

二、QBC(Query By Criteria) 查询方式

这种方式比较面向对象方式,重点是有三个描述条件的对象:Restrictions,Order,Projections。使用QBC查询,一般需要以下三个步骤:

   1、 使用Session实例 的createCriteria()方法创建Criteria对象
   2、使用工具类Restrictions的方法为Criteria对象设置查询条件,Order工具类的方法设置排序方式,Projections工具类的方法进行统计和分组。
   3、 使用Criteria对象的list()方法进行查询并返回结果
Restrictions类的常用方法:

Restrictions类的常用方法:

方法名称
描述
Restrictions.eq 等于
Restrictions.allEq 使用Map,Key/Valu进行多个等于的比对
Restrictions.gt 大于
Restrictions.ge 大于等于
Restrictions.lt 小于
Restrictions.le 小于等于
Restrictions.between 对应SQL的between
Restrictions.like 对应SQL的like
Restrictions.in 对应SQL的in
Restrictions.and and关系
Restrictions.or or关系
Restrictions.sqlRestriction SQL限定查询

Order类的常用方法:

方法名称
描述
Order.asc 升序
Order.desc 降序

Projections类的常用方法

方法名称
描述
Projections.avg 求平均值
Projections.count 统计某属性的数量
Projections.countDistinct 统计某属性不同值的数量
Projections.groupProperty 指定某个属性为分组属性
Projections.max 求最大值
Projections.min 求最小值
Projections.projectionList 创建一个ProjectionList对象
Projections.rowCount 查询结果集中的记录条数
Projections.sum 求某属性的合计

示例:

1 static void cri(String name,String password){ 2  3   Session s=null; 4  5   try{ 6  7    s=HibernateUtil.getSession(); 8  9    Criteria c=s.createCriteria(Admin.class);10 11    c.add(Restrictions.eq("aname",name));//eq是等于,gt是大于,lt是小于,or是或12 13    c.add(Restrictions.eq("apassword", password));14 15    List
list=c.list();16 17 for(Admin admin:list){18 19 System.out.println(admin.getAname());20 21 }22 23 }finally{24 25 if(s!=null)26 27 s.close();28 29 }30 }

示例2(分页查询)

1 Criteria criteria = session.createCriteria(Customer.class);2 criteria.addOrder( Order.asc("name") ); //排序方式3 criteria.setFirstResult(0);4 criteria.setMaxResults(10);5 List result = criteria.list();

适用情况:面向对象操作,革新了以前的数据库操作方式,易读。缺点:适用面较HQL有限。

三、QBE(Query By Example)例子查询方式

   将一个对象的非空属性作为查询条件进行查询。
 示例:

1 Session session = SessionFactory.getCurrentSession(); 2  3 User user = new User(); 4 user.setName("ijse"); 5  6 Transaction ts = session.beginTransaction(); 7  8 try { 9 10     Criteria criteria = session.createCriteria(User.class);11 12     criteria.add(Example.create(user));13 14     user= (User) criteria.list().get(0);   15 16     session.commit();17 18 } catch (HibernateException ex) {19 20     ts.rollBack();21 22     ex.printStackTrace();23 24 }25 26 System.out.println(user.getName());

适用情况:面向对象操作。   缺点:适用面较HQL有限,不推荐。

四、DetachedCriteria:离线条件查询

离线查询就是建立一个DetachedCriteria对象,将查询的条件等指定好,然后在session.beginTransaction()后将这个对象传入。通常这个对象可以在表示层建立,然后传入业务层进行查询。

1 //1、建立DetachedCriteria对象 2 DetachedCriteria dc = DetachedCriteria.forClass(User.class); 3  4 int id = 1; 5  6 if (id != 0) 7     dc.add(Restrictions.eq("id", id)); 8  9 Date age = new Date();10 11 if (age != null)12     dc.add(Restrictions.le("birthday", age));13 14 List users = dc(dc);//执行查询15 16 System.out.println("离线查询返回结果:" + users);17  //2、执行查询18 static List dc(DetachedCriteria dc) {19     Session s = HibernateUtil.getSession();20 21     Criteria c = dc.getExecutableCriteria(s);22     List rs = c.list();23 24     s.close();25     return rs;26 }

适用情况:面向对象操作,分离业务与底层,不需要字段属性摄入到Dao实现层。 缺点:适用面较HQL有限。

五、命名查询

  1、在数据映射元文件中进行配置如下:

1 
2 3 6
7 8
9 ....10
11 12
13 14
15 16 17 18
19 20
27 28

2、在java代码中写入:

1 static List namedQuery(int id) {2   Session s = HibernateUtil.getSession();3   Query q = s.getNamedQuery("getUserById");4   q.setInteger("id", id);5   return q.list();6 }

适用情况:万能方法,有点像ibatis轻量级框架的操作,方便维护。  缺点:不面向对象。基于hql和sql,有一定缺陷。

六、SQL查询

   示例:

1 static List sql() { 2     Session s = HibernateUtil.getSession(); 3  4     Query q = s.createSQLQuery("select * from user").addEntity(User.class); 5  6     List
rs = q.list(); 7 8 s.close(); 9 10 return rs;11 }

适用情况:不熟悉HQL的朋友,又不打算转数据库平台的朋友,万能方法   缺点:破坏跨平台,不易维护,不面向对象。

七、OID查询方式

    按照对象的OID来检索对象。Session的get()和load()方法提供了这种功能。如果在应用程序中事先知道了OID,就可以使用这种检索对象的方式。 

 

八、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问题
  示例:

1      Query q=session.createQuery(“from UserInfo”);2      Iterator
list=q.iterate();3 While(list.hasNext()) {4 UserInfo st = (UserInfo) it.next();5 System.out.println(st.getName());6 }

避免N+1查询解决方法:

    1、可以将fetch抓取数据的属性改为“join”,来避免N+1次的查询;
    2、使用二级缓存

九、复查查询(基于二:QBC的深度查询)

  复合查询就是在原有查询的基础上再进行查询,可以调用Criteria对象的createCriteria()方法在这个Criteria对象的基础上再进行查询。
示例:

1 Session session = SessionFactory.getCurrentSession(); 2  3 User user = new User(); 4  5 Transaction ts = session.beginTransaction(); 6  7 try  { 8  9    Criteria criteria1 = session.createCriteria(Room.class);10 11    Criteria  criteria2 =criterial.createCriteria("User");12 13     criteria2.add(Restrictions.eq("name",new String("ijse"));14 15     user= (User) criteria.list().get(0);16 17     session.commit();18 19 } catch (HibernateException ex) {20 21    ts.rollBack();22 23    ex.printStackTrace();24 }25 26 System.out.println(user.getName());

 

转载于:https://www.cnblogs.com/javaleon/p/3998677.html

你可能感兴趣的文章
GPT+UEFI+双硬盘+双系统 win10+ubuntu 安装指导
查看>>
软件测试第二次上机实验——Selenium的使用
查看>>
javascript常用函数集
查看>>
JavaScript 的使用基础总结③
查看>>
《人月神话》读书笔记——第一周
查看>>
Suggestion for Bing Dictionary
查看>>
.net使用httpHandler添加图片防盗链
查看>>
怎么把一个int数组转化为char型数组??
查看>>
Linux问题FAQ1
查看>>
ubuntu安装qt步骤(源码)
查看>>
根据函数名称调用函数
查看>>
中文编程专栏目录, 初衷和希冀
查看>>
双日历组件JC.DCalendar总结
查看>>
Why does "ps -aux" complain about a bogus '-'?
查看>>
visual studio 一直显示正在准备解决方案
查看>>
子查询二(在HAVING子句中使用子查询)
查看>>
OracleHelper 动软生成
查看>>
SQL 注入教程
查看>>
AtCoder Regular Contest 100 E - Or Plus Max
查看>>
08CMS Variable Override Write Arbitrarily WEBSHELL Into Arbitrarily Path
查看>>