iBATIS.NET API基礎(chǔ)淺析
有了對iBATIS.NET配置系統(tǒng)的一些認(rèn)識后,現(xiàn)在就先來簡單了解一下,iBATIS.NET是通過什么的方式去調(diào)用映射文件的SQL語句的。這對我們接下來深入了解有很大的幫助。
對于簡單的iBatis應(yīng)用場合來說,我想大部分都是集中在與SqlMapper對象打交道。這個(gè)類應(yīng)該說是一個(gè)工具類,因?yàn)槲覀円话愣际侵苯诱{(diào)用這個(gè)類的方法去執(zhí)行QUID操作,但是它卻不是真正的去做這些事情。因?yàn)閕Batis內(nèi)部有很多的類,對象之間的關(guān)系是非常復(fù)雜的,如果讓客戶直接去使用它內(nèi)部方法,無疑增加了使用的復(fù)雜性,同樣也會產(chǎn)生很多的冗余代碼。因此這里它使用外觀設(shè)計(jì)模式,通過SqlMapper類封裝了iBatis執(zhí)行數(shù)據(jù)庫訪問的復(fù)雜操作,包括打開一個(gè)會話(Session),獲取返回IMappedStatement對象實(shí)例,執(zhí)行數(shù)據(jù)庫訪問,關(guān)閉連接等相關(guān)操作。這樣我們在使用iBatis API的時(shí)候就可以非常簡單調(diào)用的一個(gè)方法,就可以做所有的事情了。比如查詢接口public IList QueryForList(string statementName, object parameterObject),它的內(nèi)部實(shí)現(xiàn)代碼是這樣的。
- IList list1;
- bool flag1 = false;
- IDalSession session1 = this._sessionHolder.LocalSession;
- if (session1 == null)
- {
- session1 = new SqlMapSession(this.DataSource);
- session1.OpenConnection();
- flag1 = true;
- }
- IMappedStatement statement1 = this.GetMappedStatement(statementName);
- try
- {
- list1 = statement1.ExecuteQueryForList(session1, parameterObject);
- }
- catch
- {
- throw;
- }
- finally
- {
- if (flag1)
- {
- session1.CloseConnection();
- }
- }
- return list1;
那這些代碼如果直接在客戶代碼中去實(shí)現(xiàn),可想而知工作量會有多大。并且還法保證正確性。
以上簡單看了一個(gè)SqlMapper的作用,那該怎樣實(shí)例化這個(gè)對象呢?實(shí)例化它也是一個(gè)非常簡單的事情。在iBATIS.NET中,SqlMapper對象默認(rèn)是一個(gè)單件模式的實(shí)現(xiàn)。通過Mapper類的靜態(tài)Instance屬性來實(shí)例化一個(gè)SqlMapper對象。這樣的設(shè)計(jì)可能有一部分是出于性能方面的考慮。因?yàn)樵诔跏蓟疭qlMapper對象,需要初始iBatis運(yùn)行環(huán)境配置,讀取和初步解析包含的各個(gè)映射文件,所以在在系統(tǒng)運(yùn)行時(shí)第一次調(diào)用iBATIS.NET API的時(shí)候,可能會需要比較長來處理這個(gè)配置。Mapper.Instance屬性的實(shí)現(xiàn)如下:
- public static SqlMapper Instance()
- {
- if (Mapper._mapper == null)
- {
- lock (typeof(SqlMapper))
- {
- if (Mapper._mapper == null)
- {
- Mapper.InitMapper();
- }
- }
- }
- return Mapper._mapper;
- }
所以在使用API的時(shí)候可以像下面的這么簡單:
- Mapper.Instance().Insert("ContentObject_DefaultInsert", p_dataObject);
當(dāng)然,如果愿意而且有必要的話,也完全可以由自己來實(shí)例化這個(gè)對象,我們可以直接使用DomSqlMapBuilder,它為我們提供這樣的擴(kuò)展能力,通過它的多種實(shí)例方法都可以返回出SqlMapper對象:Build,Configure,ConfigureAndWatch。在需要用到多個(gè)數(shù)據(jù)庫或是多種不同數(shù)據(jù)庫類型的場合下,這種方法是非常有用的。
注意:在使用一個(gè)接口時(shí),使用的statementName要在對應(yīng)類型的statement類型。比如在使用Insert接口時(shí),如果你指定的是一個(gè)select類型配置語句的話,那將會拋出異常。因?yàn)槊恳环Nstatement類型都對應(yīng)一種類型,比如如select 類型的配置語句對應(yīng)的是SelectMappedStatement類,它是從MappedStatement繼承下來,而它的ExcuteInsert方法是這樣實(shí)現(xiàn)的
- public override object ExecuteInsert(IDalSession session, object parameterObject)
- {
- throw new DataMapperException("Update statements cannot be executed as a query insert.");
- }
這樣就保證了每一種語句類型的職責(zé)明確。
iBATIS.NET API基礎(chǔ)就向你介紹到這里,希望對你了解iBATIS.NET API基礎(chǔ)有所幫助。
【編輯推薦】