国产一级a片免费看高清,亚洲熟女中文字幕在线视频,黄三级高清在线播放,免费黄色视频在线看

打開APP
userphoto
未登錄

開通VIP,暢享免費電子書等14項超值服

開通VIP
Hibernate sql查詢

Hibernate還支持使用SQL查詢,使用SQL查詢可以利用某些數(shù)據(jù)庫的特性,或者用于將原有的JDBC應(yīng)用遷移到Hibernate應(yīng)用上。使用命名的SQL查詢還可以將SQL語句放在配置文件中配置,從而提高程序的解耦,命名SQL查詢還可以用于調(diào)用存儲過程。

如果是一個新的應(yīng)用,通常不要使用SQL查詢。

SQL查詢是通過SQLQuery接口來表示的,SQLQuery接口是Query接口的子接口,因此完全可以調(diào)用Query接口的方法:

   ● setFirstResult(),設(shè)置返回結(jié)果集的起始點。

   ● setMaxResults(),設(shè)置查詢獲取的最大記錄數(shù)。

   ● list(),返回查詢到的結(jié)果集。

但SQLQuery比Query多了兩個重載的方法:

   ● addEntity,將查詢到的記錄與特定的實體關(guān)聯(lián)。

   ● addScalar,將查詢的記錄關(guān)聯(lián)成標(biāo)量值。

執(zhí)行SQL查詢的步驟如下:

(1)獲取Hibernate Session對象;

(2)編寫SQL語句;

(3)以SQL語句作為參數(shù),調(diào)用Session的createSQLQuery方法創(chuàng)建查詢對象;

(4)如果SQL語句包含參數(shù),調(diào)用Query的setXxx方法為參數(shù)賦值;

(5)調(diào)用SQLQuery對象的addEntity或addScalar方法將選出的結(jié)果與實體或標(biāo)量值關(guān)聯(lián);

(6)調(diào)用Query的list方法返回查詢的結(jié)果集。

看下面的SQL查詢示例:

private void test()

{

    //獲取Hibernate Session對象

    Session session = HibernateUtil.currentSession();

    //開始事務(wù)

    Transaction tx = session.beginTransaction();

    //編寫SQL語句

    String sqlString = "select {s.*} from student s where s.name like '馬軍'";

    //以SQL語句創(chuàng)建SQLQuery對象

    List l = session.createSQLQuery(sqlString)

                    //將查詢到的記錄與特定實體關(guān)聯(lián)起來

                    .addEntity("s",Student.class)

                    //返回全部的記錄集

                    .list();

    //遍歷結(jié)果集

    Iterator it = l.iterator();

    while (it.hasNext())

    {

        //因為將查詢結(jié)果與Student類關(guān)聯(lián),因此返回的是Student集合

        Student s = (Student)it.next();

        Set enrolments = s.getEnrolments();

        Iterator iter = enrolments.iterator();

        while(iter.hasNext())

        {

            Enrolment e = (Enrolment)iter.next();

            System.out.println(e.getCourse().getName());

        }

    }

    //提交事務(wù)

    tx.commit();

    //關(guān)閉Session

    HibernateUtil.closeSession();

}

上面的示例顯示了將查詢記錄關(guān)聯(lián)成一個實體的示例。事實上,SQL查詢也支持將查詢結(jié)果轉(zhuǎn)換成標(biāo)量值,轉(zhuǎn)換成標(biāo)量值可以使用addScalar方法,如:

Double max = (Double) session.createSQLQuery("select max(cat.weight) as maxWeight from cats cat")

        .addScalar("maxWeight", Hibernate.DOUBLE);

        .uniqueResult();

或者:
  1. StringBuffer queryStr = new StringBuffer();   
  2. queryStr.append("select count(*) AA,");   
  3. queryStr.append("sum(st.num1) BB,sum(st.num2) CC,");   
  4. queryStr.append("max(st.cost1) DD,min(st.cost2) EE,");   
  5. queryStr.append("st.col1 FF from TBXXX st")   
  6. .append(" where ")   
  7. .append(SQLQuerySetup.createfilterStr(filter))   
  8. .append(" group by st.col1");   
  9.   
  10. query = session.createSQLQuery(queryStr.toString());   
  11. query.addScalar("AA"new org.hibernate.type.IntegerType());   
  12. query.addScalar("BB"new org.hibernate.type.IntegerType());   
  13. query.addScalar("CC"new org.hibernate.type.IntegerType());   
  14. query.addScalar("DD"new org.hibernate.type.IntegerType());   
  15. query.addScalar("EE"new org.hibernate.type.IntegerType());   
  16. query.addScalar("FF"new org.hibernate.type.IntegerType());   
  17. return query.list();  

注意2個問題 
1.Query 沒有addScalar()方法,使用SQLQuery才有addScalar()方法 
2.如果查詢的結(jié)果集的字段為id,count(*) as count,則如果只 
addScalar("count",type),將得不到id的值,需要加上addScalar("id",type),也就是要把每一個字段都要addScalar()

使用SQL查詢,如果需要將查詢到的結(jié)果轉(zhuǎn)換成特定實體,就要求為選出的字段命名別名。這別名不是隨意命名的,而是以“/”實例名.屬性名“/”的格式命名,例如:

//依次將多個選出的字段命名別名,命名別名時都以ss作為前綴,ss是關(guān)聯(lián)實體的別名

String sqlStr = "select stu.studentId as {ss.studentNumber},"

        + "stu.name as {ss.name} from "

        + "student as stu where stu.name like '楊海華'";

List l = session.createSQLQuery(sqlStr)

            //將查詢出的ss實例,關(guān)聯(lián)到Student類

            .addEntity("ss",Student.class)

            .list();

在第一個示例中,以{s.*}代表該表的全部字段,且關(guān)聯(lián)實例的別名也被指定為s。

注意:如果不使用{s.*}的形式,就可讓實體別名和表別名互不相同。關(guān)聯(lián)實體的類型時,被關(guān)聯(lián)的類必須有對應(yīng)的setter方法。

4.5.1 命名SQL查詢

可以將SQL語句不放在程序中,而放在配置文件中,這種方式以松耦合的方式配置SQL語句,可以提高程序解耦。

在Hibernate的映射文件中定義查詢名,然后確定查詢所用的SQL語句,然后就可以直接調(diào)用該命名SQL查詢。在這種情況下,不需要調(diào)用addEntity()方法,因為在配置命名SQL查詢時,已經(jīng)完成了查詢結(jié)果與實體的關(guān)聯(lián)。

下面是命名SQL查詢的配置片段:

<!-- 每個sql-query元素定義一個命名SQL查詢 -->

<sql-query name="mySqlQuery">

    <!-- 關(guān)聯(lián)返回的結(jié)果與實體類 -->

    <return alias="s" class="Student"/>

        <!-- 定義命名SQL查詢的SQL語句 -->

         SELECT {s.*}

        from student s WHERE s.name like'楊海華'

</sql-query>

sql-query元素是hibernate-mapping元素的子元素。因此,sql-query定義的名可以直接通過Session訪問,上面定義的mySqlQuery查詢可以直接訪問,下面是使用該命名SQL查詢的示例代碼:

private void testNamedSQl()

{

    //獲取Hibernate Session對象

    Session session = HibernateUtil.currentSession();

    //開始事務(wù)

    Transaction tx = session.beginTransaction();

    //調(diào)用命名查詢,直接返回結(jié)果

    List l = session.getNamedQuery("mySqlQuery")

                         .list();

    //遍歷結(jié)果集

    Iterator it = l.iterator();

    while (it.hasNext())

    {

        //在定義SQL查詢時,已經(jīng)將結(jié)果集與Student類關(guān)聯(lián)起來

        //因此,集合里的每個元素都是Student實例

        Student s = (Student)it.next();

        Set enrolments = s.getEnrolments();

        Iterator iter = enrolments.iterator();

        while(iter.hasNext())

        {

            Enrolment e = (Enrolment)iter.next();

            System.out.println("=====================================");

            System.out.println(e.getCourse().getName());

            System.out.println("=====================================");

        }

    }

    tx.commit();

    HibernateUtil.closeSession();

}

4.5.2 調(diào)用存儲過程

Hibernate 3增加了存儲過程的支持,該存儲過程只能返回一個結(jié)果集。

下面是Oracle 9i的存儲過程示例:

CREATE OR REPLACE FUNCTION selectAllEmployments

    RETURN SYS_REFCURSOR

AS

    st_cursor SYS_REFCURSOR;

BEGIN

    OPEN st_cursor FOR

SELECT EMPLOYEE, EMPLOYER,

STARTDATE, ENDDATE,

REGIONCODE, EID, VALUE, CURRENCY

FROM EMPLOYMENT;

      RETURN st_cursor;

END;

如果需要使用該存儲過程,可以先將其定義成命名SQL查詢,例如:

<!-- 定義命名SQL查詢,name屬性指定命名SQL查詢名 -->

<sql-query name="selectAllEmployees_SP" callable="true">

    <!-- 定義返回列與關(guān)聯(lián)實體類屬性之間的映射 -->

    <return alias="emp" class="Employment">

        <!-- 依次定義每列與實體類屬性的對應(yīng) -->

        <return-property name="employee" column="EMPLOYEE"/>

        <return-property name="employer" column="EMPLOYER"/>

        <return-property name="startDate" column="STARTDATE"/>

        <return-property name="endDate" column="ENDDATE"/>

        <return-property name="regionCode" column="REGIONCODE"/>

        <return-property name="id" column="EID"/>

        <!-- 將兩列值映射到一個關(guān)聯(lián)類的組件屬性 -->

        <return-property name="salary">

            <!-- 映射列與組件屬性之間的關(guān)聯(lián) -->

            <return-column name="VALUE"/>

            <return-column name="CURRENCY"/>

        </return-property>

    </return>

    { ? = call selectAllEmployments() }

</sql-query>

調(diào)用存儲過程還有如下需要注意的地方:

   ● 因為存儲過程本身完成了查詢的全部操作,所以調(diào)用存儲過程進(jìn)行的查詢無法使用setFirstResult()/setMaxResults()進(jìn)行分頁。

   ● 存儲過程只能返回一個結(jié)果集,如果存儲過程返回多個結(jié)果集,Hibernate將僅處理第一個結(jié)果集,其他將被丟棄。

   ● 如果在存儲過程里設(shè)定SET NOCOUNT ON,將有更好的性能表現(xiàn)。當(dāng)然也可以沒有該設(shè)定。

本站僅提供存儲服務(wù),所有內(nèi)容均由用戶發(fā)布,如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點擊舉報。
打開APP,閱讀全文并永久保存 查看更多類似文章
猜你喜歡
類似文章
使用Hibernate SQLQuery執(zhí)行原生SQL
hibernate SQLQuery實踐指南
hibernate原生SQL查詢,返回值映射到MAP
Hibernate使用原生SQL適應(yīng)復(fù)雜數(shù)據(jù)查詢
hibernate緩存
hibernate的緩存
更多類似文章 >>
生活服務(wù)
分享 收藏 導(dǎo)長圖 關(guān)注 下載文章
綁定賬號成功
后續(xù)可登錄賬號暢享VIP特權(quán)!
如果VIP功能使用有故障,
可點擊這里聯(lián)系客服!

聯(lián)系客服