一般使用的Hibernate一般是三種:hql查詢,QBC查詢和QBE查詢:
一、QBE(Qurey By Example)檢索方式
QBE是最簡單的,可是功能也是最弱的,QBE的功能不是特別強大,僅在某些場合下有用。一個典型的使用場合就是在查詢窗口中讓用戶輸入一系列的查詢條件,而後返回匹配的對象。QBE只支持=和like比較運算符,沒法不大區間值,及其或的匹配。在這種狀況下,仍是採用HQL檢索方式或QBC檢索方式。
java
/** 數據庫
* @function 根據傳遞過來的Object,分頁顯示在數據庫中與其匹配的記錄 app
* @param pageNo post
* 當前頁數 this
* @param pageSize spa
* 每頁顯示的記錄數 code
* @param object 對象
* 將查詢條件封裝爲Object 接口
* @return 將查詢結果封裝爲Pager返回
*/
public Pager findPageByExample(int pageNo, int pageSize, Object object)
{
Pager pager = null;
try
{
Criteria criteria = this.getSession().createCriteria(
Class.forName(this.getEntity()));
if (object != null)
{
criteria.add(Example.create(object).enableLike());
}
// 獲取根據條件分頁查詢的總行數
int rowCount = (Integer) criteria.setProjection(
Projections.rowCount()).uniqueResult();
criteria.setProjection(null);
criteria.setFirstResult((pageNo - 1) * pageSize);
criteria.setMaxResults(pageSize);
List result = criteria.list();
pager = new Pager(pageSize, pageNo, rowCount, result);
} catch (RuntimeException re)
{
throw re;
} finally
{
return pager;
}
}
/** * @function 根據傳遞過來的Object,分頁顯示在數據庫中與其匹配的記錄 * @param pageNo * 當前頁數 * @param pageSize * 每頁顯示的記錄數 * @param object * 將查詢條件封裝爲Object * @return 將查詢結果封裝爲Pager返回 */ public Pager findPageByExample(int pageNo, int pageSize, Object object) { Pager pager = null; try { Criteria criteria = this.getSession().createCriteria( Class.forName(this.getEntity())); if (object != null) { criteria.add(Example.create(object).enableLike()); } // 獲取根據條件分頁查詢的總行數 int rowCount = (Integer) criteria.setProjection( Projections.rowCount()).uniqueResult(); criteria.setProjection(null); criteria.setFirstResult((pageNo - 1) * pageSize); criteria.setMaxResults(pageSize); List result = criteria.list(); pager = new Pager(pageSize, pageNo, rowCount, result); } catch (RuntimeException re) { throw re; } finally { return pager; } }
注意代碼的第20行,即criteria.add(Example.create(object).enableLike());這一行,需將Example.create(object)調用.enableLike()方法,否則不能模糊查詢。
在BO層將須要模糊查詢的列用"%%"串起來,否則仍然和"="同樣。
BO層代碼:
/**
* @function 將傳遞過來的參數封裝成搶修人員Bean,分頁查詢符合條件的記錄
* @param pageNo
* 當前的頁碼
* @param pageSize
* 每頁顯示的記錄數
* @param mendName
* 搶修人員的名稱
* @param specialty
* 搶修人員的工種
* @param post
* 搶修人員的職稱
* @return 將符合條件的記錄數以及頁碼信息封裝成PagerBean返回
*/
public Pager getInfoByQuery(int pageNo, int pageSize, String mendName,
String specialty, String post)
{
EicMend eicMend = new EicMend();
if (mendName != null && mendName.length() > 0)
{
eicMend.setMendname("%" + mendName + "%");
}
if (specialty != null && specialty.length() > 0)
{
eicMend.setSpecialty(specialty);
}
if (post != null && post.length() > 0)
{
eicMend.setPost(post);
}
Pager pager = erpManagerDao
.findPageByExample(pageNo, pageSize, eicMend);
return pager;
}
/** * @function 將傳遞過來的參數封裝成搶修人員Bean,分頁查詢符合條件的記錄 * @param pageNo * 當前的頁碼 * @param pageSize * 每頁顯示的記錄數 * @param mendName * 搶修人員的名稱 * @param specialty * 搶修人員的工種 * @param post * 搶修人員的職稱 * @return 將符合條件的記錄數以及頁碼信息封裝成PagerBean返回 */ public Pager getInfoByQuery(int pageNo, int pageSize, String mendName, String specialty, String post) { EicMend eicMend = new EicMend(); if (mendName != null && mendName.length() > 0) { eicMend.setMendname("%" + mendName + "%"); } if (specialty != null && specialty.length() > 0) { eicMend.setSpecialty(specialty); } if (post != null && post.length() > 0) { eicMend.setPost(post); } Pager pager = erpManagerDao .findPageByExample(pageNo, pageSize, eicMend); return pager; }
執行SQL語句以下:
Hibernate: select count(*) as y0_ from YJZX.EIC_MEND this_ where
(this_.MENDNAME like ? and this_.POST like ?)
Hibernate: select * from ( select this_.MENDID as MENDID23_0_, ……
this_.EXPERTREMARK as EXPERTR28_23_0_ from YJZX.EIC_MEND this_ where
(this_.MENDNAME like ? and this_.POST like ?) ) where rownum <= ?
Hibernate: select count(*) as y0_ from YJZX.EIC_MEND this_ where (this_.MENDNAME like ? and this_.POST like ?) Hibernate: select * from ( select this_.MENDID as MENDID23_0_, …… this_.EXPERTREMARK as EXPERTR28_23_0_ from YJZX.EIC_MEND this_ where (this_.MENDNAME like ? and this_.POST like ?) ) where rownum <= ?
因此只需將需模糊查詢的列用「%%」連接便可。
二、QBC(Qurey By Criteria)檢索方式
採用HQL檢索方式時,在應用程序中須要定義基於字符串形式的HQL查詢語句。QBC API提供了檢索對象的另外一種方式,它主要由Criteria接口、Criterion接口和Restrictions接口組成,它支持在運行時動態生成查詢語句。比較常見的是兩種傳參方式:一種是用map傳參,另外一種是用Criterion…不定參數傳參。
Map傳參方式範例以下:
DAO層:
/**
* @function 分頁顯示符合全部的記錄數,將查詢結果封裝爲Pager
* @param pageNo
* 當前頁數
* @param pageSize
* 每頁顯示的條數
* @param map
* 將查詢條件封裝爲map
* @return 查詢結果Pager
*/
public Pager findPageByCriteria(int pageNo, int pageSize, Map map)
{
Pager pager = null;
try
{
Criteria criteria = this.getSession().createCriteria(
Class.forName(this.getEntity()));
if (map != null)
{
Set<String> keys = map.keySet();
for (String key : keys)
{
criteria.add(Restrictions.like(key, map.get(key)));
}
}
// 獲取根據條件分頁查詢的總行數
int rowCount = (Integer) criteria.setProjection(
Projections.rowCount()).uniqueResult();
criteria.setProjection(null);
criteria.setFirstResult((pageNo - 1) * pageSize);
criteria.setMaxResults(pageSize);
List result = criteria.list();
pager = new Pager(pageSize, pageNo, rowCount, result);
} catch (RuntimeException re)
{
throw re;
} finally
{
return pager;
}
}
/** * @function 分頁顯示符合全部的記錄數,將查詢結果封裝爲Pager * @param pageNo * 當前頁數 * @param pageSize * 每頁顯示的條數 * @param map * 將查詢條件封裝爲map * @return 查詢結果Pager */ public Pager findPageByCriteria(int pageNo, int pageSize, Map map) { Pager pager = null; try { Criteria criteria = this.getSession().createCriteria( Class.forName(this.getEntity())); if (map != null) { Set<String> keys = map.keySet(); for (String key : keys) { criteria.add(Restrictions.like(key, map.get(key))); } } // 獲取根據條件分頁查詢的總行數 int rowCount = (Integer) criteria.setProjection( Projections.rowCount()).uniqueResult(); criteria.setProjection(null); criteria.setFirstResult((pageNo - 1) * pageSize); criteria.setMaxResults(pageSize); List result = criteria.list(); pager = new Pager(pageSize, pageNo, rowCount, result); } catch (RuntimeException re) { throw re; } finally { return pager; } }
Map傳參方式對應BO層代碼:
/**
* @function 將傳遞過來的參數封裝成搶修人員Bean,分頁查詢符合條件的記錄
* @param pageNo
* 當前的頁碼
* @param pageSize
* 每頁顯示的記錄數
* @param mendName
* 搶修人員的名稱
* @param specialty
* 搶修人員的工種
* @param post
* 搶修人員的職稱
* @return 將符合條件的記錄數以及頁碼信息封裝成PagerBean返回
*/
public Pager getInfoByQuery2(int pageNo, int pageSize, String mendName,
String specialty, String post)
{
Map map = new HashMap();
if (mendName != null && mendName.length() > 0)
{
map.put("mendname", "%" + mendName + "%");
}
if (specialty != null && specialty.length() > 0)
{
map.put("specialty", specialty);
}
if (post != null && post.length() > 0)
{
map.put("post", post);
}
Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize, map);
return pager;
}
/** * @function 將傳遞過來的參數封裝成搶修人員Bean,分頁查詢符合條件的記錄 * @param pageNo * 當前的頁碼 * @param pageSize * 每頁顯示的記錄數 * @param mendName * 搶修人員的名稱 * @param specialty * 搶修人員的工種 * @param post * 搶修人員的職稱 * @return 將符合條件的記錄數以及頁碼信息封裝成PagerBean返回 */ public Pager getInfoByQuery2(int pageNo, int pageSize, String mendName, String specialty, String post) { Map map = new HashMap(); if (mendName != null && mendName.length() > 0) { map.put("mendname", "%" + mendName + "%"); } if (specialty != null && specialty.length() > 0) { map.put("specialty", specialty); } if (post != null && post.length() > 0) { map.put("post", post); } Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize, map); return pager; }
第二種方式:Criterion…不定參數傳參方式。其代碼以下所示:
DAO層代碼:
/**
* @function 分頁顯示符合全部的記錄數,將查詢結果封裝爲Pager
* @param pageNo
* 當前頁數
* @param pageSize
* 每頁顯示的條數
* @param criterions
* 不定參數Criterion
* @return 查詢結果Pager
*/
public Pager findPageByCriteria(int pageNo, int pageSize,
Criterion... criterions)
{
Pager pager = null;
try
{
Criteria criteria = this.getSession().createCriteria(
Class.forName(this.getEntity()));
if (criterions != null)
{
for (Criterion criterion : criterions)
{
if (criterion != null)
{
criteria.add(criterion);
}
}
}
// 獲取根據條件分頁查詢的總行數
int rowCount = (Integer) criteria.setProjection(
Projections.rowCount()).uniqueResult();
criteria.setProjection(null);
criteria.setFirstResult((pageNo - 1) * pageSize);
criteria.setMaxResults(pageSize);
List result = criteria.list();
pager = new Pager(pageSize, pageNo, rowCount, result);
} catch (RuntimeException re)
{
throw re;
} finally
{
return pager;
}
}
/** * @function 分頁顯示符合全部的記錄數,將查詢結果封裝爲Pager * @param pageNo * 當前頁數 * @param pageSize * 每頁顯示的條數 * @param criterions * 不定參數Criterion * @return 查詢結果Pager */ public Pager findPageByCriteria(int pageNo, int pageSize, Criterion... criterions) { Pager pager = null; try { Criteria criteria = this.getSession().createCriteria( Class.forName(this.getEntity())); if (criterions != null) { for (Criterion criterion : criterions) { if (criterion != null) { criteria.add(criterion); } } } // 獲取根據條件分頁查詢的總行數 int rowCount = (Integer) criteria.setProjection( Projections.rowCount()).uniqueResult(); criteria.setProjection(null); criteria.setFirstResult((pageNo - 1) * pageSize); criteria.setMaxResults(pageSize); List result = criteria.list(); pager = new Pager(pageSize, pageNo, rowCount, result); } catch (RuntimeException re) { throw re; } finally { return pager; } }
Criterion…不定參數傳參方式對應BO層代碼:
/**
* @function 將傳遞過來的參數封裝成搶修人員Bean,分頁查詢符合條件的記錄
* @param pageNo
* 當前的頁碼
* @param pageSize
* 每頁顯示的記錄數
* @param mendName
* 搶修人員的名稱
* @param specialty
* 搶修人員的工種
* @param post
* 搶修人員的職稱
* @return 將符合條件的記錄數以及頁碼信息封裝成PagerBean返回
*/
public Pager getInfoByQuery3(int pageNo, int pageSize, String mendName,
String specialty, String post)
{
Criterion criterion1 = null, criterion2 = null, criterion3 = null;
if (mendName != null && mendName.length() > 0)
{
criterion1 = Restrictions.ilike("mendname", mendName,
MatchMode.ANYWHERE);
}
if (specialty != null && specialty.length() > 0)
{
criterion2 = Restrictions.ilike("specialty", specialty,
MatchMode.EXACT);
}
if (post != null && post.length() > 0)
{
criterion3 = Restrictions.ilike("post", post, MatchMode.EXACT);
}
Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize,
criterion1, criterion2, criterion3);
return pager;
}
/** * @function 將傳遞過來的參數封裝成搶修人員Bean,分頁查詢符合條件的記錄 * @param pageNo * 當前的頁碼 * @param pageSize * 每頁顯示的記錄數 * @param mendName * 搶修人員的名稱 * @param specialty * 搶修人員的工種 * @param post * 搶修人員的職稱 * @return 將符合條件的記錄數以及頁碼信息封裝成PagerBean返回 */ public Pager getInfoByQuery3(int pageNo, int pageSize, String mendName, String specialty, String post) { Criterion criterion1 = null, criterion2 = null, criterion3 = null; if (mendName != null && mendName.length() > 0) { criterion1 = Restrictions.ilike("mendname", mendName, MatchMode.ANYWHERE); } if (specialty != null && specialty.length() > 0) { criterion2 = Restrictions.ilike("specialty", specialty, MatchMode.EXACT); } if (post != null && post.length() > 0) { criterion3 = Restrictions.ilike("post", post, MatchMode.EXACT); } Pager pager = erpManagerDao.findPageByCriteria(pageNo, pageSize, criterion1, criterion2, criterion3); return pager; }
三、HQL檢索方式
HQL(Hibernate Query Language)是面向對象的查詢語言,它和SQL查詢語言有些相識。在Hibernate提供的各類檢索方式中,HQL是使用最廣的一種檢索方式。
使用Query接口分頁查詢DAO代碼:
/**
* @function 分頁顯示符合全部的記錄數,將查詢結果封裝爲Pager
* @param pageNo
* 當前頁數
* @param pageSize
* 每頁顯示的條數
* @param instance
* 將查詢條件封裝爲專家Bean
* @return 查詢結果Pager
*/
public List<Object> findPageByQuery(int pageNo, int pageSize, String hql,
Map map)
{
List<Object> result = null;
try
{
Query query = this.getSession().createQuery(hql);
Iterator it = map.keySet().iterator();
while (it.hasNext())
{
Object key = it.next();
query.setParameter(key.toString(), map.get(key));
}
query.setFirstResult((pageNo - 1) * pageSize);
query.setMaxResults(pageSize);
result = query.list();
} catch (RuntimeException re)
{
throw re;
}
return result;
}
/** * @function 分頁顯示符合全部的記錄數,將查詢結果封裝爲Pager * @param pageNo * 當前頁數 * @param pageSize * 每頁顯示的條數 * @param instance * 將查詢條件封裝爲專家Bean * @return 查詢結果Pager */ public List<Object> findPageByQuery(int pageNo, int pageSize, String hql, Map map) { List<Object> result = null; try { Query query = this.getSession().createQuery(hql); Iterator it = map.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); query.setParameter(key.toString(), map.get(key)); } query.setFirstResult((pageNo - 1) * pageSize); query.setMaxResults(pageSize); result = query.list(); } catch (RuntimeException re) { throw re; } return result; }
查詢全部記錄數的DAO代碼:
/**
* @function 根據查詢條件查詢記錄數的個數
* @param hql
* hql查詢語句
* @param map
* 用map封裝查詢條件
* @return 數據庫中知足查詢條件的數據的條數
*/
public int getTotalCount(String hql, Map map)
{
try
{
Query query = this.getSession().createQuery(hql);
Iterator it = map.keySet().iterator();
while (it.hasNext())
{
Object key = it.next();
query.setParameter(key.toString(), map.get(key));
}
Integer i = (Integer) query.list().get(0);
return i;
} catch (RuntimeException re)
{
throw re;
}
}
/** * @function 根據查詢條件查詢記錄數的個數 * @param hql * hql查詢語句 * @param map * 用map封裝查詢條件 * @return 數據庫中知足查詢條件的數據的條數 */ public int getTotalCount(String hql, Map map) { try { Query query = this.getSession().createQuery(hql); Iterator it = map.keySet().iterator(); while (it.hasNext()) { Object key = it.next(); query.setParameter(key.toString(), map.get(key)); } Integer i = (Integer) query.list().get(0); return i; } catch (RuntimeException re) { throw re; } }
BO層代碼:
/**
* @function 將傳遞過來的參數封裝成專家Bean,分頁查詢符合條件的記錄
* @param pageNo
* 當前的頁碼
* @param pageSize
* 每頁顯示的記錄數
* @param expertName
* 專家的名稱
* @param expertSpecialty
* 專家的專業類別
* @param post
* 專家的行政職位
* @return 將符合條件的記錄數以及頁碼信息封裝成PagerBean返回
*/
public Pager getInfoByQuery(int pageNo, int pageSize, String expertName,
String expertSpecialty, String post)
{
StringBuffer hql = new StringBuffer();
hql.append("select count(expertid) from EicExpert where 1=1 ");
Map map = new HashMap();
if (expertName != null && expertName.length() > 0)
{
map.put("expertname", "%" + expertName + "%");
hql.append("and expertname like :expertname ");
}
if (expertSpecialty != null && expertSpecialty.length() > 0)
{
map.put("expertspecialty", expertSpecialty);
hql.append("and expertspecialty like :expertspecialty ");
}
if (post != null && post.length() > 0)
{
map.put("post", post);
hql.append("and post like :post ");
}
String queryHql = hql.substring(22);
List result = erpManagerDao.findPageByQuery(pageNo, pageSize,
queryHql, map);
int rowCount = erpManagerDao.getTotalCount(hql.toString(), map);
Pager pager = new Pager(pageSize, pageNo, rowCount, result);
return pager;
}
/** * @function 將傳遞過來的參數封裝成專家Bean,分頁查詢符合條件的記錄 * @param pageNo * 當前的頁碼 * @param pageSize * 每頁顯示的記錄數 * @param expertName * 專家的名稱 * @param expertSpecialty * 專家的專業類別 * @param post * 專家的行政職位 * @return 將符合條件的記錄數以及頁碼信息封裝成PagerBean返回 */ public Pager getInfoByQuery(int pageNo, int pageSize, String expertName, String expertSpecialty, String post) { StringBuffer hql = new StringBuffer(); hql.append("select count(expertid) from EicExpert where 1=1 "); Map map = new HashMap(); if (expertName != null && expertName.length() > 0) { map.put("expertname", "%" + expertName + "%"); hql.append("and expertname like :expertname "); } if (expertSpecialty != null && expertSpecialty.length() > 0) { map.put("expertspecialty", expertSpecialty); hql.append("and expertspecialty like :expertspecialty "); } if (post != null && post.length() > 0) { map.put("post", post); hql.append("and post like :post "); } String queryHql = hql.substring(22); List result = erpManagerDao.findPageByQuery(pageNo, pageSize, queryHql, map); int rowCount = erpManagerDao.getTotalCount(hql.toString(), map); Pager pager = new Pager(pageSize, pageNo, rowCount, result); return pager; }
注:Pager類是我封裝的一個分頁類,包含 每頁顯示記錄數,當前頁,總記錄數,每頁顯示數據的集合。因可有可無,沒有貼出來。另外我不知道Query接口有沒有相似於Criteria那樣能夠直接在分頁查詢記錄的同時查詢出總記錄條數,知道的大蝦麻煩告訴下哈。在BO裏設置不定參數的時候感受也不太好,不知道大蝦們可有比較好的辦法。