首先,MyBatis 封裝了絕大多數的數據訪問代碼,使得開發者只需關注 SQL 本身,而不需要花費精力去處理像創建 Connection,以及確保關閉 Connection 這樣繁雜的代碼。
其次,MyBatis 可以算是在所有主流的持久層框架中學習成本最低,最容易上手和掌握的框架。雖說其他持久層框架也號稱門檻低,容易上手,但是等到你真正使用時會發現,要想掌握並用好它是一件非常困難的事。
1. 待訪問的數據庫
考慮我們希望訪問數據庫中的產品表,表的名稱為:[Production].[Products],表的結構如下所示:
為了簡單起見,我們僅僅讀取前兩個字段:productit 和 productname。
2. 實體
在項目中,我們希望讀取的數據被轉換為實體對象,當然,我們需要定義一個類來表示這個映射關系。
在 EntityModel 項目中,我們定義了一個實體類 Product。讀取的數據將被轉換為這個類的對象實例。這個類不需要實現任何接口,也不需要從任何特殊的基類派生。
namespace EntityModel { public class Product { public int ProductId { get; set; } public string ProductName { get; set; } } }
3. 映射數據訪問的 SQL 語句,以及實體與字段的映射關系
這步映射一般通過 XML 文件完成,文件名任意,並沒有特殊的要求,關鍵是映射文件必須符合特定的架構要求。這個架構要求在 MyBatisNet 的壓縮包中存在,名為:SqlMap.xsd。
文件中主要包含三個部分。
3.1 別名
為了在 XML 文件中便於描述,可以為涉及的數據類型創建一個別名,例如,為 Product 類創建別名 Product, 如下所示,type 是原有的 .NET 類型表示,typeAlias 就是我們定義的別名。
<alias> <typeAlias alias="Product" type="EntityModel.Product, EntityModel"/> </alias>
3.2 查詢結果的映射
這里定義查詢結果中的字段與實體對象的屬性之間的映射關系,可以在 resultMaps 中包含多個映射,每個映射通過 resultMap 進行描述。
其中:id 用於后面的 SQL 定義中使用,class 指的是我們定義的實體類,這里使用了上面定義的別名。
每一個 result 中的 property 用來描述實體類的屬性,type 是實體類的類型,column 是對應的查詢字段名稱,dbType 就是數據庫字段的類型了。
<resultMaps> <!-- 映射可以用在下面的語句設置中 --> <resultMap id="GetAllProductsResult" class="Product"> <result property="ProductId" type="int" column="ProductId" dbType="int" /> <result property="ProductName" type="string" column="ProductName" dbType="nvarchar" /> </resultMap> </resultMaps>
3.3 SQL 定義
在 MyBatisNet 中,SQL 不用寫在代碼中,而是寫在映射文件中。
下面提供了兩個查詢定義,注意每個查詢的 id 不同,以后在代碼中,通過這個 id 來查詢對應的 SQL 語句。
resultClass 和 resultMap 用來配置查詢結果應該轉化為何種類型的對象實例,映射的名字就是 3.2 中定義的映射名。
<![CDATA[ 和 ]]> 是 XML 中對於不需轉義的內容的特殊標識形式,等同於 C# 中字符串之前的 @ 符號,比較特殊一點。
<statements> <!-- resultClass 直接設置返回的類型 --> <!-- resultMap 通過映射設置返回類型 --> <select id="GetAllProducts" resultMap="GetAllProductsResult"> <![CDATA[ SELECT productid, productname FROM [Production].Products ]]> </select> <select id="GetProductById" parameterClass="int" resultMap="GetAllProductsResult"> <![CDATA[ select productid, productname from [Production].Products where productid = #value# ]]> </select> </statements>
完整的映射配置如下所示:
<?xml version="1.0" encoding="utf-8" ?> <sqlMap namespace="EntityModel" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <alias> <typeAlias alias="Product" type="EntityModel.Product, EntityModel"/> </alias> <resultMaps> <!-- 映射可以用在下面的語句設置中 --> <resultMap id="GetAllProductsResult" class="Product"> <result property="ProductId" type="int" column="ProductId" dbType="int" /> <result property="ProductName" type="string" column="ProductName" dbType="nvarchar" /> </resultMap> </resultMaps> <statements> <!-- resultClass 直接設置返回的類型 --> <!-- resultMap 通過映射設置返回類型 --> <select id="GetAllProducts" resultMap="GetAllProductsResult"> <![CDATA[ SELECT productid, productname FROM [Production].Products ]]> </select> <select id="GetProductById" parameterClass="int" resultMap="GetAllProductsResult"> <![CDATA[ select productid, productname from [Production].Products where productid = #value# ]]> </select> </statements> </sqlMap>
4. 數據訪問的配置信息 Providers.config
訪問不同類型的數據庫,需要用到一些不同的類型和寫法,這些信息 MyBatisNet 已經幫我們准備好了,providers.config 文件就是,我們並不需要做什么。
唯一需要注意的就是對於我們需要使用的數據訪問類型,必須將 enabled 配置為 true。
比如,你希望使用 SQL2005 方式,那么就將這一段的 enabled 設置為 true.
需要記住你使用的提供器的 name, 在后面會使用到的。
<provider name="sqlServer2005" enabled="true" description="Microsoft SQL Server, provider V2.0.0.0 in framework .NET V2.0" assemblyName="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" connectionClass="System.Data.SqlClient.SqlConnection" commandClass="System.Data.SqlClient.SqlCommand" parameterClass="System.Data.SqlClient.SqlParameter" parameterDbTypeClass="System.Data.SqlDbType" parameterDbTypeProperty="SqlDbType" dataAdapterClass="System.Data.SqlClient.SqlDataAdapter" commandBuilderClass=" System.Data.SqlClient.SqlCommandBuilder" usePositionalParameters = "false" useParameterPrefixInSql = "true" useParameterPrefixInParameter = "true" parameterPrefix="@" allowMARS="true" />
5. 將一切配置粘在一起 SqlMap.config
SqlMap.config 是 MyBatisNet 的頂級配置文件,各個部分通過它粘和在一起。
5.1 屬性定義
屬性類似於程序中的變量,定義之后,可以在后面的配置中使用名稱來表示其中的值,這樣,以后我們就可以直接修改變量了。
定義之后,在使用的使用通過 ${屬性名} 使用。比如,在后面的數據庫連接串中,就可以直接使用屬性名了。
<!-- 屬性可以在后面使用, 使用的時候通過 ${屬性名引用} --> <properties> <property key="datasource" value=".\sqlexpress" /> <property key="database" value="TSQLFundamentals2008" /> <property key="selectKey" value="select scope_identity() as value" /> <property key="directory" value="MapFiles" /> <property key="useStatementNamespaces" value="false" /> </properties>
5.2 設置參數
配置 MyBatisNet 的一些參數
<!--Basic Setting About Configuration--> <settings> <setting useStatementNamespaces="false"/> <setting cacheModelsEnabled="true"/> </settings>
5.3 Providers.config 的來源
還記得 4 中的數據訪問的配置信息嗎?我們保存在一個文件中,這里配置如何找到它。
<!-- 設置 provider 文件的來源,這個文件一般直接使用 myBatisNet 提供的文件 --> <providers resource="providers.config"/>
5.4 數據庫連接
數據庫連接串,數據庫連接使用的 provider ,這個名字就是我們在 4 中曾經啟用的那個。
<!--數據庫連接--> <database> <!-- provider 名字來自文件 providers.config 這個文件由 myBatisNet提供,直接使用即可 注意:這里使用的 provider 需要在 providers.config 中設置為啟用 enabled="true" --> <provider name="sqlServer2005" /> <dataSource name="iBatisNet" connectionString="data source=${datasource};database=${database};integrated security=true;" /> </database>
5.5 SQL 映射文件的來源
這里直接使用文件格式,注意要將文件復制到程序的執行目錄下。
<!-- 映射文件位置 --> <sqlMaps> <sqlMap resource="Maps/ProductMap.xml"/> </sqlMaps>
完整的配置文件如下:
<?xml version="1.0" encoding="utf-8" ?> <sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"> <!-- 屬性可以在后面使用, 使用的時候通過 ${屬性名引用} --> <properties> <property key="datasource" value=".\sqlexpress" /> <property key="database" value="TSQLFundamentals2008" /> <property key="selectKey" value="select scope_identity() as value" /> <property key="directory" value="MapFiles" /> <property key="useStatementNamespaces" value="false" /> </properties> <!--Basic Setting About Configuration--> <settings> <setting useStatementNamespaces="false"/> <setting cacheModelsEnabled="true"/> </settings> <!-- 設置 provider 文件的來源,這個文件一般直接使用 myBatisNet 提供的文件 --> <providers resource="providers.config"/> <!--數據庫連接--> <database> <!-- provider 名字來自文件 providers.config 這個文件由 myBatisNet提供,直接使用即可 注意:這里使用的 provider 需要在 providers.config 中設置為啟用 enabled="true" --> <provider name="sqlServer2005" /> <dataSource name="iBatisNet" connectionString="data source=${datasource};database=${database};integrated security=true;" /> </database> <!-- 映射文件位置 --> <sqlMaps> <sqlMap resource="Maps/ProductMap.xml"/> </sqlMaps> </sqlMapConfig>
6. 使用 ISqlMapper 訪問數據
在 MyBatisNet 中,我們需要獲取 ISqlMapper 對象來訪問數據,這個對象 MyBatisNet 中已經定義了一個靜態方法,我們可以直接使用。
IBatisNet.DataMapper.Mapper.Instance()
使用注入方式,定義如下的數據訪問對象。
public class ProductDao { // private static SqlMapper sqlMapper = null; public ISqlMapper Mapper { set; get; } static ProductDao() { // 現在 IBatisNet.DataMapper.Mapper.Instance() 內部就已經完成了下面的操作 // DomSqlMapBuilder builder = new DomSqlMapBuilder(); // sqlMapper = builder.Configure() as SqlMapper; } public IList<EntityModel.Product> GetProductList() { IList<EntityModel.Product> productList = Mapper.QueryForList<EntityModel.Product>("GetAllProducts", null); return productList; } public EntityModel.Product GetProductById(int id) { EntityModel.Product product = Mapper.QueryForObject<EntityModel.Product>("GetProductById", 1); return product; } }
其中 Mapper 等待注入,查詢單個對象使用了 Mapper 的 QueryForObject 泛型方法,查詢多個對象使用了 QueryForList 方法,參數就是 SQL 映射中定義的 id。
7. 訪問數據
主程序中創建數據訪問對象,注入 Mapper ,完成數據訪問。
DataMapperStart.ProductDao crud = new DataMapperStart.ProductDao(); // 默認配置文件使用 SqlMap.config crud.Mapper = IBatisNet.DataMapper.Mapper.Instance(); EntityModel.Product p = crud.GetProductById(1); Console.WriteLine(p.ProductName); Console.WriteLine(); IList<EntityModel.Product> list = crud.GetProductList(); foreach (EntityModel.Product product in list) { Console.WriteLine("Product Id: {0}, Name: {0}", product.ProductId, product.ProductName); }
總結:
看起來步驟很多,實際上主要涉及到三個配置文件,代碼非常的簡單。MyBatisNet 提供了 XML 的架構文件,在 VS 中可以實現 XML 的提示,寫起來其實很方便。