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 的提示,写起来其实很方便。

点击下载示例代码

原文地址:https://www.cnblogs.com/haogj/p/2575436.html