65.9K
CodeProject 正在变化。 阅读更多。
Home

MyBatis.NET

starIconstarIconstarIconstarIconemptyStarIcon

4.00/5 (3投票s)

2015 年 4 月 6 日

CPOL

4分钟阅读

viewsIcon

91084

downloadIcon

4302

MyBatis.NET 作为数据映射器

引言

在本文中,我将向您展示一个简单的 C# 演示应用程序,用于使用 MyBatis.NET 作为数据映射器来访问 SQL SERVER。在深入编码之前,让我们先了解一下 MyBatis.NET 是什么以及为什么我们应该使用它。

什么是 MyBatis.NET

MyBatis 是一个数据映射工具。它将数据库查询(包括存储过程)的列映射到业务对象的属性。映射器的一个定义是“一个设置两个独立对象之间通信的对象。数据映射器是‘映射器层,它在对象和数据库之间移动数据,同时保持它们彼此独立以及与映射器本身无关。”

当您的应用程序分层,并且业务层可以与 UI 层分离时,MyBatis 是一个不错的选择。您提供数据库和对象;MyBatis 提供位于两者之间的映射层。

为什么选择 MyBatis.NET

.NET 平台已经提供了一个功能强大的库来访问数据库,无论是通过 SQL 语句还是存储过程,但在使用 ADO.NET 时,有几件事仍然很难做好,包括:

  • 将 SQL 代码与编程代码分离
  • 将输入参数传递给库类并提取输出
  • 将数据访问类与业务逻辑类分离
  • 缓存经常使用的数据直到其更改
  •  管理事务和线程

iBATIS DataMapper 通过使用 XML 文档在普通对象和 SQL 语句或存储过程之间创建映射来解决这些问题——以及更多问题。“普通对象”可以是 IDictionary 或属性对象。

背景

您可能到处都看到“MyBatis”和“iBatis”这两个名称被互换使用,因为 MyBatis 在 2010 年 5 月 19 日之前以“iBatis”的名称在 Apache 基金会下开发,然后“iBatis”项目迁移到 Google Code,并更名为“MyBatis”。最初,MyBatis 是为 Java 开发的,最近 .NET 版本被称为 MyBatis.NET。

使用代码

这是一个简单的演示应用程序,它不包含 MyBatis.NET 的所有功能。对于那些希望在其应用程序中将 MyBatis.NET 用作数据库和业务对象之间的数据映射器的人来说,这是一个很好的起点。在此演示中,我使用的是 SQL SERVER,但您也可以使用 MyBatis 支持的任何其他流行数据库。

 下图显示了 MyBatis.NET 数据映射器的工作流程。

 

数据映射器工作所需的第一件事是数据映射定义文件(sqlMap.config)。我已经创建了如下数据映射定义文件:

<span style="color: rgb(17, 17, 17); font-family: 'Segoe UI', Arial, sans-serif; font-size: 14px;"><?xml version="1.0" encoding="utf-8" ?></span>

<sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

  <settings>
    <setting useStatementNamespaces="false" />
    <setting cacheModelsEnabled="true" />
    <setting validateSqlMap="true" />
  </settings>

  <database>
    <provider name="sqlServer2.0" />
    <dataSource name="MtBatisSQL" connectionString="Data Source=MachineName\SQL2008R2;Initial Catalog=MyBatisNet;Integrated Security=True"/>
  </database>

  <sqlMaps>
    <sqlMap embedded="sqlFile.xml, MyBatisDataMapper" />
  </sqlMaps>
</sqlMapConfig>

第一部分设置参数,然后设置提供程序和数据源,最后是 SQL 映射。在这种情况下,所有映射都存储在单独的文件 sqlFile.xml 中,如下所示。

