天天看點

hibernate的 HQL、QBE、QBC

一: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);

	}
	
           

繼續閱讀