IBatisNet基础组件
DomSqlMapBuilder
DomSqlMapBuilder,其作用是根據配置文件創建SqlMap實例。可以通過這個組件從Stream,?Uri,?FileInfo, or?XmlDocument?instance?來讀取sqlMap.config文件。
SqlMap
??SqlMap是IBatisnet的核心組件,提供數據庫操作的基礎平臺。SqlMap可通過DomSqlMapBuilder創建。
?????????Assembly assembly = Assembly.Load("IBatisNetDemo");
????????????Stream stream = assembly.GetManifestResourceStream("IBatisNetDemo.sqlmap.config");
???????????DomSqlMapBuilder builder = new DomSqlMapBuilder();
???????????sqlMap = builder.Configure( stream );
?????SqlMap是線程安全的,也就是說,在一個應用中,可以共享一個SqlMap實例。
?????SqlMap提供了眾多數據操作方法,下面是一些常用方法的示例,具體說明文檔參見?ibatis net doc,或者ibatisnet的官方開發手冊。
SqlMap基本操作示例
例1:數據寫入操作(insert、update、delete)
| ?SqlMap.BeginTransaction(); ?Person person = new Person(); ?Person.FirstName =?“Zhang”; ?Person.LastName =?“shanyou”; int?Id = (int) SqlMap.Insert("InsertPerson", person); ?SqlMap.CommitTransaction();. |
例2:數據查詢:
| Int Id = 1; Person person = SqlMap.QueryForObject<Person>("", Id); return person; |
例3:在指定對象中存放查詢結果:
| Int Id = 1; Person person =??new Person(); person = SqlMap.QueryForObject<Person>("GetBirthday", Id, person); return person; |
?例4:執行批量查詢(Select)
| IList<Person> list = null; list = SqlMap.QueryForList<Person>("SelectAllPerson", null); ?return list; |
例5:查詢指定范圍內的數據(Select)
| IList<Person> list = null; list = SqlMap.QueryForList<Person>("SelectAllPerson", null, 0, 40); return list; |
例6:結合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); |
例7:分頁查詢(Select)
| PaginatedList list = sqlMap.QueryForPaginatedList (“getProductList”, null, 10); list.NextPage(); list.PreviousPage(); |
例8:基于Map的批量查詢(select)
| IDictionary map = sqlMap.QueryForMap (“getProductList”, null, “productCode”); Product p = (Product) map[“EST-93”]; |
OR映射
相對于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="IBatisNetDemo.Domain.Person,IBatisNetDemo"?/>
??</alias>
????<cacheModels>
????<cacheModel?id="person-cache"?implementation="MEMORY"?>
??????<flushInterval?hours="24"/>
??????<flushOnExecute??statement="UpdateAccountViaInlineParameters"/>
??????<flushOnExecute??statement="UpdateAccountViaParameterMap"/>
??????<property?name="Type"?value="Weak"/>
????</cacheModel>
??</cacheModels>
??<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="SelectAllPerson"?resultMap="SelectAllResult"?cacheModel="account-cache">
??????select
??????PER_ID,
??????PER_FIRST_NAME,
??????PER_LAST_NAME,
??????PER_BIRTH_DATE,
??????PER_WEIGHT_KG,
??????PER_HEIGHT_M
??????from PERSON????
????</select>
????<select?id="SelectByPersonId"?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>
????<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>
??</statements>
</sqlMap>
可以看到,映射文件主要分為兩個部分:模塊配置和Statement配置。
模塊配置包括:
1、typeAlias節點
定義了本映射文件中的別名,以避免過長變量值的反復書寫,此例中通過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> |
Statement配置:
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對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基础组件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 同一家银行信用卡额度共享吗
- 下一篇: 使用Uploadify实现上传图片生成缩