1. 程式人生 > 實用技巧 >NHibernate之(15):探索NHibernate中使用儲存過程(上)

NHibernate之(15):探索NHibernate中使用儲存過程(上)

本節內容

  • 引入
  • 使用MyGeneration生成儲存過程
  • 例項分析
    • 1.刪除物件
  • 結語

    返回文章列表

引入

上一篇,我們介紹了檢視,徵集大家的意見,我接下來可能用三篇篇幅來介紹在NHibernate中如何使用儲存過程的整個詳細過程,這些全是在實際運用中積累的經驗,涉及剛剛使用的錯誤資訊,如何修改儲存過程,並且比較沒有使用儲存過程的不同點,並非官方比較權威的資料,所以敬請參考。

使用MyGeneration生成儲存過程

由於寫儲存過程不是這節的重點,我們來利用MyGeneration程式碼生成工具來利用為Customer表生成插入、更新、刪除記錄的儲存過程。順便也來學習MyGeneration開源的生成器怎麼用的,如果你還沒有,請到

這裡下載安裝。

安裝完之後,開啟MyGeneration,如果你第一次使用MyGeneration會自動彈出“預設設定”對話方塊,需要你對MyGeneration設定資料庫連線字串、模板語言、資料庫驅動、模板存放路徑等資訊,截圖如下(由於這篇圖片比較多,點選圖片放大):

我們要首先配置資料庫連線字串,如果你對手寫感興趣,你可以直接在文字框中修改具體字串;如果你和我一樣,就點選“OLEDB...”按鈕利用介面配置連線字串,點選按鈕之後,出來“資料連線屬性”對話方塊,中文的哦,MyGeneration直接呼叫SQL Server的配置對話方塊,按下面圖示,填寫自己的連線字串資訊:

然後點選“確定”,這個對話方塊的連線資訊將儲存在“預設配置”對話方塊中,點選“Save”儲存配置資訊。

MyGeneration使用提示

如果你的作業系統是Windows Vista,請右擊“以管理員身份執行”MyGeneration,這一點我還是比較鬱悶的,弄了很久MyGeneration配置資訊和模板儲存失敗,後來換成以管理員身份執行問題全部解決。

這時,MyGeneration主介面就打開了,點選工具欄的第三個按鈕,開啟“模板瀏覽器”視窗,截圖如下:

展開Microsoft SQL Server節點,找到“Script Insert/Update/Delete Procedures for SQL Server”模板,右擊選擇執行,我們利用這個模板為Customer表生成增刪改儲存過程。

開啟後,這個模板介面如下,選擇輸出路徑和資料庫表,這裡我輸入路徑為桌面,選擇Customer表,點選OK。截圖如下:

這時在桌面上生成sql_procs_Customer.sql檔案,開啟SQL Server Management Studio執行這個SQL指令碼,展開NHibernateSample表下的儲存過程,已經出來了三個儲存過程,分別是CustomerDelete、CustomerInsert、CustomerUpdate。

好了,我們使用MyGeneration生成儲存過程,這個工作完成了,但是噩夢開始了......

例項分析

還是一步一步來,依次從刪除物件、新建物件、更新物件、查詢物件來介紹在NHibernate中如何使用儲存過程的整個詳細過程。在NHibernate的對映檔案中,在Class元素中提供了<sql-delete>、<sql-insert>、<sql-update>元素用於刪除、新建、更新物件,注意這三個元素順序唯一,就是下圖顯示的順序,在根元素提供了<sql-query>元素用來查詢物件,下圖顯示在Class元素中的增刪改儲存過程元素。

1.刪除物件

這篇資料訪問層中程式碼我們使用NHibernate之旅(6):探索NHibernate中的事務中的程式碼,測試程式碼在NHibernate之旅(5):探索Insert, Update, Delete操作中體現,無需任何改動。

Step1:為了比較,我們先執行DeleteCustomerTest()測試方法,沒有使用儲存過程下刪除物件生成SQL語句如下:

DELETE FROM Customer WHERE CustomerId = @p0 AND Version = @p1; @p0 = '7', @p1 = '1'

Step2:修改對映檔案新增儲存過程,開啟Customer.hbm.xml對映檔案,在Class元素下新增<sql-delete>節點,呼叫CustomerDelete儲存過程,CustomerDelete儲存過程有一個CustomerId引數,這裡用一個問號表示:

<sql-delete>exec CustomerDelete ?</sql-delete>

Step3:執行DeleteCustomerTest()測試方法,出現錯誤“NHibernate.StaleObjectStateException : Row was updated or deleted by another transaction (or unsaved-value mapping was incorrect): [DomainModel.Entities.Customer#4]”,這個錯誤是儲存過程寫法錯誤,我們修改CustomerDelete儲存過程,去掉SET NOCOUNT ON,程式碼片段如下:

ALTER PROCEDURE [dbo].[CustomerDelete]
(
    @CustomerId int
)
AS
    --SET NOCOUNT ON
    DELETE 
    FROM   [Customer]
    WHERE  
        [CustomerId] = @CustomerId
    RETURN @@Error

Step4:執行DeleteCustomerTest()測試成功,NHibernate生成語句如下:

exec CustomerDelete @p0; @p0 = '6', @p1 = '1'

恩,成功了,但是在看看儲存過程,想想儲存過程中寫的SQL語句,和沒有使用儲存過程,NHibernate生成的SQL語句有些不同,顯然沒有顧及到版本控制問題,使用儲存過程NHibernate生成語句無緣無故增加了一個引數@p1,我們來解決一下:

Step5:修改儲存過程新增Version處理

ALTER PROCEDURE [dbo].[CustomerDelete]
(
    @CustomerId int,
    @Version int
)
AS
    DELETE 
    FROM   [Customer]
    WHERE  
    [CustomerId] = @CustomerId and [Version] = @Version
    RETURN @@Error

Step6:執行DeleteCustomerTest()測試,發生錯誤:“過程或函式 'CustomerDelete' 需要引數 '@Version',但未提供該引數。” 哦,原來對映檔案引數數量沒有改。

Step7:修改儲存過程引數數量,開啟對映檔案在<sql-delete>中新增一個引數即新增“,?”

<sql-delete>exec CustomerDelete ?,?</sql-delete>

Step8:最後執行DeleteCustomerTest()測試成功,NHibernate生成SQL語句如下,和NHibernate沒有使用儲存過程一樣了,考慮了版本控制問題,完全符合。OK!!

exec CustomerDelete @p0,@p1; @p0 = '8', @p1 = '1'

當然了,如果你不想使用儲存過程,也可以直接在<sql-delete>中寫SQL語句,像這樣,照樣用。

<sql-delete>DELETE FROM [Customer] WHERE [CustomerId] = ? and [Version] =?</sql-delete>

結語

這篇就說到這裡了,主要學習怎麼使用MyGeneration提供的模板建立儲存過程和刪除物件儲存過程的使用,下篇繼續建立、更新、查詢物件儲存過程的使用。

本系列連結:NHibernate之旅系列文章導航

NHibernate Q&A

下次繼續分享NHibernate!