IbatisNet开发使用小结
一.?? 介紹
??平常做企業級應用,需求變化是經常的事,而很多基礎代碼重復也是很讓人頭疼的問題。所以很多人會使用一些ORM框架來增強項目的可維護性、可擴展性。IBatis.Net就是一個比較易用的ORM框架,使用起來較為方便、靈活。IBatis.Net是從Ibatis的Java版本移植過來的.NET版本。iBATIS作為一種獨特的Data Mapper,使用SQL映射的方式將對象持久化至關系型數據庫。簡單的理解就是它將我們在數據訪問層實現的C#邏輯代碼,變為通過關系數據庫與對象的映射,將SQL邏輯放到外部的XML配置文件中,以方便以后的維護。
?? 這個框架有兩個主要的組成部分,一個是SQL Maps,另一個是Data Access Objects。Sql Maps是這個框架的核心部分,通過使用Sql Maps你可以顯著的節約數據庫操作的代碼量。SQL Maps使用一個簡單的XML文件來實現從實體到SQL statements的映射。使用DAO,封裝了對數據的訪問,你可以動態配置你的應用程序來訪問不同的實體存儲機制。隱藏持久性層實現的細節,Data Access Objects允許你通過一個簡單接口的來操作數據。
? ?
二.?? 準備工作
下面先讓我們來動手實踐一下,看看如何使用和調用IbatisNet。
1.? 下載IbatisNet軟件包: http://ibatis.apache.org/dotnetdownloads.cgi
| iBATIS.NET Downloads
| ?? |
| ?? |
官方網站還提供了一個示例項目:NPetShop Example Application
? ?
2.? 建立測試數據庫,并在數據庫中創建一個Person 表:
| 字段 | 類型 | 大小 |
| PER_ID | int | 4 |
| PER_FIRST_NAME | nvarchar | 40 |
| PER_LAST_NAME | nvarchar | 40 |
| PER_BIRTH_DATE | DateTime | 8 |
| PER_WEIGHT_KG | float | 8 |
| PER_HEIGHT_M | float | 8 |
? ?
三.?? 開發步驟
1.邏輯結構
???
2.建立項目
打開VS.NET,新建一個"ASP.NET Web應用程序"項目。
? ?
3.添加引用
在項目中添加下面dll的引用:
IBatisNet.Common.dll
IBatisNet.DataMapper.dll
IBatisNet.DataAccess.dll
? ?
4.在項目中,添加配置文件 SqlMap.config
該文件為IBatis.net默認的配置文件,不能缺少,當然可以不必是Sql.config,但是如果改為其他的名字的話需要在前臺代碼中說明,請參考下面的內容providers.config:該文件必須存在,并且不能改變它的文件名,該文件描述了如何連接數據庫,無須配置
結合上面示例中的IbatisNet配置文件,下面對配置文件中各節點的說明:
| <?xml version="1.0" encoding="utf-8"?> <sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > ? ? <!-- 常量屬性,通過單獨文件properties.config加載--> <properties resource="properties.config"/> <!-- 常量屬性,通過程序集資源中 加載 <properties embedded="database.config, IBatisNetDemo"/>--> ???? ? <settings> ????<setting useStatementNamespaces="${useStatementNamespaces}"/> ????<setting cacheModelsEnabled="true"/> ????<setting validateSqlMap="false"/> </settings> ? ? <!-- 數據驅動提供類配置文件的路徑和文件名 --> <providers resource="providers.config"/> ? ? <!-- 設置數據庫連接信息????--> <database> <provider name="${provider}"/> <dataSource name="IBatisNetTest" connectionString="${connectionString}"/> </database> ? ? <!-- 指定項目內映射的文件的位置--> <sqlMaps> <!-- 從程序集中 <sqlMap embedded="${root}Person.xml,${assembly}" />--> <!-- 從文件中--> <sqlMap resource="@Maps/Person.xml" /> ????</sqlMaps> </sqlMapConfig> |
? ?
詳細說明:
(1) properties節點
可以根據需要配置一些常量屬性。如果這些屬性有很多的話可以單獨寫一個文件里面,再通過resource(或url, embedded分別是引用url和編譯在程序中的資源文件)屬性引用進來。
? ?
properties 節點參數
| 參數 | 描述 |
| resource | 指定the properties文件從application的根目錄進行加載 resource="properties.config" |
| url | 指定the properties文件從文件的絕對路徑進行加載 url="c:/Web/MyApp/Resources/properties.config" 或者 url="file://c:/Web/MyApp/Resources/properties.config" |
| embedded | 指定文件可以作為程序集的資源文件進行加載' embedded=" database.config, IBatisNetDemo" |
? ?
上面例子中properties.config文件的配置如下:
| <?xml version="1.0" encoding="utf-8" ?> <settings> ????<!—應用程序和配置屬性設置--> ????<add key="provider" value="sqlServer2.0" /> ????<add key="connectionString"???? value="server=127.0.0.1;database=TVSystem;uid=sa;pwd=1" /> ????<add key="root" value="IBatisNetTest.Maps." /> ????<add key="assembly" value="IBatisNetTest" /> ? <add key="userid" value="sa" /> <add key="password" value="" /> <add key="database" value="Northwind" /> <add key="datasource" value="localhost" /> <add key="selectKey" value="select @@IDENTITY as value" /> <add key="directory" value="Maps" /> <add key="useStatementNamespaces" value="false" /> </settings> |
? ?
下面解釋一下這個文件的節點參數
properties.config節點參數
| 參數 | 描述 |
| key | 定義key (variable) 名字 key="username" |
| value | 定義DataMapper 中使用的 key的值 value="mydbuser" |
? ?
(2)?setting節點
Setting節點參數
| 參數 | 描述 |
| cacheModelsEnabled | 是否啟用sqlMap上的緩存機制 Example: cacheModelsEnabled="true" Default: true (enabled) |
| useStatementNamespaces | 是否使用Satement命名空間,這里的命名空間指的是映射文件中sqlMap節點的namespace屬性,如上例中針對Person表的映射文件sqlMap節點 <sqlMap namespace="Person" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance> 這里,指定了此sqlMap節點下定義的操作均叢屬于"Person"命名空間在useStatementNamespaces="true"的情況下,Statement調用需追加命名空間,如:sqlMap.Update("Person.UpdatePerson",person);否則直接通過Statement名稱調用即可,如sqlMap.Update("UpdatePerson",person);但請注意此時需要保證所有映射文件中,statement定義無重名 Example: useStatementNamespaces="false" Default: false (disabled) |
| validateSqlMap | 是配置要不要啟示SqlMapConfig.xsd schema驗證映射文件. Example: validateSqlMap="false" Default: false (disabled) |
? ?
(3)?provider節點
配置數據驅動提供類配置文件的路徑和文件名,通過resource(或url, embedded分別是引用url和編譯在程序中的資源文件)屬性引用進來,參數的含義同properties。
ADO.NET是通過數據訪問提供程序(Provider)訪問數據庫。IBatisNet使用的是插件式結構來使用這些數據庫提供程序,每一個Provider對應于providers.config文件中定義的一個provider項。1.3版本的Provider.config文件中定義了已經實現的16個provider,通過設置這個文件中的幾個參數來決定使用哪個數據庫提供程序。
????????? sqlServer1.0 - Microsoft SQL Server 7.0/2000 provider available with .NET Framework 1.0
????????? sqlServer1.1 -Microsoft SQL Server 7.0/2000 provider available with .NET Framework 1.1
????????? sqlServer2.0 - Microsoft SQL server 7.0/2000/2005 provider available with .NET Framework 2.0
????????? OleDb1.1 - OleDb provider available with .NET Framework 1.1
????????? Odbc1.1 - Odbc provider available with .NET Framework 1.1
????????? oracle9.2 - Oracle provider V9.2.0.401
????????? oracle10.1 - Oracle provider V10.1.0.301
????????? oracleClient1.0 - MS Oracle provider V1.0.5 available with .NET Framework 1.1
????????? ByteFx - ByteFx MySQL provider V0.7.6.15073
????????? MySql - MySQL provider V1.0.4.20163
????????? SQLite3 - SQLite.NET provider V0.21.1869.3794
????????? Firebird1.7 - Firebird SQL .NET provider V1.7.0.33200
????????? PostgreSql0.7 - Npgsql provider V0.7.0.0
????????? PostgreSql0.7.1 - Npgsql provider V0.7.1.0
????????? iDb2.10 - IBM DB2 iSeries provider V10.0.0.0
????????? Informix -- informix NET Provider, 2.81.0.0
提供程序要求安裝相關類庫,每一個provider 元素都有"enabled" 屬性來控制是否啟用這個providers. 一個provider 可以通過 "default"屬性標識為默認的提供程序。
? ?
(4)?database節點
數據庫的信息,包括使用哪些數據庫驅動和數據連接字符串的配置。
Database節點參數
| 參數 | 描述 |
| provider | 數據庫訪問所使用的provider.config文件定義的provider |
| dataSource | 特定的數據庫連接字符串 |
? ?
(5)?typeHandler節點
定義數據庫類型到dotnet數據類型的處理,不同的數據庫都有一些特殊的數據庫字段類型需要特殊處理,就可以通過這個功能實現。比如說Blob字段在不同的數據庫中處理不一樣。大家可以去看看Ibatisnet源代碼就清楚這個功能的實現原理,對于我們的設計會有很大的啟發
(6)?sqlMaps節點
sqlMap節點指定了映射文件的位置,配置中可以出現多個sqlMap節點,以指定項目內所包含的所有映射文件。
? ?
? ?
5.創建實體類
定義Person的實體類,該對象類將與數據庫進行映射。
| [Serializable] public class Person { private int id; private string firstName; private string lastName; private DateTime? birthDate; private double? weightInKilograms; private double? heightInMeters; public Person() { } public int Id { get { return id; } set { id = value; } } public string FirstName { get { return firstName; } set { firstName = value; } } public string LastName { get { return lastName; } set { lastName = value; } } public DateTime? BirthDate { get { return birthDate; } set { birthDate = value; } } public double? WeightInKilograms { get { return weightInKilograms; } set { weightInKilograms = value; } } public double? HeightInMeters { get { return heightInMeters; } set { heightInMeters = value; } } } |
? ?
? ?
6.添加Person的映射文件Person.xml
相對于Nhibernate等ORM實現來說,IBatisnet的映射配置更為直接,下面是配置文件內容:
| <?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="Person" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" > ? ? ????<!--模塊配置--> ????<alias> ????????<typeAlias alias="Person" type="IBatisNetLib.Person,IBatisNetLib" /> ????</alias> ????<resultMaps> ????????<resultMap id="SelectAllResult" class="Person"> ????????????<result property="Id" column="PER_ID" /> ????????????<result property="FirstName" column="PER_FIRST_NAME" /> ????????????<result property="LastName" column="PER_LAST_NAME" /> ????????????<result property="BirthDate" column="PER_BIRTH_DATE" /> ????????????<result property="WeightInKilograms" column="PER_WEIGHT_KG" /> ????????????<result property="HeightInMeters" column="PER_HEIGHT_M" /> ????????</resultMap> ????</resultMaps> ???????? <!--statement配置--> ????<statements> <select id="Exists" resultClass="int" parameterclass="int"> select count(1) from PERSON where PER_ID = #value# </select> ? ????????<insert id="InsertPerson" parameterclass="Person" > ????????????<selectKey property="Id" type="post" resultClass="int"> ????????????????${selectKey} ????????????</selectKey> ????????????insert into Person ????????????( PER_FIRST_NAME, ????????????PER_LAST_NAME, ????????????PER_BIRTH_DATE, ????????????PER_WEIGHT_KG, ????????????PER_HEIGHT_M)values(#FirstName#,#LastName#,#BirthDate#, #WeightInKilograms#, #HeightInMeters#) ????????</insert> ? ? ????????<update id="UpdatePerson" ???????????????????? parameterclass="Person"> ????????????<![CDATA[ update Person set PER_FIRST_NAME =#FirstName#, PER_LAST_NAME =#LastName#, PER_BIRTH_DATE =#BirthDate#, PER_WEIGHT_KG=#WeightInKilograms#, PER_HEIGHT_M=#HeightInMeters# where PER_ID = #Id# ]]> ????????</update> ? ? ????????<delete id="DeletePerson" parameterclass="Person"> ????????????delete from Person where PER_ID = #Id# ????????</delete> ? <select id="SelectAllPerson" resultMap="SelectAllResult"> Select * from PERSON </select> ? ? <select id="SelectByPersonId" resultMap="SelectAllResult" resultClass="Person" parameterClass="int"> select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M from PERSON where PER_ID = #value# </select> </statements>???? </sqlMap> |
? ?
可以看到,映射文件主要分為兩個部分:模塊配置 和 Statement配置。
模塊配置包括:
(1)Type Alias節點
定義了本映射文件中的別名,以避免過長變量值的反復書寫,此例中通過typeAlias節點為類"IBatisNetDemo.Domain.Person"定義了一個別名"Person",這樣在本配置文件中的其他部分,需要引用"IBatisNetDemo.Domain.Person"類時,只需以其別名替代即可。
? ?
(2)cacheModel節點
定義了本映射文件中使用的Cache機制:
| <cacheModel id="person-cache" implementation="MEMORY" > <flushInterval hours="24"/> <flushOnExecute statement="UpdateAccountViaInlineParameters"/> <flushOnExecute statement="UpdateAccountViaParameterMap"/> <property name="Type" value="Weak"/> </cacheModel> |
這里聲明了一個名為"person-cache"的cacheModel,之后可以在Statement聲明中對其進行引用:
| <select id="SelectAllPerson" resultMap="SelectAllResult" cacheModel=" person-cache"> select PER_ID, PER_FIRST_NAME, PER_LAST_NAME, PER_BIRTH_DATE, PER_WEIGHT_KG, PER_HEIGHT_M from PERSON </select> |
這表明對通過id為SelAllPerson的"Select Statement"獲取的數據,使用CacheModel "person-cache"進行緩存。之后如果程序再次用此Satement進行數據查詢。即直接從緩存中讀取數據,而不需再去數據庫查詢。
CacheModel主要有幾個配置點:
| 參數 | 描述 |
| flushInterval | 設定緩存有效期,如果超過此設定值,則將此CacheModel緩存清空 |
| CacheSize | 本Cachemodel中最大的數據對象數量 |
| flushOnExecute | 指定執行特定的Statement時,將緩存清空。如UpdatePerson操作將更新數據庫中用戶信息,這將導致緩存中的數據對象與數據庫中的實際數據發生偏差,因此必須將緩存清空以避免臟數據的出現。 |
? ?
(3)resultMaps節點
resultMaps實現dotnet實體到數據庫字段的映射配置:
| <resultMap id="SelectAllResult" class="Person"> <result property="Id" column="PER_ID" /> <result property="FirstName" column="PER_FIRST_NAME" /> <result property="LastName" column="PER_LAST_NAME" /> <result property="BirthDate" column="PER_BIRTH_DATE" /> <result property="WeightInKilograms" column="PER_WEIGHT_KG" /> <result property="HeightInMeters" column="PER_HEIGHT_M" /> </resultMap> |
? ?
(4)Statement配置:
?⑴ ID
指定了操作ID,之后我們可以在代碼中通過指定操作id 來執行此節點所定義的操作,如:
SqlMap.Update("UpdatePerson", person);
ID設定使得在一個配置文件中定義兩個同名節點成為可能(兩個update節點,以不同id區分)
⑵ parameterClass
指定了操作所需的參數類型,此例中update 操作以IBatisNetDemo.Domain.Person類型的對象作為參數,目標是將提供的Person實例更新到數據庫。
parameterClass="Person"中,user為"IBatisNetDemo.Domain.Person"
類的別名,別名可通過typeAlias節點指定,如示例配置文件中的:
<typeAlias alias="Person" type="IBatisNetDemo.Domain.Person,IBatisNetDemo" />
? ?
⑶ <![CDATA[……]]>
通過<![CDATA[……]]>節點,可以避免SQL 中與XML 規范相沖突的字符對XML映射文件的合法性造成影響。
⑷ 執行更新操作的SQL,這里的SQL 即實際數據庫支持的SQL 語句,將由IBatisNet填入參數后交給數據庫執行。
⑸ SQL中所需的用戶名參數,"# FirstName #"在運行期會由傳入的Person對象的FirstName屬性填充。
⑹ SQL 中所需的用戶性別參數"# LastName #",將在運行期由傳入的user 對象的LastName屬性填充。
⑺ SQL中所需的條件參數"#id#",將在運行期由傳入的Person對象的Person屬性填充。
對于這個示例,IBatisNet在運行期會讀取id 為"UpdatePerson"的update節點的SQL定義,并調用指定的user對象的對應getter方法獲取屬性值,并用此屬性值,對SQL中的參數進行填充后提交數據庫執行。
? ?
? ?
Statement配置包含了數個與Sql Statement相關的節點,<statement>元素是一個通用的能夠包容任意類型sql的元素。我們可以用更多細節的元素。
這些細節元素提供更好的錯誤檢查以及一些更多的功能。(例如,一個插入函數能夠返回數據庫自動生成的key)。以下表格總結了聲明類型元素以及他們的特性和屬性。
| Statement Element | Attributes | Child Elements | Methods |
| <statement> | id parameterClass resultClass parameterMap resultMap cacheModel xmlResultName (Java only) | All dynamic elements | insert update delete All query methods |
| <insert> | id parameterClass parameterMap | All dynamic elements <selectKey> <generate> (.NET only) | insert update delete |
| <update> | id parameterClass parameterMap | All dynamic elements <generate> (.NET only) | insert update delete |
| <delete> | id parameterClass parameterMap | All dynamic elements <generate> (.NET only) | insert update delete |
| <select> | id parameterClass resultClass parameterMap resultMap cacheModel | All dynamic elements <generate> (.NET only) | All query methods |
| <procedure> | id parameterClass resultClass parameterMap resultMap xmlResultName (Java only) | All dynamic elements | insert update delete All query methods |
? ?
其中,statement最為通用,它可以代替其余的所有節點。除statement之外的節點對應于SQL中的同名操作(procedure對應存儲過程)。使用Statement定義所有操作,缺乏直觀性,建議在開發中根據操作目的,各自選用對應的節點名加以說明。一方面,使得配置文件更加直觀,另一方面,也可以借助xsd對i節點聲明進行更有針對性的檢查,以避免配置上的失誤。
? ?
| <statement id="statementName" [parameterMap="nameOfParameterMap"] [parameterClass="some.class.Name"] [resultMap="nameOfResultMap"] [resultClass="some.class.Name"] [cacheModel="nameOfCache"] >? select * from PRODUCT where PRD_ID = [?|#propertyName#] order by [$simpleDynamic$] ? ? </statement> |
? ?
其中"[ ]"包圍的部分為可能出現的配置項,各參數說明見下表。具體的使用方法參見IBatisNet官方文檔。
| 參數 | 描述 |
| parameterMap | 參數映射,需結合parameterMap節點對映射關系加以定義,對于存儲過程之外的statement而言,建議使用parameterClass作為參數配置方式,一方面避免了參數映射配置工作,另一方面其性能表現更加出色 |
| parameterClass | 參數類。指定了參數類型的完整類名(包括命名空間),可以通過別名避免每次書寫冗長的類名 |
| resultMap | 結果映射,需結合resultMap節點對映射關系加以定義 |
| resultClass | 結果類。指定了結果類型的完整類名(包括命名空間),可以通過別名避免每次書寫冗長的類名 |
| cacheModel | Statement對應的Cache模塊 |
? ?
一般而言,對于insert、update、delete、select語句,優先采用parameterClass和resultClass.。paremeterMap使用較少,而ResultMap則大多用于存儲過程處理和查詢。存儲過程相對而言比較封閉(很多情況下需要調用現有的存儲過程),其參數名和返回的數據字段命名往往不符合dotnet編程的命名規范)。使用resultMap建立字段名同Dotnet對象的屬性之間的映射關系就非常有效。另一方面,由于通過ResultMap指定了字段名和字段類型,ibatisnet無需再通過ado.net來動態獲取字段信息,在一定程度上也提升了性能。
IBatisNet開發使用小結 之二
?本文示例項目源碼下載
?動軟代碼生成器新增對IBatisNet的代碼生成插件
四.?? IBatisNet組件使用
1.? DomSqlMapBuilder
DomSqlMapBuilder,其作用是根據配置文件創建SqlMap實例。可以通過這個組件從Stream, Uri, FileInfo, or XmlDocument instance 來讀取sqlMap.config文件。?
2.? SqlMap
SqlMapper是IBatisnet的核心組件,提供數據庫操作的基礎平臺。所有的操作均通過SqlMapper實例完成。SqlMapper可通過DomSqlMapBuilder創建。
這個例子中我們可以將所有的配置文件按照嵌入資源文件方式存放,從程序集去加載sqlmap.config文件。也可以直接以文件方式加載sqlmap.config。?
| /// <summary> /// IsqlMapper實例 /// </summary> /// <returns></returns> public static ISqlMapper sqlMap ; private string fileName = "sqlMap.Config"; public BaseSqlMapDao() { //從程序集資源中加載 //Assembly assembly = Assembly.Load("IBatisNetDemo"); //Stream stream = assembly.GetManifestResourceStream("IBatisNetDemo.sqlmap.config"); //DomSqlMapBuilder builder = new DomSqlMapBuilder(); //sqlMap = builder.Configure(stream); ? ? //從文件加載創建實例 DomSqlMapBuilder builder = new DomSqlMapBuilder(); sqlMap = builder.Configure(fileName); } |
? ?
SqlMap是線程安全的,也就是說,在一個應用中,可以共享一個SqlMap實例。
SqlMap提供了眾多數據操作方法,下面是一些常用方法的示例,具體說明文檔參見 ibatis net doc,或者ibatisnet的官方開發手冊。?
3.? SqlMap基本操作示例?
例1:數據寫入操作(insert、update、delete)
| SqlMap.BeginTransaction(); Person person = new Person(); Person.FirstName = "li"; Person.LastName = "tianping"; int Id = (int) SqlMap.Insert("InsertPerson", person); SqlMap.CommitTransaction(); |
?例2:數據查詢:
| Int Id = 1; Person person = SqlMap.QueryForObject<Person>("", Id); return person; |
?例3:執行批量查詢(Select)
| IList<Person> list = null; list = SqlMap.QueryForList<Person>("SelectAllPerson", null); return list; |
?例4:查詢指定范圍內的數據(Select)
| IList<Person> list = null; list = SqlMap.QueryForList<Person>("SelectAllPerson", null, 0, 40); return list; |
?例5:結合RowDelegate進行查詢:
| public void RowHandler(object obj, IList list) { Product product = (Product) object; product.Quantity = 10000; } SqlMapper.RowDelegate handler = new SqlMapper.RowDelegate(this.RowHandler); IList list = sqlMap.QueryWithRowDelegate("getProductList", null, handler); |
?4.? 存儲過程操作
下面特別說明一下ibatisnet對Stored Procedures的處理,iBatis數據映射把存儲過程當成另外一種聲明元素。示例演示了一個基于存儲過程的簡單數據映射。?
| <!-- Microsot SQL Server --> <procedure id="SwapEmailAddresses" parameterMap="swap-params"> ps_swap_email_address </procedure> ... <parameterMap id="swap-params"> <parameter property="email1" column="First_Email" /> <parameter property="email2" column="Second_Email" /> </parameterMap> ? ? <!-- Oracle with MS OracleClient provider --> <procedure id="InsertCategory" parameterMap="insert-params"> prc_InsertCategory </procedure> ... <parameterMap id="insert-params"> <parameter property="Name" column="p_Category_Name"/> <parameter property="GuidString" column="p_Category_Guid" dbType="VarChar"/> <parameter property="Id" column="p_Category_Id" dbType="Int32" type="Int"/> </parameterMap> ? ? <!-- Oracle with ODP.NET 10g provider --> <statement id="InsertAccount" parameterMap="insert-params"> prc_InsertAccount </statement> ... <parameterMap id="insert-params"> <parameter property="Id" dbType="Int32"/> <parameter property="FirstName" dbType="VarChar2" size="32"/> <parameter property="LastName" dbType="VarChar2" size="32"/> <parameter property="EmailAddress" dbType="VarChar2" size="128"/> </parameterMap> ?? |
? ?
示例是調用存儲過程swapEmailAddress的時候將會在數據庫表的列和兩個email地址之間交換數據,參數對象亦同。參數對象僅在屬性被設置成INOUT或者OUT的時候才會被修改。否則,他們將不會被修改。當然,不可變得參數對象是不會被修改的,比如string.
.Net中,parameterMap屬性是必須的。DBType,參數方向,大小由框架自動發現的。(使用CommandBuilder實現的)。
? ?
五.?? IBatisNet封裝類:BaseSqlMapDao
為了日后的重復使用和代碼簡潔,我們可以像DbHelperSQL一樣,對SqlMap的各種操作進行封裝。
? ?
| using System; using System.Collections; using System.Collections.Generic; using System.Text; using System.IO; using System.Web; using System.Reflection; using IBatisNet.Common; using IBatisNet.Common.Pagination; using IBatisNet.DataMapper; using IBatisNet.DataMapper.Exceptions; using IBatisNet.DataMapper.Configuration; namespace IBatisNetLib { /// <summary> /// 基于IBatisNet的數據訪問基類 /// </summary> public class BaseSqlMapDao { /// <summary> /// IsqlMapper實例 /// </summary> /// <returns></returns> public static ISqlMapper sqlMap; #region 構造ISqlMapper private string fileName = "sqlMap.Config"; public BaseSqlMapDao() { //從程序集中加載 //Assembly assembly = Assembly.Load("IBatisNetDemo"); //Stream stream = assembly.GetManifestResourceStream("IBatisNetDemo.sqlmap.config"); //DomSqlMapBuilder builder = new DomSqlMapBuilder(); //sqlMap = builder.Configure(stream); ? ? //從文件加載創建實例 DomSqlMapBuilder builder = new DomSqlMapBuilder(); sqlMap = builder.Configure(fileName); } #endregion ? /// <summary> /// 是否存在 /// </summary> /// <param name="tableName">表名</param> /// <returns></returns> protected bool ExecuteExists(string statementName, object parameterObject) { try { object obj = sqlMap.QueryForObject(statementName, parameterObject); int cmdresult; if ((Object.Equals(obj, null)) || (obj == null)) { cmdresult = 0; } else { cmdresult = int.Parse(obj.ToString()); } if (cmdresult == 0) { return false; } else { return true; } } catch (Exception e) { throw (e); } } ? /// <summary> /// 執行添加 /// </summary> /// <param name="statementName">操作名</param> /// <param name="parameterObject">參數</param> protected object ExecuteInsert(string statementName, object parameterObject) { try { return sqlMap.Insert(statementName, parameterObject); } catch (Exception e) { throw new DataMapperException("Error executing query '" + statementName + "' for insert. Cause: " + e.Message, e); } } /// <summary> /// 執行添加,返回自動增長列 /// </summary> /// <param name="statementName">操作名</param> /// <param name="parameterObject">參數</param> /// <returns>返回自動增長列</returns> protected int ExecuteInsertForInt(string statementName, object parameterObject) { try { object obj=sqlMap.Insert(statementName, parameterObject); if (obj != null) { return Convert.ToInt32(obj); } else { return 0; } } catch (Exception e) { throw new DataMapperException("Error executing query '" + statementName + "' for insert. Cause: " + e.Message, e); } } ? ? /// <summary> /// 執行修改 /// </summary> /// <param name="statementName">操作名</param> /// <param name="parameterObject">參數</param> /// <returns>返回影響行數</returns> protected int ExecuteUpdate(string statementName, object parameterObject) { try { return sqlMap.Update(statementName, parameterObject); } catch (Exception e) { throw new DataMapperException("Error executing query '" + statementName + "' for update. Cause: " + e.Message, e); } } ? ? /// <summary> /// 執行刪除 /// </summary> /// <param name="statementName">操作名</param> /// <param name="parameterObject">參數</param> /// <returns>返回影響行數</returns> protected int ExecuteDelete(string statementName, object parameterObject) { try { return sqlMap.Delete(statementName, parameterObject); } catch (Exception e) { throw new DataMapperException("Error executing query '" + statementName + "' for delete. Cause: " + e.Message, e); } } ? ? /// <summary> /// 得到列表 /// </summary> /// <typeparam name="T">實體類型</typeparam> /// <param name="statementName">操作名稱,對應xml中的Statement的id</param> /// <param name="parameterObject">參數</param> /// <returns></returns> protected IList<T> ExecuteQueryForList<T>(string statementName, object parameterObject) { try { return sqlMap.QueryForList<T>(statementName, parameterObject); } catch (Exception e) { throw new DataMapperException("Error executing query '" + statementName + "' for list. Cause: " + e.Message, e); } } ? ? /// <summary> /// 得到指定數量的記錄數 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="statementName"></param> /// <param name="parameterObject">參數</param> /// <param name="skipResults">跳過的記錄數</param> /// <param name="maxResults">最大返回的記錄數</param> /// <returns></returns> protected IList<T> ExecuteQueryForList<T>(string statementName, object parameterObject, int skipResults, int maxResults) { try { return sqlMap.QueryForList<T>(statementName, parameterObject, skipResults, maxResults); } catch (Exception e) { throw new DataMapperException("Error executing query '" + statementName + "' for list. Cause: " + e.Message, e); } } ? ? /// <summary> /// 得到分頁的列表 /// </summary> /// <param name="statementName">操作名稱</param> /// <param name="parameterObject">參數</param> /// <param name="pageSize">每頁記錄數</param> /// <returns></returns> protected IPaginatedList ExecuteQueryForPaginatedList(string statementName, object parameterObject, int pageSize) { try { return sqlMap.QueryForPaginatedList(statementName, parameterObject, pageSize); } catch (Exception e) { throw new DataMapperException("Error executing query '" + statementName + "' for paginated list. Cause: " + e.Message, e); } } ? ? /// <summary> /// 查詢得到對象的一個實例 /// </summary> /// <typeparam name="T">對象type</typeparam> /// <param name="statementName">操作名</param> /// <param name="parameterObject">參數</param> /// <returns></returns> protected T ExecuteQueryForObject<T>(string statementName, object parameterObject) { try { return sqlMap.QueryForObject<T>(statementName, parameterObject); } catch (Exception e) { throw new DataMapperException("Error executing query '" + statementName + "' for object. Cause: " + e.Message, e); } } } } |
? ?
????調用該基類實現映射文件的數據訪問代碼:
| using System; using System.Collections.Generic; using System.Text; namespace IBatisNetLib { public class PersonService : BaseSqlMapDao { public PersonService() { } /// <summary> /// 是否存在該記錄 /// </summary> public bool Exists(object Id) { return ExecuteExists("Exists", Id); } public void Insert(Person person) { ExecuteInsert("InsertPerson", person); } public void Update(Person person) { ExecuteUpdate("UpdatePerson", person); } public void Delete(Person person) { ExecuteDelete("DeletePerson", person); } public IList<Person> GetAllPerson() { IList<Person> list = null; list = ExecuteQueryForList<Person>("SelectAllPerson", null); return list; } public Person GetPerson(object Id) { Person person = ExecuteQueryForObject<Person>("SelectByPersonId", Id); return person; } } } |
??
轉載于:https://www.cnblogs.com/asks/p/4098225.html
總結
以上是生活随笔為你收集整理的IbatisNet开发使用小结的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: webkit webApp 开发技术要点
- 下一篇: c# C++接口封装 汽车模拟仿真