Hibernate的三種查詢方式


1、背景了解:Hibernate的三種查詢方式

Hibernate總的來說共有三種查詢方式:HQL、QBC和SQL三種,這里做簡單的概念介紹,不詳細進行展開。
 

1.1 HQL(Hibernate Query Language)

與所熟悉的SQL的語法差不太多,不同的就是把表名換成了類或者對象,如下示例:
 
@Override 
public SysUser findUserByLoginName(String pLoginName) {
    String hql = "from SysUser as u where u.loginName = ?";
    List<SysUser> users = getHibernateTemplate().find(hql, pLoginName); //pLoginName對應?
    return users.isEmpty() ? null : users.get(0);
}

1.2 SQL(Structured Query Language)

 
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;
}
 
缺點:違背了hibernate的跨平台優點,不易維護,不面向對象。不推薦使用。
 

1.3 QBC(Query By Criteria)

1.3.1 QBC查詢的基本步驟

這種方式比較面向對象方式,重點是有三個描述條件的對象:Restrictions,Order,Projections。使用QBC查詢,一般需要以下三個步驟:
  • 使用Session實例的createCriteria()方法創建Criteria對象;
  • 使用工具類Restrictions的方法為Criteria對象設置查詢條件,Order工具類的方法設置排序方式,Projections工具類的方法進行統計和分組;
  • 使用Criteria對象的list()方法進行查詢並返回結果。
 

1.3.2 Restrictions、Order、Projections的常用方法

Restrictions類的常用方法(設置查詢條件):
返回值類型 方法名稱 描述
SimpleExpression Restrictions.eq 等於(equal)
Criterion Restrictions.allEq 使用Map,Key/Valu進行多個等於的比對
SimpleExpression Restrictions.gt 大於(great than)
SimpleExpression Restrictions.ge 大於等於(great than or equal)
SimpleExpression Restrictions.lt 小於(less than)
SimpleExpression Restrictions.le 小於等於(less than or equal)
Criterion Restrictions.between 對應SQL的between
SimpleExpression Restrictions.like 對應SQL的like
Criterion Restrictions.in 對應SQL的in
LogicalExpression Restrictions.and and關系
LogicalExpression Restrictions.or or關系
Criterion Restrictions.isNull 為空
Criterion Restrictions.sqlRestriction SQL限定查詢
 
Order類的常用方法(設置排序方式):
返回值類型 方法名稱 描述
Order Order.asc 升序
Order Order.desc 降序
 
Projections類的常用方法(統計和分組):
返回值類型 方法名稱 描述
AggregateProjection Projections.avg 求平均值
CountProjection Projections.count 統計某屬性的數量
CountProjection Projections.countDistinct 統計某屬性不同值的數量
PropertyProjection Projections.groupProperty 指定某個屬性為分組屬性
AggregateProjection Projections.max 求最大值
AggregateProjection Projections.min 求最小值
ProjectionList Projections.projectionList 創建一個ProjectionList對象
Projection Projections.rowCount 查詢結果集中的記錄條數
AggregateProjection Projections.sum 求某屬性的合計
更多方法,以及方法的詳細使用及解釋,請參看 在線API:Hibernate API Documentation(3.2.7.ga)
 

1.3.3 QBC的查詢示例和基本理解

接下來,基於以上的一些常用方法,我們先看兩個示例:
 
//查詢匹配的賬戶adminList
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();
 
 
 
//分頁查詢前10條
Criteria criteria = session.createCriteria(Customer.class);
criteria.addOrder( Order.asc("name") ); //排序方式
criteria.setFirstResult(0);
criteria.setMaxResults(10);
List result = criteria.list()
 
 
看到這里,流程大概很好理解,從方法名就知道無非是把各種條件往里面加最后就可以獲得一個符合條件的list。那么, 下面再延伸理解一下:
org.hibernate.Criteria實際上是個條件附加的容器,如果想要設定查詢條件,則要使用 org.hibernate.criterion.Restrictions的各種靜態方法傳回org.hibernate.criterion. Criterion 實例,傳回的每個org.hibernate.criterion.Criteria實例代表着一個條件,你要 使用org.hibernate.Criteria的add()方法加入這些條件實例。下面看個示例:
 
