mybatisnet - 2 使用 DataMapper 訪問數據庫


首先,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 的提示,寫起來其實很方便。

點擊下載示例代碼

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM