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

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

iBATIS In Action:使用映射语句(二)

發布時間:2024/1/17 编程问答 39 豆豆
生活随笔 收集整理的這篇文章主要介紹了 iBATIS In Action:使用映射语句(二) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

IDictionary,則property是相應key的名稱。同一property值可以出現多次,這取決于它在語句中出現的次數。

column

用于定義存儲過程的參數名稱。

direction

可用于指定存儲過程參數的方向。其值可以是InputOutputInputOutput。

dbType

用于顯式地指定參數對應的列類型。對于某些操作,一些ADO.NET provider不能判斷列的類型,此時dbType必須指定。

此特性僅在列為nullable時是必需的。此外,在顯式指定日期類型時也需要此特性。盡管.NET僅有一種日期值類型(System.DateTime),大多數數據庫卻不止一個。通常情況下,數據庫至少有三種不同的日期類型(DateDateTimeTimeStamp)。為使映射過程能夠正確,我們可能需要指定列的dbType。

type

用于指定前面的propertyCLR類型。在向存儲過程傳入InputOputOutput類型的參數時,該特性很有用。

正常情況下,property的類型可通過反射獲得,但對于IDictionary類型的參數就無能為力了,此時類型被假定為Object。

nullValue

nullValue可以設置為任何的有效值(這取決于property的類型)。

注意:對于值類型(intdoubledatetime等)的屬性,它們是不能為null的,那如何向數據庫中插入null值呢?可以采用nullValue,比如對于Age列(int類型),我們可以指定nullValue0,這意味著如果該屬性未設置(C#中,int屬性的默認值為0),那么會向數據庫插入NULL。在.NET2.0中也可以使用nullable類型,此時更為方便。請參考我的小文。

size

設置列的最大尺寸。

precision

設置數字值的精度。

scale

設置小數的位數。

typeHandler

用于自定義類型處理器(Custom Type Handler)。

內聯參數在多數情況下效果不錯。如果您希望改善性能,或者遇到了意外的情況,外部參數可能就用得上了。在第5章中,我們會更全面地討論外部參數,在這里,暫不需要。

4.3.2?重溫內聯參數

如果您更喜歡使用內聯參數,同樣可以為參數指定更多的信息,如屬性的類型,類的類型以及null值替換(即nullValue特性)。看下面四個例子:

<statement?id="insertProduct"?parameterClass="Product">
????insert?into?PRODUCT?(PRD_ID,?PRD_DESCRIPTION)
????values?(#id#,?#description#)
</statement>

這是最簡單的情況,下面這個例子指定了dbType:

<statement?id="insertProduct"?parameterClass="Product">
????insert?into?PRODUCT?(PRD_ID,?PRD_DESCRIPTION)
????values?(#id:int#,?#description:VarChar#)
</statement>

下面這個例子指定了nullValue:

<statement?id="insertProduct"?parameterClass="Product">
????insert?into?PRODUCT?(PRD_ID,?PRD_DESCRIPTION)
????values?(#id:int:-999999#,?#description:VarChar#)
</statement>

類似于Java中的DataMapper,內聯參數還有另外一種語法,使用逗號。

<update?id="UpdateAccountViaInlineParameters"?parameterClass="Account">
????update?Accounts?set
????Account_FirstName?=?#FirstName#,
????Account_LastName?=?#LastName#,
????Account_Email?=?#EmailAddress,type=string,dbType=Varchar,nullValue=no_email@provided.com#
????where
????Account_ID?=?#Id#
</update>

4.3.3?標準類型的參數(standard type parameter

在實際開發中,我們會發現很多語句只接受單個參數,通常為int或string。此時并不需要將其封裝在另一個對象中,直接使用標準庫對象(string, int等)就可以了,下面是一個例子:?

<statement?id="getProduct"?parameterClass="System.Int32">
????select?*?from?PRODUCT?where?PRD_ID?=?#value#
</statement>

假定PRD_ID為數字類型,在調用該語句時,可以傳入一個標準的int對象。#value#參數會替換為傳入的int值。此處的value僅僅是一個占位符,您可以根據需要將其替換為其它名稱。

為方便起見,iBATIS框架提供了基元類型的別名,比如,int可用于代替System.Int32。要了解這些別名的完整內容,請參考iBATIS.NET的官方文檔。

4.3.4 IDictionary類型的參數

<statement?id="getProduct"?parameterClass="System.Collections.IDictionary">
????select?*?from?PRODUCT
????where?PRD_CAT_ID?=?#catId#
????and?PRD_CODE?=?#code#
</statement>

我們也可以使用IDictionary類型的對象作為參數。通??梢允褂肏ashtable??聪旅娴睦?#xff1a;

看看這條語句,跟前面出現的沒有什么不同。如果傳入的對象是Hashtable類型,它必須要包含有名稱為catId和code的鍵,而鍵所對應的值必須要適合于列的類型,這些要求與使用普通的對象是一樣的。

為方便起見,iBATIS框架也提供了IDictionary類型的別名。因此,可以用map或hashtable來代替System.Collections.Hashtable。要了解這些別名的完整內容,請參考iBATIS.NET的官方文檔。

OK,至此我們已經知道了如何輸入參數了,下面就來看看如何獲取輸出值了。

4.4結果映射(result map

Result Map將從數據庫查詢所得的結果映射到對象的屬性。在使用映射語句時,Result Map是我們要理解的最常用也是最重要的特性之一。

通過Result Map我們可以控制如何從查詢結果中獲取數據,以及列是如何映射到對象的屬性的。Result Map可以描述列的類型、null值的替換以及復雜屬性(包括集合)的映射。

4.4.1?擴展Result Map

可選的extends特性值可以設置為另一個Result Map的名稱,這樣就可以復用指定Result Map的映射方式了。“父級”Result Map的所有屬性都將作為當前Result Map的一部分,“父級”Result Map的值在當前Result Map之前進行設置,其效果類似于類的繼承。

提示:“父級”Result Map必須在“子級”Result Map之前定義。

4.4.2 <resultMap>的特性

<resultMap>接受三個特性:

特性

描述

id

必需的,為Result Map提供唯一標識。

class

可選的,指定當前Result Map使用的類??梢栽O置為類的完整名稱或別名。

extends

可選的,指定要進行“繼承”的Result Map

4.4.3 <constructor>元素

<constructor>元素必須與result class的構造函數簽名相匹配。如果指定了此元素,iBATIS用它來實例化結果對象(result object)。

4.4.4 <result>元素

<resultMap>元素包含一個或多個<result>子元素,用以將執行SQL的結果集映射至對象的屬性。

特性

描述

property

必需的,表示結果對象的屬性名稱。

column

必需的,指定結果集中的列名稱,使用該列來產生當前屬性。

columnIndex

可選的,指定列的索引,該特性對性能會有輕微的幫助99%的應用程序中是不需要的,而且它還會犧牲可維護性和可讀性。另外一些provider中,該特性可能對性能沒有任何幫助。

dbType

用于顯式地指定列的類型。由于CLR和數據庫中類型的不一致,該特性比較有用,尤其是對datetimestring類型。

type

用于顯式地指定結果對象屬性的CLR類型。通常屬性的類型可通過反射獲得,但在映射到Hashtable之類的對象時就無能為力了。

resultMapping

該特性的值可以設置為另一個Result Map的名稱,借助后者來填充屬性。如果使用的Result Map位于另一個文件中,則必須要使用它的完全限定名稱(加上命名空間)。

nullValue

用于指定null值的替代值,該特性可以設置為任何有效的值(取決于屬性的類型)。如果屬性類型為值類型,則其值不可能為null,如果列的值為null,那么通過該特性可以將屬性設定為某個常量值。另一方面,如果屬性可以為null,我們可能想用某個常量值而不是null來表示它,這個時候nullValue特性也是有用的。

select

用于描述對象間的關系,并自動加載復雜類型(即用戶定義類型)。其值必須為另一映射語句的名稱。

lazyLoad

聯合使用lazyLoadselect特性,可以指定select特性所指定語句的結果是否要延遲加載。延遲加載對IListIList<>的支持是透明的,對強類型的集合類的支持則需要Castle.DynamicProxy組件。

typeHandler

允許使用自定義類型處理器(Custom Type Handler)。這樣就可以擴展DataMapper的能力,來處理那些provider特定的類型或者是provider不支持的類型。

代碼示例:nullValue的使用

<resultMap?id="get-product-result"?class="product">
????
<result?property="id"?column="PRD_ID"/>
????
<result?property="description"?column="PRD_DESCRIPTION"/>
????
<result?property="subCode"?column="PRD_SUB_CODE"?nullValue="-9999"?/>
</resultMap>

注意:如果PRD_SUB_CODE列的值為null,則subCode屬性的值將設置為-9999。記住,在插入/更新數據時,Parameter Map的nullValue特性也要進行設置,這樣才能一致。實際上有了nullable類型后,該特性可以不使用了。

4.4.5?隱式的結果映射

如果SQL語句返回的列與結果對象的屬性相匹配,那么顯式的Result Map就不再必要了。在下面的例子中,列的名稱和屬性的名稱已然匹配,因此無需聲明Result Map。

<statement?id="selectProduct"?resultClass="Product">
????select
????id,
????description
????from?PRODUCT
????where?id?=?#value#
</statement>

但是,如果列的名稱和屬性名稱不一致,而列名不可能修改(比如使用其它公司開發的數據庫),那該怎么辦呢?可以使用列的別名,看下例:

<statement?id="selectProduct"?resultClass="Product">
????select
????PRD_ID?as?id,
????PRD_DESCRIPTION?as?description
????from?PRODUCT
????where?PRD_ID?=?#value#
</statement>

當然,此時就不能指定dbType、nullValue或者其它的特性了(不要太貪心…)。

區分大小寫是隱式Result Map的另一個問題。誠然,我們可為一個類同時定義“FirstName”和“Firstname”兩個屬性,在iBATIS進行映射時,它就不能保證是匹配哪個屬性了(當然了,沒幾個開發人員會定義這樣相近的兩個屬性)。

最后,隱式Result Map會有性能損失,如果我們使用第三方的.NET數據庫provider,而它又對ResultSetMetaData支持很差,那損失就更明顯了。

4.4.6?返回基元類型的結果(如string,int等)

很多時候,并不需要返回一個具有多個屬性的對象,我們需要的僅僅是單個的string,int,bool等類型的值。這時,您可以指定標準類型作為結果類型,如:

<select?id="selectProductCount"?resultClass="System.Int32">
????select?count(*)?from?PRODUCT
</select>

結果類型也可使用iBATIS框架提供的別名,比如,int可用于代替System.Int32。要了解這些別名的完整內容,請參考iBATIS.NET的官方文檔。

4.4.7?返回IDictionary類型的結果

有些時候我們需要的只是包含數據的鍵/值列表。Result Map可以生成一個IDictionary類型的實例,其語法與普通的POCO對象一樣:

<resultMap?id="select-product-result"?class="hashtable">
????
<result?property="id"?column="PRD_ID"/>
????
<result?property="code"?column="PRD_CODE"/>
????
<result?property="description"?column="PRD_DESCRIPTION"/>
????
<result?property="suggestedPrice"?column="PRD_SUGGESTED_PRICE"/>
</resultMap>

在這個例子中,iBATIS會為每一行創建一個Hashtable實例,這個實例包含了返回的數據,屬性名id、code等均作為Hashtable的key,列的值則作為Hashtable的值。

也可以使用IDictionary類型作為隱式的Result Map:

<statement?id="selectProductCount"?resultClass="hashtable">
????select?*?from?PRODUCT
</statement>

Hashtable包含的值取決于列的值。如果列發生了變化(比如添加或刪除了列),返回的結果也會隨之發生變化。

注意:某些provider可能將返回的列名稱定為大寫或小寫,此時要注意使用正確的key名稱。

4.5?小結

在本章中,我們探討了POCO,SQL Map的API,映射語句。隨著您對這些內容的熟悉,創建映射語句也會越來越簡單,就像其它任何事情一樣,熟能生巧。

如果您希望盡可能地減少運行時的錯誤,就要顯式聲明!使用顯式的參數和結果映射,并且要使用強類型的對象。這樣,您的程序會啟動更快(因為iBATIS會嘗試推導所有內容),運行更快,使用的內存更少。

在下章中,我們將研究iBATIS支持的非查詢語句,屆時,我們就能夠了解數據庫維護所需的各種基本操作了。

點擊這里下載示例代碼(數據庫為Northwind,請修改SqlMap.config中的配置)。

下一篇:iBATIS In Action:執行非查詢語句(一);


本文轉自一個程序員的自省博客園博客,原文鏈接:http://www.cnblogs.com/anderslly/archive/2007/11/04/ibatisusingmappedstatement02.html,如需轉載請自行聯系原作者。

總結

以上是生活随笔為你收集整理的iBATIS In Action:使用映射语句(二)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。