IBatisNet基础组件
DomSqlMapBuilder
DomSqlMapBuilder,其作用是根據(jù)配置文件創(chuàng)建SqlMap實(shí)例。可以通過這個組件從Stream,?Uri,?FileInfo, or?XmlDocument?instance?來讀取sqlMap.config文件。
SqlMap
??SqlMap是IBatisnet的核心組件,提供數(shù)據(jù)庫操作的基礎(chǔ)平臺。SqlMap可通過DomSqlMapBuilder創(chuàng)建。
?????????Assembly assembly = Assembly.Load("IBatisNetDemo");
????????????Stream stream = assembly.GetManifestResourceStream("IBatisNetDemo.sqlmap.config");
???????????DomSqlMapBuilder builder = new DomSqlMapBuilder();
???????????sqlMap = builder.Configure( stream );
?????SqlMap是線程安全的,也就是說,在一個應(yīng)用中,可以共享一個SqlMap實(shí)例。
?????SqlMap提供了眾多數(shù)據(jù)操作方法,下面是一些常用方法的示例,具體說明文檔參見?ibatis net doc,或者ibatisnet的官方開發(fā)手冊。
SqlMap基本操作示例
例1:數(shù)據(jù)寫入操作(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:數(shù)據(jù)查詢:
| Int Id = 1; Person person = SqlMap.QueryForObject<Person>("", Id); return person; |
例3:在指定對象中存放查詢結(jié)果:
| Int Id = 1; Person person =??new Person(); person = SqlMap.QueryForObject<Person>("GetBirthday", Id, person); return person; |
?例4:執(zhí)行批量查詢(Select)
| IList<Person> list = null; list = SqlMap.QueryForList<Person>("SelectAllPerson", null); ?return list; |
例5:查詢指定范圍內(nèi)的數(shù)據(jù)(Select)
| IList<Person> list = null; list = SqlMap.QueryForList<Person>("SelectAllPerson", null, 0, 40); return list; |
例6:結(jié)合RowDelegate進(jìn)行查詢:
| 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實(shí)現(xiàn)來說,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節(jié)點(diǎn)
定義了本映射文件中的別名,以避免過長變量值的反復(fù)書寫,此例中通過typeAlias節(jié)點(diǎn)為類“IBatisNetDemo.Domain.Person”定義了一個別名“Person”,這樣在本配置文件中的其他部分,需要引用“IBatisNetDemo.Domain.Person”類時,只需以其別名替代即可。
2、cacheModel節(jié)點(diǎn)
定義了本映射文件中使用的Cache機(jī)制:
| <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聲明中對其進(jìn)行引用:
| <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”獲取的數(shù)據(jù),使用CacheModel “person-cache”進(jìn)行緩存。之后如果程序再次用此Satement進(jìn)行數(shù)據(jù)查詢。即直接從緩存中讀取數(shù)據(jù),而不需再去數(shù)據(jù)庫查詢。
CacheModel主要有幾個配置點(diǎn):
| 參數(shù) | 描述 |
| flushInterval | 設(shè)定緩存有效期,如果超過此設(shè)定值,則將此CacheModel緩存清空 |
| CacheSize | 本Cachemodel中最大的數(shù)據(jù)對象數(shù)量 |
| flushOnExecute? | 指定執(zhí)行特定的Statement時,將緩存清空。如UpdatePerson操作將更新數(shù)據(jù)庫中用戶信息,這將導(dǎo)致緩存中的數(shù)據(jù)對象與數(shù)據(jù)庫中的實(shí)際數(shù)據(jù)發(fā)生偏差,因此必須將緩存清空以避免臟數(shù)據(jù)的出現(xiàn)。 |
3、resultMaps節(jié)點(diǎn)
?resultMaps實(shí)現(xiàn)dotnet實(shí)體到數(shù)據(jù)庫字段的映射配置:
| <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配置包含了數(shù)個與Sql Statement相關(guān)的節(jié)點(diǎn),<statement>元素是一個通用的能夠包容任意類型sql的元素。我們可以用更多細(xì)節(jié)的元素。
這些細(xì)節(jié)元素提供更好的錯誤檢查以及一些更多的功能。(例如,一個插入函數(shù)能夠返回?cái)?shù)據(jù)庫自動生成的key)。以下表格總結(jié)了聲明類型元素以及他們的特性和屬性。
| 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最為通用,它可以代替其余的所有節(jié)點(diǎn)。除statement之外的節(jié)點(diǎn)對應(yīng)于SQL中的同名操作(procedure對應(yīng)存儲過程)。使用Statement定義所有操作,缺乏直觀性,建議在開發(fā)中根據(jù)操作目的,各自選用對應(yīng)的節(jié)點(diǎn)名加以說明。一方面,使得配置文件更加直觀,另一方面,也可以借助xsd對i節(jié)點(diǎn)聲明進(jìn)行更有針對性的檢查,以避免配置上的失誤。
| <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> |
其中“[ ]”包圍的部分為可能出現(xiàn)的配置項(xiàng),各參數(shù)說明見下表。具體的使用方法參見IBatisNet官方文檔。
| 參數(shù) | 描述 |
| parameterMap | 參數(shù)映射,需結(jié)合parameterMap節(jié)點(diǎn)對映射關(guān)系加以定義,對于存儲過程之外的statement而言,建議使用parameterClass作為參數(shù)配置方式,一方面避免了參數(shù)映射配置工作,另一方面其性能表現(xiàn)更加出色 |
| parameterClass | 參數(shù)類。指定了參數(shù)類型的完整類名(包括命名空間),可以通過別名避免每次書寫冗長的類名 |
| resultMap | 結(jié)果映射,需結(jié)合resultMap節(jié)點(diǎn)對映射關(guān)系加以定義 |
| resultClass | 結(jié)果類。指定了結(jié)果類型的完整類名(包括命名空間),可以通過別名避免每次書寫冗長的類名 |
| cacheModel | Statement對應(yīng)的Cache模塊 |
一般而言,對于insert、update、delete、select語句,優(yōu)先采用parameterClass和resultClass.。paremeterMap使用較少,而ResultMap則大多用于存儲過程處理和查詢。存儲過程相對而言比較封閉(很多情況下需要調(diào)用現(xiàn)有的存儲過程),其參數(shù)名和返回的數(shù)據(jù)字段命名往往不符合dotnet編程的命名規(guī)范)。使用resultMap建立字段名同Dotnet對象的屬性之間的映射關(guān)系就非常有效。另一方面,由于通過ResultMap指定了字段名和字段類型,ibatisnet無需再通過ado.net來動態(tài)獲取字段信息,在一定程度上也提升了性能。
下面特別說明一下ibatisnet對Stored Procedures的處理,iBatis數(shù)據(jù)映射把存儲過程當(dāng)成另外一種聲明元素。示例演示了一個基于存儲過程的簡單數(shù)據(jù)映射。
| <!-- 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> |
示例是調(diào)用存儲過程swapEmailAddress的時候?qū)跀?shù)據(jù)庫表的列和兩個email地址之間交換數(shù)據(jù),參數(shù)對象亦同。參數(shù)對象僅在屬性被設(shè)置成INOUT或者OUT的時候才會被修改。否則,他們將不會被修改。當(dāng)然,不可變得參數(shù)對象是不會被修改的,比如string.
??.Net中,parameterMap屬性是必須的。DBType,參數(shù)方向,大小由框架自動發(fā)現(xiàn)的。(使用CommandBuilder實(shí)現(xiàn)的)
總結(jié)
以上是生活随笔為你收集整理的IBatisNet基础组件的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 同一家银行信用卡额度共享吗
- 下一篇: 余额宝里的钱是自己的吗