NHibernate之(15):探索NHibernate中使用儲存過程(上)
本節內容
- 引入
- 使用MyGeneration生成儲存過程
- 例項分析
- 1.刪除物件
- 結語
返回文章列表
引入
上一篇,我們介紹了檢視,徵集大家的意見,我接下來可能用三篇篇幅來介紹在NHibernate中如何使用儲存過程的整個詳細過程,這些全是在實際運用中積累的經驗,涉及剛剛使用的錯誤資訊,如何修改儲存過程,並且比較沒有使用儲存過程的不同點,並非官方比較權威的資料,所以敬請參考。
使用MyGeneration生成儲存過程
由於寫儲存過程不是這節的重點,我們來利用MyGeneration程式碼生成工具來利用為Customer表生成插入、更新、刪除記錄的儲存過程。順便也來學習MyGeneration開源的生成器怎麼用的,如果你還沒有,請到
安裝完之後,開啟MyGeneration,如果你第一次使用MyGeneration會自動彈出“預設設定”對話方塊,需要你對MyGeneration設定資料庫連線字串、模板語言、資料庫驅動、模板存放路徑等資訊,截圖如下(由於這篇圖片比較多,點選圖片放大):
我們要首先配置資料庫連線字串,如果你對手寫感興趣,你可以直接在文字框中修改具體字串;如果你和我一樣,就點選“OLEDB...”按鈕利用介面配置連線字串,點選按鈕之後,出來“資料連線屬性”對話方塊,中文的哦,MyGeneration直接呼叫SQL Server的配置對話方塊,按下面圖示,填寫自己的連線字串資訊:
然後點選“確定”,這個對話方塊的連線資訊將儲存在“預設配置”對話方塊中,點選“Save”儲存配置資訊。
這時,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!