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

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 运维知识 > 数据库 >内容正文

数据库

第 17 章 Native SQL查询

發(fā)布時間:2025/7/14 数据库 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 第 17 章 Native SQL查询 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

第?17?章?Native SQL查詢

你也可以使用你的數(shù)據(jù)庫的Native SQL語言來查詢數(shù)據(jù)。這對你在要使用數(shù)據(jù)庫的某些特性的時候(比如說在查詢提示或者Oracle中的 CONNECT關(guān)鍵字),這是非常有用的。這就能夠掃清你把原來直接使用SQL/JDBC 的程序遷移到基于 Hibernate應(yīng)用的道路上的障礙。

Hibernate3允許你使用手寫的sql來完成所有的create,update,delete,和load操作(包括存儲過程)

17.1.?創(chuàng)建一個基于SQL的Query

SQL查詢是通過SQLQuery接口來控制的,它是通過調(diào)用Session.createSQLQuery()方法來獲得

List cats = sess.createSQLQuery("select {cat.*} from cats cat").addEntity("cat", Cat.class);.setMaxResults(50);.list();

這個查詢指定了:

  • SQL查詢語句,它帶一個占位符,可以讓Hibernate使用字段的別名.

  • 查詢返回的實體,和它的SQL表的別名.

addEntity()方法將SQL表的別名和實體類聯(lián)系起來,并且確定查詢結(jié)果集的形態(tài)。

addJoin()方法可以被用于載入其他的實體和集合的關(guān)聯(lián),TODO:examples!

原生的SQL查詢可能返回一個簡單的標(biāo)量值或者一個標(biāo)量和實體的結(jié)合體。

Double max = (Double) sess.createSQLQuery("select max(cat.weight) as maxWeight from cats cat").addScalar("maxWeight", Hibernate.DOUBLE);.uniqueResult();

17.2.?別名和屬性引用

上面使用的{cat.*}標(biāo)記是 "所有屬性" 的簡寫.你可以顯式地列出需要的字段,但是你必須讓Hibernate 為每一個屬性注入字段的別名.這些字段的站位符是以字段別名為前導(dǎo),再加上屬性名.在下面的例子里,我們從一個其他的表(cat_log) 中獲取Cat對象,而非Cat對象原本在映射元數(shù)據(jù)中聲明的表.注意我們甚至在where子句中也可以使用屬性別名. 對于命名查詢,{}語法并不是必需的.你可以在第?17.3?節(jié) “命名SQL查詢”得到更多的細(xì)節(jié).

String sql = "select cat.originalId as {cat.id}, " +"cat.mateid as {cat.mate}, cat.sex as {cat.sex}, " +"cat.weight*10 as {cat.weight}, cat.name as {cat.name} " +"from cat_log cat where {cat.mate} = :catId"List loggedCats = sess.createSQLQuery(sql).addEntity("cat", Cat.class).setLong("catId", catId).list();

注意:如果你明確地列出了每個屬性,你必須包含這個類和它的子類的屬性! and its subclasses!

17.3.?命名SQL查詢

可以在映射文檔中定義查詢的名字,然后就可以象調(diào)用一個命名的HQL查詢一樣直接調(diào)用命名SQL查詢.在這種情況下,我們 需要調(diào)用addEntity()方法.

<sql-query name="mySqlQuery"><return alias="person" class="eg.Person"/>SELECT person.NAME AS {person.name},person.AGE AS {person.age},person.SEX AS {person.sex}FROM PERSON person WHERE person.NAME LIKE 'Hiber%' </sql-query> List people = sess.getNamedQuery("mySqlQuery").setMaxResults(50).list();

一個命名查詢可能會返回一個標(biāo)量值.你必須使用<return-scalar>元素來指定字段的別名和 Hibernate類型

<sql-query name="mySqlQuery"><return-scalar column="name" type="string"/><return-scalar column="age" type="long"/>SELECT p.NAME AS name,p.AGE AS age,FROM PERSON p WHERE p.NAME LIKE 'Hiber%' </sql-query>

<return-join>和<load-collection>元素分別用作 外連接和定義那些初始化集合的查詢

17.3.1.?使用return-property來明確地指定字段/別名

使用<return-property>你可以明確的告訴Hibernate使用哪些字段,這和使用{}-語法 來讓Hibernate注入它自己的別名是相反的.

<sql-query name="mySqlQuery"><return alias="person" class="eg.Person"><return-property name="name" column="myName"/><return-property name="age" column="myAge"/><return-property name="sex" column="mySex"/></return>SELECT person.NAME AS myName,person.AGE AS myAge,person.SEX AS mySex,FROM PERSON person WHERE person.NAME LIKE :name </sql-query> <return-property>也可用于多個字段,它解決了使用{}-語法不能細(xì)粒度控制多個字段的限制 <sql-query name="organizationCurrentEmployments"><return alias="emp" class="Employment"> <return-property name="salary"> <return-column name="VALUE"/><return-column name="CURRENCY"/> </return-property><return-property name="endDate" column="myEndDate"/></return>SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer}, STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},REGIONCODE as {emp.regionCode}, EID AS {emp.id}, VALUE, CURRENCYFROM EMPLOYMENTWHERE EMPLOYER = :id AND ENDDATE IS NULLORDER BY STARTDATE ASC </sql-query>

注意在這個例子中,我們使用了<return-property>結(jié)合{}的注入語法. 允許用戶來選擇如何引用字段以及屬性.

如果你映射一個識別器(discriminator),你必須使用<return-discriminator>來指定識別器字段

17.3.2.?使用存儲過程來查詢

Hibernate 3引入了對存儲過程查詢的支持. 存儲過程必須返回一個結(jié)果集,作為Hibernate能夠使用的第一個外部參數(shù). 下面是一個Oracle9和更高版本的存儲過程例子.

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;

在Hibernate里要要使用這個查詢,你需要通過命名查詢來映射它.

<sql-query name="selectAllEmployees_SP" callable="true"><return alias="emp" class="Employment"><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"/> <return-property name="salary"> <return-column name="VALUE"/><return-column name="CURRENCY"/> </return-property></return>{ ? = call selectAllEmployments() } </sql-query>

注意存儲過程當(dāng)前僅僅返回標(biāo)量和實體.現(xiàn)在不支持<return-join>和<load-collection>

17.3.2.1.?使用存儲過程的規(guī)則和限制

為了在Hibernate中使用存儲過程,你必須遵循一些規(guī)則.不遵循這些規(guī)則的存儲過程將不可用.如果你仍然想要使用他們, 你必須通過session.connection()來執(zhí)行他們.這些規(guī)則針對于不同的數(shù)據(jù)庫.因為數(shù)據(jù)庫 提供商有各種不同的存儲過程語法和語義.

對存儲過程進(jìn)行的查詢無法使用setFirstResult()/setMaxResults()進(jìn)行分頁。

對于Oracle有如下規(guī)則:

  • 存儲過程必須返回一個結(jié)果集.它通過返回SYS_REFCURSOR實現(xiàn)(在Oracle9或10),在Oracle里你需要定義一個REF CURSOR 類型

  • 推薦的格式是 { ? = call procName(<parameters>) } 或 { ? = call procName }(這更像是Oracle規(guī)則而不是Hibernate規(guī)則)

對于Sybase或者M(jìn)S SQL server有如下規(guī)則:

  • 存儲過程必須返回一個結(jié)果集。.注意這些servers可能返回多個結(jié)果集以及更新的數(shù)目.Hibernate將取出第一條結(jié)果集作為它的返回值, 其他將被丟棄。

  • 如果你能夠在存儲過程里設(shè)定SET NOCOUNT ON,這可能會效率更高,但這不是必需的。

17.4.?定制SQL用來create,update和delete

Hibernate3能夠使用定制的SQL語句來執(zhí)行create,update和delete操作。在Hibernate中,持久化的類和集合已經(jīng) 包含了一套配置期產(chǎn)生的語句(insertsql, deletesql, updatesql等等),這些映射標(biāo)記 <sql-insert>, <sql-delete>, and <sql-update>重載了 這些語句。

<class name="Person"><id name="id"><generator class="increment"/></id><property name="name" not-null="true"/><sql-insert>INSERT INTO PERSON (NAME, ID) VALUES ( UPPER(?), ? )</sql-insert><sql-update>UPDATE PERSON SET NAME=UPPER(?) WHERE ID=?</sql-update><sql-delete>DELETE FROM PERSON WHERE ID=?</sql-delete> </class>

這些SQL直接在你的數(shù)據(jù)庫里執(zhí)行,所以你可以自由的使用你喜歡的任意語法。但如果你使用數(shù)據(jù)庫特定的語法, 這當(dāng)然會降低你映射的可移植性。

如果設(shè)定callable,則能夠支持存儲過程了。

<class name="Person"><id name="id"><generator class="increment"/></id><property name="name" not-null="true"/><sql-insert callable="true">{call createPerson (?, ?)}</sql-insert><sql-delete callable="true">{? = call deletePerson (?)}</sql-delete><sql-update callable="true">{? = call updatePerson (?, ?)}</sql-update> </class>

參數(shù)的位置順序是非常重要的,他們必須和Hibernate所期待的順序相同。

你能夠通過設(shè)定日志調(diào)試級別為org.hiberante.persister.entity,來查看Hibernate所期待的順序。在這個級別下, Hibernate將會打印出create,update和delete實體的靜態(tài)SQL。如果想看到預(yù)想中的順序。記得不要將定制SQL包含在映射文件里, 因為他們會重載Hibernate生成的靜態(tài)SQL。

在大多數(shù)情況下(最好這么做),存儲過程需要返回插入/更新/刪除的行數(shù),因為Hibernate對語句的成功執(zhí)行有些運行時的檢查。 Hibernate常會把進(jìn)行CUD操作的語句的第一個參數(shù)注冊為一個數(shù)值型輸出參數(shù)。

