一、各個配置文件的作用說明
providers.config:指定數據庫提供者,.Net版本等信息。
xxxxx.xml:映射規則。
SqlMap.config:大部分配置一般都在這里,如數據庫連接等等。
二、默認配置文件的存放位置
在Windows應用項目或者類庫項目中,需要放在項目的/bin/debug/目錄下。
在Web應用程序中,需要放在應用程序根目錄。
當然,這也不是強制性的,也可以很靈活地配置
public IList<PersonModel> GetList() { //ISqlMapper mapper = Mapper.Instance(); DomSqlMapBuilder builder = new DomSqlMapBuilder(); ISqlMapper mapper = builder.Configure(@"C:\Users\Administrator\Desktop\Ibatis.Net測試\Ibatis.Net測試\SqlMap.config"); IList<PersonModel> ListPerson = mapper.QueryForList<PersonModel>("SelectAllPerson", null); //這個"SelectAllPerson"就是xml映射文件的Id return ListPerson; }
例如以上代碼,就從指定的位置去加載了SqlMap.config。注意,雖然SqlMap.config是從指定的位置,但是要注意里面的resource引入的資源,還是從原來的默認目錄開始找,例如
<providers resource="providers.config"/>
SqlMap.config里面的providers.config這個東西,還是需要在原來默認位置。
三、SqlMap.config
下面先放上一個在官網直接下載后的sample.SqlMap.config
<?xml version="1.0" encoding="utf-8"?> <sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <properties resource="../../../Files/properties.config"/> <settings> <setting useStatementNamespaces="false"/> </settings> <providers resource="../../../Files/providers.config"/> <!-- Database connection information --> <database> <provider name="OleDb2.0"/> <dataSource name="Blogs" connectionString="Provider=Microsoft.Jet.OLEDB.4.0;Data Source=../../../Files/Blogs.mdb"/> </database> <sqlMaps> <sqlMap resource="../../../Files/Maps/Access/Post.xml" /> <sqlMap resource="../../../Files/Maps/Access/Blog.xml" /> <sqlMap resource="../../../Files/Maps/Access/Author.xml" /> </sqlMaps> </sqlMapConfig>
1、properties節點
properties節點通常用於引入在外部定義一些鍵值對配置文件,以方便在后面統一調用,這樣修改的時候,只修改就可以了。
它的引入方式有3種:
- resource: 通過相對路徑來確定文件的位置。
- url: 通過絕對路徑來確定文件位置。
- embedded:通過嵌入資源方式來確定文件位置。
<sqlMap embedded = "命名空間.文件名.后綴名, 命名空間"/>
例如,你在外部的config文件中,定義了一個數據庫連接
<?xml version="1.0" encoding="utf-8" ?> <setting> <add key="connectionString" value="server=KISSDODOG-PC;uid=sa;pwd=123;database=Test"/> </setting>
這樣在SqlMap.config文件就可以這樣寫:
<!--數據庫連接字符串--> <database> <provider name="sqlServer2008"/> <dataSource name="Test" connectionString="${DataSource}"/> </database>
2、Settings節點
Settings節點里,可以配置以下5個信息:
- useStatementNamespaces:默認flase,是否使用全局完整命名空間。
- cacheModelsEnabled :默認true,是否啟用緩存。
- validateSqlMap:默認false,使用啟用SqlMapConfig.xsd來驗證映射XML文件。
- useReflectionOptimizer:默認true,是否使用反射機制訪問C#中對象的屬性。
- useEmbedStatementParams 是否使用嵌入的方式聲明可變參數
示例:
<settings> <setting useStatementNamespaces="false"/> --使用全局完整命名空間 </settings>
使用全局命名空間時,不同的xml映射文件,id互不影響。如果出現提示出現 重復的sql Id的情況,大多是沒啟用。如果啟用,則執行sql語句時,要用命名空間.id的方式。這個理所當然要啟用的。區分清楚點好,否則很容易出現xml 的 sql id重復的情況。
3、Providers節點
示例:
<providers resource="providers.config"/>
這里使用引入外部配置文件的方式實現。
4、alias節點
alias節點用於為類指定一個別名,通常用於為一些很長的類名指定一個別名,這樣可以減少一些代碼。
<typeAlias alias="Person" type="iBatis.Domain.Person,iBatisSample"/>
以上代碼的意思是,為iBatis.Domain.Person類指定一個別名Person。Person就代表iBatis.Domain.Person這個類。
起初我以為別名只是起了縮短配置類的作用,但后來我發現別名是還有其他作用的,它還指明了IBatis.net應該到哪個程序集去找實體類。
如果程序偶爾報如下錯誤,那么你就要考慮加上別名了。
“/”應用程序中的服務器錯誤。
Could not load type from string value 'xxx'
<alias> <typeAlias alias="Field" type="Nx.Domain.Common.Field, Nx.Domain" /> </alias>
Ibatis.Net有很多默認的別名:
5、database節點
指定一個你選擇使用的數據庫,和數據庫連接。
示例:
<database> <provider name="sqlServer2008"/> <dataSource name="Test" connectionString="server=KISSDODOG-PC;uid=sa;pwd=123;database=Test"/> </database>
6、SqlMaps節點
SqlMaps節點,用於配置映射信息。通常在映射信息寫在外部,在這個節點引入。
四、映射文件
映射文件與NHibernate類似,都是指定哪個屬性名,對於哪個列名。不過貌似沒有NHibernate那么復雜,東西貌似不多,不過也可能只是我了解得太少。
下面來看看省略的寫法(當property與column完全相同時,可以這樣寫):
<?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="Ibatis" xmlns="http://ibatis.apache.org/mapping" xmlns:xls="http://www.w3.org/2001/XMLSchema-instance"> <statements> <select id="SelectAllPerson" resultClass="Ibatis.Net.Domain.PersonModel"> select * from person </select> </statements> </sqlMap>
下面再來看看全部寫全的寫法,為了展示不同,我將Id和Name的屬性名改為PersonId,PersonName:
<?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="Ibatis" xmlns="http://ibatis.apache.org/mapping" xmlns:xls="http://www.w3.org/2001/XMLSchema-instance"> <resultMaps> <resultMap id="Person" Class="Ibatis.Net.Domain.PersonModel"> <!--id會被statements節點所用,Class實體類所在位置--> <result property="PersonId" column="Id"/> <!--property實體類的屬性名,column對應的列名--> <result property="PersonName" column="Name"/> </resultMap> </resultMaps> <statements> <select id="SelectAllPerson" resultMap="Person"> <!--id在程序中會被SqlMapper實體類所調用,resultMap就是resultMap節點的id--> select * from person </select> </statements> </sqlMap>
resultMaps部分:定義了數據庫字段名與實體類屬性名之間的關系。當然,如果你數據庫字段名與實體類屬性名完全一樣,那么resultMaps部分是可以省略的。另外要注意一點,ResultMap的列比你查詢的列不能少,也不能多。它不會說,ResultMap里映射的列多了,該屬性就自動將select返回的列自動置null,而是直接所有列都不映射賦值。也就是說,Person表有Id,Name,Age3列,如果你只想要SELECT兩個列(Id,Name),那么ResultMap里面的3列映射沒用了,你必須另外搞一個ResulpMap只映射兩列的。不爽。
statements部分:用於定義你需要執行的語句,在程序中通過select的id調用。
屬性 |
說明 |
parameterMap |
參數映射,需結合parameterMap節點對映射關系加以定義,對於存儲過程之外的statement而言,建議使用parameterClass作為參數配置方式,一方面避免了參數映射配置工作,另一方面其性能表現更加出色 |
parameterClass |
參數類。指定了參數類型的完整類名(包括命名空間),可以通過別名避免每次書寫冗長的類名 |
resultMap |
結果映射,需結合resultMap節點對映射關系加以定義 |
resultClass |
結果類。指定了結果類型的完整類名(包括命名空間),可以通過別名避免每次書寫冗長的類名 |
cacheModel |
Statement對應的Cache模塊 |
extends |
重復使用SQL子句 |
1、extends
extends用於提取一段重復使用的SQL語句而避免重復書寫
<select id="SelectAllCustomers" resultMap="Customer"> SELECT * FROM Customers </select> <select id="SelectAllCustomerOrderByCustomerID" resultMap="Customer" extends="SelectAllCustomers"> ORDER BY CustomerID </select>
2、parameterMap的屬性
它可以接受三個屬性,id/class/extends,其中是有id是必須的,class用於聲明使用的實體類名稱,可以是別名,也可以是全名,extends,可想而知,不解釋
在它下一級節點中應該包含若干個parameter元素,來指定對象屬性與當前變量的映射規則,parameter有如下常用屬性:
- property:指定類中的一個屬性
- columu:定義的參數名稱
- direction:用於聲明存儲過程的參數方向(input,output,inputoutput)
- dbType:用於指定property映射到數據庫中的數據類型
- type:用於為參數的對象指定CLR類型
- nullValue:指定在property為何值時,將會在存儲數據時候,替換為null,這是經常會被用到的
- size:用於指定最大值
3、resultMap的屬性
它的屬性很多是和parameterMap想對應的,但是值得一提的是它下面可以添加一個constructor元素來匹配一個構造函數。當然,這個的前提是Customers類中有這樣一個構造函數。例如:
<resultMaps> <resultMap id="Customer" class="Customers"> <constructor> <argument argumentName="PersonId" column="PersonID"/> <argument argumentName="PersonName" column="PersonName"/> </constructor> <result property="PersonId" column="PersonID"/> <result property="PersonName" column="PersonName"/> </resultMap> </resultMaps>
4、存儲過程
這里有一點區別就是,只可以使用parameterMap,而不可以使用parameterClass,其實想一想,您難道還會為每一個存儲過程定義個傳入的實體類嗎?還有一點,就是他的參數完全是按照 parameterMap中的定義自動匹配的。
<procedure id="demoProcedure" parameterMap="procedureDemo"> CustOrderHist </procedure>
5、對SQL片段的引用
在編寫SqlMaps的時候,經常需要把一個SQL語句進行拆分,然后在不通的地方引用它我們可以使用sql和include的組合來完成。
<sql id="order"> ORDER BY PersonID </sql>
<select id="SelectAllCustomerOrderByCustomerID" resultMap="Customer"> SELECT * FROM Person <include refid="test"/> </select>
五、$與#的區別
- SELECT * FROM TABLE WHERE Id = #id# 其中如果字段id為字符串類型,那么#id#表示的就是'id',也就是說會自動加引號。如果id為整型,那么#id#就是整型;
- SELECT * FROM TABLE WHERE Id = $id$ ,如果字段id為整型,Sql語句就不會出錯,但是如果字段id為字符串類型,那么Sql語句應該寫成 SELECT * FROM TABLE WHERE Id = '$id$',否則會出錯,因為它不會自動增加單引號。