<?xml version="1.0" encoding="utf-8" ?>
<sqlMap namespace="MyBatisApp" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >

  <statements>
    <statement id="FindDepartment" parameterClass="System.Int32" resultClass="System.String" >
      SELECT Name
      FROM Department
      WHERE Id =  #value#
    </statement>
    <procedure id="GetEmployees" parameterMap="get-employees-params"  resultMap="get-employee-result">
      GetEmployees
    </procedure>
  </statements>
  <parameterMaps>
  <parameterMap id="get-employees-params">
    <parameter property="Id" column="DepartmentId" />
  </parameterMap>
  </parameterMaps>
  <resultMaps>
    <resultMap id="get-employee-result" class="model.Employee">
      <result property="Id" column="Id" dbType="Int"/>
      <result property="Name" column="Name" dbType="Varchar"/>
      <result property="Age" column="Age" dbType="Varchar"/>
      <result property="DepartmentId" column="DepartmentId" dbType="Int"/>
    </resultMap>
  </resultMaps>
</sqlMap>

正如您所见,我使用 SELECT 查询创建了一个简单的 FindDepartment 语句,该语句接受部门 ID 作为 int 并返回部门名称作为字符串。

还有一个存储过程 GetEmployees,它使用 parameterMap 和 resultsMap。参数映射用于在执行存储过程之前将参数属性(此处为 id)映射到存储过程中的列参数(此处为 DepartmentId)。另一方面,结果映射将存储过程的结果(结果集中的列)映射到对象(Employee 对象中的属性)。

在我们开始编码之前,我们需要更多配置文件。请记住,在 sqlMap.config 文件中,数据库元素需要提供程序和数据源。提供程序只不过是连接到指定数据库的驱动程序信息。在上面的配置中,我们指定了:

<provider name="sqlServer2.0" />

我们可以根据部署环境拥有任意数量的提供程序,并根据需要更改提供程序。以下是我们即将使用的提供程序:

<?xml version="1.0" encoding="utf-8"?>

<providers 
xmlns="http://ibatis.apache.org/providers" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">

<clear/>
<provider
    name="sqlServer2.0"
    enabled="true"
    default="false" 
    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"
    />

  <provider
    name="sqlServer4.0"
    enabled="true"
    default="true"
    description="Microsoft SQL Server, provider V4.0.0.0 in framework .NET V4.0"
    assemblyName="System.Data, Version=4.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"
    />

</providers>

 

现在让我们开始用 C# 编码。要访问任何映射的 SQL 语句或存储过程,我们需要从我们提供的配置中获取 SqlMapper 实例。以下代码显示了如何获取 SqlMapper 实例:

public static ISqlMapper EntityMapper
        {
            get
            {
                try
                {
                    ISqlMapper mapper = Mapper.Instance();
                    return mapper;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        } 

ISqlMapper 可从引用的库 IBatisNet.DataMapper.dll 获得。现在实例可用,我们可以如下执行语句和存储过程:

 

        public static List<model.Employee> getEmployees(model.Department department)
        {

            ISqlMapper mapper = EntityMapper;

            List<model.Employee> employees = mapper.QueryForList<model.Employee>("GetEmployees", department).ToList();
            return employees;

        }

        public static string FindDepartment(int deptId){

            ISqlMapper mapper = EntityMapper;
            string str = mapper.QueryForObject<string>("FindDepartment", deptId);
            return str;

        }
            //Find Department
            string deptName = FindDepartment(1);
            Console.WriteLine(deptName);
            Console.Read();
            
            // Get Employees
            model.Department dep = new model.Department();
            dep.Id = 1;
            List<model.Employee> emps = getEmployees(dep);
            Console.ReadLine();

 

无论是语句还是 SP,在执行代码方面都没有区别。唯一的区别是,如果结果类型是列表,那么我们必须使用 QueryForList 而不是 QueryForObject。这只是为了展示 MyBatis.NET 如何用作数据库和业务对象之间的数据映射器。MyBatis.NET 提供的功能比我们在本次演示中看到的要多得多。它支持事务,包括分布式事务。

可以清楚地看出,数据访问代码非常干净整洁,没有分散在代码中的 SQL 语句或存储过程来访问数据库数据。它纯粹使用对象及其方法。

延伸阅读

https://mybatis.github.io/mybatis-3/

 

© . All rights reserved.