CREATE OR REPLACE FUNCTION updatePerson (uid IN NUMBER, uname IN VARCHAR2)RETURN NUMBER IS BEGINupdate PERSONsetNAME = uname,whereID = uid;return SQL%ROWCOUNT;END updatePerson;

17.5.?定制裝載SQL

你可能需要聲明你自己的SQL(或HQL)來裝載實體

<sql-query name="person"><return alias="p" class="Person" lock-mode="upgrade"/>SELECT NAME AS {p.name}, ID AS {p.id} FROM PERSON WHERE ID=? FOR UPDATE </sql-query>

這只是一個前面討論過的命名查詢聲明,你可以在類映射里引用這個命名查詢。

<class name="Person"><id name="id"><generator class="increment"/></id><property name="name" not-null="true"/><loader query-ref="person"/> </class>

這也可以用于存儲過程

TODO: 未完成的例子

<sql-query name="organizationEmployments"><load-collection alias="empcol" role="Organization.employments"/>SELECT {empcol.*}FROM EMPLOYMENT empcolWHERE EMPLOYER = :idORDER BY STARTDATE ASC, EMPLOYEE ASC </sql-query><sql-query name="organizationCurrentEmployments"><return alias="emp" class="Employment"/><synchronize table="EMPLOYMENT"/>SELECT EMPLOYEE AS {emp.employee}, EMPLOYER AS {emp.employer},STARTDATE AS {emp.startDate}, ENDDATE AS {emp.endDate},REGIONCODE as {emp.regionCode}, ID AS {emp.id}FROM EMPLOYMENTWHERE EMPLOYER = :id AND ENDDATE IS NULLORDER BY STARTDATE ASC </sql-query>

轉(zhuǎn)載于:https://www.cnblogs.com/nieshanfeng/archive/2011/08/23/2151265.html

總結(jié)

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

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

主站蜘蛛池模板: 精品国产乱码久久久久久108 | 亚洲精品乱码久久久久久日本蜜臀 | 青青青免费在线 | 777色婷婷| 欧美男同又粗又长又大 | 免费看a网站 | 国产日韩欧美中文 | 最新国产拍偷乱偷精品 | 毛片手机在线 | 精品99久久 | 大肉大捧一进一出好爽视频 | 激情四月 | 色网站免费观看 | av中字| 性欧美色图 | 美女露胸露尿口 | 日本一本久 | 性の欲びの女javhd | 丰满秘书被猛烈进入高清播放在 | 色综合加勒比 | 91资源在线播放 | 人人看人人射 | 99国产精品久久久久久久成人热 | 白嫩情侣偷拍呻吟刺激 | 欧美极品三级 | 亚洲九区 | 黄色精品视频 | 青青草娱乐在线 | fee性满足he牲bbw| 成人日韩在线 | 日韩黄色短视频 | 韩毛片 | 国产黄色www | 欧美在线资源 | 视频在线观看免费大片 | 成人久色 | 青娱乐精品视频 | 黄色精品视频 | 日韩综合中文字幕 | 日本久久综合 | 久久精品在这里 | 麻豆精品国产 | 久久精品色妇熟妇丰满人妻 | 在线播放精品 | 黄色片a级 | 久久久久久av无码免费看大片 | 一区二区三区av在线 | 欧美精品一级 | 高清视频在线免费观看 | 国产三级麻豆 | 另类欧美亚洲 | 成人免费av片 | 久久av资源网 | 黄色精品一区二区 | 91精彩视频在线观看 | 日韩中文一区二区三区 | 大乳女喂男人吃奶视频 | 成年人在线观看视频免费 | 影音先锋在线国产 | 美女啪啪一区二区 | 久久久新 | 一区二区三区av | 国产午夜在线一区二区三区 | 蜜臀aⅴ国产精品久久久国产老师 | 一区二区三区激情 | 激情区 | 精品人妻无码一区二区三区蜜桃一 | 精品人妻一区二区三区含羞草 | 一级免费黄色 | 日本黄色天堂 | 国产一卡二卡在线播放 | 成熟丰满熟妇高潮xxxxx视频 | 天天干天天草天天射 | 亚洲三区在线 | 波多野结衣在线播放视频 | 青青青操| 波多野结衣乳巨码无在线观看 | 日韩美女一区 | 青青视频免费看 | 亚洲在线视频网站 | 999毛片| 中文字幕啪啪 | 夜夜嗨av一区二区 | 亚洲精品久久久久avwww潮水 | 色婷婷热久久 | 亚洲二区在线观看 | 日韩av在线中文字幕 | 天堂√在线 | www日本在线 | 97毛片| av观看网站| 国产精品一卡 | 黄色三级av | 在线h网 | 国产日韩视频在线观看 | 国产freexxxx性播放麻豆 | av在线资源网 | 毛片无遮挡高清免费观看 | 亚洲欧美视频在线播放 |