一:HQL語句 -- 面向對象的思想,字段用pojo的變量名代替,表名用pojo類名代替,有幾種參數的表示方法,這裡不舉例,網上很多。
沒有select 的 hql查詢語句:查詢該表所有字段。調用list()方法,傳回的是list<pojo>
String hql = "from EmpVo e where e.empname=:empname";
Query createQuery = session.createQuery(hql);
List<EmpVo> emp = createQuery .list();
有select的查詢語句,查詢部分字段:調用list()方法,傳回的是list<Object[]>,如果想讓傳回的是list<pojo>,則可以将hql
String hql = "select empname,cardno,sex from EmpVo e where e.empname=:empname";
改為
String hql = "select new EmpVo(empname,cardno,sex) from EmpVo e where e.empname=:empname";
同時 在pojo中 生成 對應的 有參數構造方法 如
public EmpVo(String empname,String cardno,String sex){
this.empname = empname;
this.cardno = cardno;
this.sex = sex;
}
但這種方式很麻煩,剛好hibernate有個Transformers類,他可以将傳回的結果進行轉換,主要就是來解決傳回的結果是list<Object[]> ,不好周遊,也不友善取值。 下面介紹用法:
String hql ="select empname as name,cardno as cardno,sex as sex from EmpVo";
Query createQuery = session.createQuery(hql);
list=createQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
注意 : 如果用的是 hql查詢,我們的hql語句必須 有别名,否則轉換出來的資料為空
原因: 查詢出的資料,做類型轉換,會自動調用下面這個方法,tuple是查出來的資料,aliases是别名。
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
Map result = new HashMap(tuple.length);
for ( int i=0; i<tuple.length; i++ ) {
String alias = aliases[i];
if ( alias!=null ) {
result.put( alias, tuple[i] );
}
}
return result;
}
可以看出 如果alias == null,就會傳回一個空map,即map這個對象存在,但裡面并沒有存任何資料。
但是: 還有另外 一個方法,我個人認為比較好用
String sql1 = "select empname,cardno,sex from employee";
NativeQuery createSQLQuery = session.createSQLQuery(sql1);
createSQLQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
直接用sql語句來查詢,并且調用的是
session.createSQLQuery(sql1);
當執行transfromTuple的時候,會将表的字段名,作為别名,是以用這種方式,就不需要自己去為字段設定别名了。
@Override
public Object transformTuple(Object[] tuple, String[] aliases) {
Map result = new HashMap(tuple.length);
for ( int i=0; i<tuple.length; i++ ) {
String alias = aliases[i];
if ( alias!=null ) {
result.put( alias, tuple[i] );
}
}
return result;
}
二、QBE--線上查詢
// QBE 的查詢 方式 更加 展現面向對象的 思想 --QBE 傳回的list 可以 直接列印出來 -HQL不可以
public List findEmpByQbc(EmpVo emp) {
List list = null;
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.getTransaction();
try {
tx.begin();
Criteria criteria = session.createCriteria(EmpVo.class);
criteria.add(Restrictions.like("empname", "張", MatchMode.ANYWHERE));
list = criteria.list();
tx.commit();
session.close();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
}
return list;
}
Restrictions 就相當于 sql 裡面的 where ,可以加 一些條件來限制。
MatchMode就是 限制的作用域: 如例子中 要求empname 中必須包含張這個字,至于張這個字出現在哪裡都可以,隻要包含了就行,這就是 MatchMode.ANYWHERE 的作用。
三、QBC 查詢 --- 離線查詢 。
QBE 查詢的 弊端 就是 通用性查,我現在查詢emp表,需要寫一個方法,當時這個方法當我要查詢 dep表的時候就不适用了。
因為表與表的字段不同,限制條件也會不同。
是以産生了 QBC 查詢, QBC查詢實作了 将 限制的條件 與 session 分離, 我們在調用這個查詢方法前,通過 DetachedCriteria 對象,來設定一些限制條件,然後 再調用 方法,将 DetachedCriteria 與 session 綁定。
下面 展示 代碼
// 離線查詢 --- 分頁查詢
public List findByRow(DetachedCriteria dc, int startrow, int pagesize) {
List list = null;
HibernateSessionFactory.getSession().clear();
Session session = HibernateSessionFactory.getSession();
Transaction tx = session.getTransaction();
try {
tx.begin();
// 綁定資料庫連接配接
Criteria cr = dc.getExecutableCriteria(session);
// 去重複
cr.setResultTransformer(cr.DISTINCT_ROOT_ENTITY);
cr.setMaxResults(pagesize); // 每頁顯示記錄數
cr.setFirstResult(startrow); // 設定起始位置
list = cr.list();
tx.commit();
session.close();
} catch (Exception e) {
tx.rollback();
e.printStackTrace();
}
return list;
}
調用
public static void main6(String[] args) {
HBaseDao base = new HBaseDao();
//離線查詢
DetachedCriteria dc = DetachedCriteria.forClass(EmpVo.class); //查emp這個表
dc.add(Restrictions.eq("empname", "張三)); //設定條件,empname = "張三"
find = base.findByRow(dc, 0, 1); //調用方法,傳一個DetachedCriteria對象,分頁的起始條數,每頁顯示資料數目
System.out.println("離線查詢,分頁查詢 :" +find);
}