//查找age等於(eq)20或(or)age為空(isNull)的User
Criteria criteria = session.createCriteria(User.class);
criteria.add(Restrictions.or( Restrictions.eq("age", new Integer(20)), Restrictions.isNull("age") ));
List users = criteria.list();
 
              
//實際上它產生的對應的sql如下
Hibernate: 
select 
    this_.id as id0_0_, this_.name as name0_0_, this_.age as age0_0_ 
from 
    T_USER this_ 
where 
    (this_.age=? or this_.age is null)
 

1.3.4 復合查詢

復合查詢就是在原有的查詢基礎上在進行查詢,比如有Clazz班級,包含對象屬性Student,那么我們希望查詢 “包含學生姓名為Bob” 的班級,那么就可以使用復合查詢:
 
 
         
Criteria criteria = session.createCriteria(Clazz.class);
Criteria criteriaInner = criteria.createCriteria(Student.class);
criteriaInner.add(Restrictions.eq("name", "Bob"));
List clazzList =  criteria.list();
 
如果是DetachedCriteria,則是根據關聯屬性的名稱,而非Class,如:
 
Member member = MemberHelper.getCurrentLoginMember();
DetachedCriteria criteria = DetachedCriteria.forClass(Picture.class);
DetachedCriteria collectCriteria = criteria.createCriteria("collectRecordList");
collectCriteria.add(Restrictions.eq("member", member));
List<Picture> pictureList = Picture.listByCriteria(criteria, page, Order.desc("updateDate"));
 
 
 

1.3.5 Hibernate中Criteria方式的基本使用流程

所以,基於以上的的示例和理解,我們不難看出Criteria的基本使用流程:
 
 

2、DetachedCriteria是什么,和Criteria有什么區別

父接口CriteriaSpecification,其下有子接口Criteria和實現類DetachedCriteria, Criteria和DetachedCriteria均可使用Criterion和Projection設置查詢條件。可以設置FetchMode( 聯合查詢抓取的模式 ) ,設置排序方式。對於Criteria還可以設置FlushModel(沖刷 Session 的方式)和LockMode(數據庫鎖模式)。
 
Criteria和DetachedCriteria的主要區別在於創建的形式不一樣,Criteria是在線的,所以它是由Hibernate Session進行創建的;而 DetachedCriteria是離線的,創建時無需Session,它通過2個靜態方法forClass(Class) 或 forEntityName(Name) 進行DetachedCriteria 的實例創建。
 
(另,Spring的框架提供了getHibernateTemplate ().findByCriteria(detachedCriteria) 方法可以很方便地根據DetachedCriteria來返回查詢結果)
 
所以它也稱為離線條件查詢,即建立一個DetachedCriteria對象,將查詢的條件等指定好,然后在session.beginTransaction()后將這個對象傳入。通常這個對象可以在表示層建立,然后傳入業務層進行查詢。
 

3、DetachedCriteria的基本使用

上面已經提到,Criteria和DetachedCriteria均可使用Criterion和Projection設置查詢條件,設置排序方式。那么這里也無需過度展開,以一個簡單的例子來示意吧:
 
//查詢id為1且在今天或今天之前出生的user的名單
//1、創建DetachedCriteria並設置條件
DetachedCriteria dc = DetachedCriteria.forClass(User.class);
int id = 1;
dc.add(Restrictions.eq("id", id));
Date age = new Date();
dc.add(Restrictions.le("birthday", age));

//2、執行查詢(Criteria   getExecutableCriteria(Session session))
Session session = HibernateUtil.getSession();
Criteria c = dc.getExecutableCriteria(session);
List users = c.list();
 
 
這里值得一提的是,DetachedCriteria並沒有像Criteria一樣有list()的方法來返回List,所以需要以此獲取一個可執行的Criteria,達到真正執行查詢的目的,我們看下官方的解釋:
 
org.hibernate.criterion
Class DetachedCriteria
getExecutableCriteria
public Criteria getExecutableCriteria(Session session)
Get an executable instance of Criteria, to actually run the query.


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM