日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

Hibernate sql查询

發(fā)布時(shí)間:2024/4/17 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Hibernate sql查询 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

http://www.cnblogs.com/kelin1314/archive/2010/09/09/1821897.html

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

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

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

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

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

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

但SQLQuery比Query多了兩個(gè)重載的方法:

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

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

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

(1)獲取Hibernate Session對(duì)象;

(2)編寫SQL語句;

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

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

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

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

看下面的SQL查詢示例:

private void test()

{

??? //獲取Hibernate Session對(duì)象

??? 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對(duì)象

??? List l = session.createSQLQuery(sqlString)

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

??????????????????? .addEntity("s",Student.class)

??????????????????? //返回全部的記錄集

??????????????????? .list();

??? //遍歷結(jié)果集

??? Iterator it = l.iterator();

??? while (it.hasNext())

??? {

??????? //因?yàn)閷⒉樵兘Y(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)成一個(gè)實(shí)體的示例。事實(shí)上,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();

或者:
  • StringBuffer queryStr =?new?StringBuffer(); ??
  • queryStr.append("select count(*) AA,"); ??
  • queryStr.append("sum(st.num1) BB,sum(st.num2) CC,"); ??
  • queryStr.append("max(st.cost1) DD,min(st.cost2) EE,"); ??
  • queryStr.append("st.col1 FF from TBXXX st") ??
  • .append(" where ") ??
  • .append(SQLQuerySetup.createfilterStr(filter)) ??
  • .append(" group by st.col1"); ??
  • ??
  • query = session.createSQLQuery(queryStr.toString()); ??
  • query.addScalar("AA",?new?org.hibernate.type.IntegerType()); ??
  • query.addScalar("BB",?new?org.hibernate.type.IntegerType()); ??
  • query.addScalar("CC",?new?org.hibernate.type.IntegerType()); ??
  • query.addScalar("DD",?new?org.hibernate.type.IntegerType()); ??
  • query.addScalar("EE",?new?org.hibernate.type.IntegerType()); ??
  • query.addScalar("FF",?new?org.hibernate.type.IntegerType()); ??
  • return?query.list();??
  • 注意2個(gè)問題?
    1.Query 沒有addScalar()方法,使用SQLQuery才有addScalar()方法?
    2.如果查詢的結(jié)果集的字段為id,count(*) as count,則如果只?
    addScalar("count",type),將得不到id的值,需要加上addScalar("id",type),也就是要把每一個(gè)字段都要addScalar()

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

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

    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實(shí)例,關(guān)聯(lián)到Student類

    ??????????? .addEntity("ss",Student.class)

    ??????????? .list();

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

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

    4.5.1 命名SQL查詢

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

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

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

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

    <sql-query name="mySqlQuery">

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

    ??? <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對(duì)象

    ??? 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查詢時(shí),已經(jīng)將結(jié)果集與Student類關(guān)聯(lián)起來

    ??????? //因此,集合里的每個(gè)元素都是Student實(shí)例

    ??????? 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)用存儲(chǔ)過程

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

    下面是Oracle 9i的存儲(chǔ)過程示例:

    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;

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

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

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

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

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

    ??????? <!-- 依次定義每列與實(shí)體類屬性的對(duì)應(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"/>

    ??????? <!-- 將兩列值映射到一個(gè)關(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)用存儲(chǔ)過程還有如下需要注意的地方:

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

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

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

    ?

    總結(jié)

    以上是生活随笔為你收集整理的Hibernate sql查询的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。