MyBatis实现CRUD

from:  /792419/459684

说明:这是一个系列文章,在前面的四篇当中周公分别讲述了利用ADO.NET、NHibernate、Linq to SQL及EntityFramework来实现CRUD功能(C:Create/R:Read/U:Update/D:Delete),在这里再讲述另一种框架,那就是MyBatisNet。MyBatisNet源自于iBatisNet,而iBatisNet又是受了Java平台上的iBatis的影响。
iBatis及iBatis.NET都是利用XML描述来执行存储过程或者SQL语句。与其它ORM框架相比,简单易学是iBatis及iBatis.NET的最大特点,简单易学并不意味着它们功能简单,实际上它们能提供强大的功能。不过iBatis及iBatis.NET现在已经分别更名为MyBatis和MyBatis.NET,它们原来的官方网站

一、准备
要想在项目中使用MyBatisNet,就需要到它的官方网站IBatisNet.Common.Logging.Log4Net.dll
IBatisNet.DataAccess.dll
IBatisNet.DataMapper.dll
log4net.dll
同时MyBatis还提供了一些辅助文件,如IBatisNet.Common.Logging.Log4Net.xml、IBatisNet.Common.xml、IBatisNet.DataAccess.xml、log4net.xml及IBatisNet.DataMapper.xml,将这些文件拷贝到VS的相应目录就可以在编写代码时获得程序的API说明,这个位置就是你的.NET Framework的安装目录,比如系统盘是C盘,这个位置就是C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\zh-CN。除此之外,还有一些xsd文件,如provider.xsd、SqlMap.xsd及SqlMapConfig.xsd,这些文件都是对应的xml文件的验证文件,利用这些文件就可以在VS中编辑这些文件时获得智能感知,从而减少出错的机会。假设你的系统是安装在C盘,如果你使用的是VS2005,那么就把这些文件拷贝到C:\Program Files\Microsoft Visual Studio 8\Xml\Schemas;如果你使用的是VS2008,那么就拷贝到C:\Program Files\Microsoft Visual Studio 9.0\Xml\Schemas;如果你使用的是VS2010,那么就拷贝到C:\Program Files\Microsoft Visual Studio 10.0\Xml\Schemas。

除了上面的准备工作之外,我们还需要几个配置文件,分别如下:
Providers.config文件
这个文件可以从下载的MyBatis压缩包中找到,它包含了常用数据库驱动程序清单,里面一个典型的节点如下:

 
 
  1. <provider 
  2.    name="sqlServer2005" 
  3.    enabled="true" 
  4.    description="Microsoft SQL Server, provider V2.0.0.0 in framework .NET V2.0"   
  5.    assemblyName="System.Data, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"   
  6.    connectionClass="System.Data.SqlClient.SqlConnection"   
  7.    commandClass="System.Data.SqlClient.SqlCommand" 
  8.    parameterClass="System.Data.SqlClient.SqlParameter" 
  9.    parameterDbTypeClass="System.Data.SqlDbType" 
  10.    parameterDbTypeProperty="SqlDbType" 
  11.    dataAdapterClass="System.Data.SqlClient.SqlDataAdapter" 
  12.    commandBuilderClass=" System.Data.SqlClient.SqlCommandBuilder" 
  13.    usePositionalParameters = "false" 
  14.    useParameterPrefixInSql = "true" 
  15.    useParameterPrefixInParameter = "true"   
  16.    parameterPrefix="@" 
  17.    allowMARS="true" 
  18.   /> 

这段XML代码想必大家也能猜得到大部分的属性的意思,在这里周公只讲两个需要注意的地方,一个是enabled属性,如果要启用某个数据库驱动就要将它的值设为true,还有一个就是parameterPrefix属性,表示参数化SQL语句中参数的前缀。

SqlMap.config文件
这是一个有关当前数据库信息及实体映射文件配置的文件。在这个文件里我们可以指定数据库连接的信息(账号、密码及主机等),还可以指定实体映射文件。
关于数据库连接的信息可以采用如下方式的配置:
首先在<properties>节点配置有关数据库连接的信息,在本实例中周公的配置如下:

 
 
  1. <properties> 
  2.   <property key="userid" value="sa" /> 
  3.   <property key="password" value="root" /> 
  4.   <property key="database" value="AspNetStudy" /> 
  5.   <property key="datasource" value="netskycn\SQL2005" /> 
  6.   <property key="selectKey" value="select @@IDENTITY as value" /> 
  7.   <property key="directory" value="MapFiles" /> 
  8.   <property key="useStatementNamespaces" value="false" /> 
  9. </properties> 

上面的大部分属性的意思可以猜测得出来,唯一周公觉得需要说明的是selectKey属性,这是解决插入记录之后获取自增字段主键的值的,在不同的数据库中这个SQL语句可能会不同。
接着在<database>节点中使用这些属性,在周公的运行环境中<database>节点值如下:

 
 
  1. <database> 
  2.   <provider name="sqlServer2005"/> 
  3.   <!--<dataSource name="iBatisNet" connectionString="data source=netskycn\SQL2005;database=AspNetStudy;user id=sa;password=root;"/>--> 
  4.   <dataSource name="iBatisNet" connectionString="data source=${datasource};database=${database};user id=${userid};password=${password};"/> 
  5. </database> 

当然,你也可以采用那种被注释的方式,也就是直接将连接字符串写好,而不是采用未注释的方式,不过个人感觉未注释的方式稍微容易维护一些,一旦数据库连接信息发生变动,集中修改<properties>节点中的值就可以了。
最后需要解决的是实体映射文件的问题。和NHibernate一样,MyBatis也是通过XML文件来解决数据记录与实体之间的映射关系的,关于这些映射文件如何编写周公稍后再说。这里要说的是在SqlMap.config文件中可以有两种方式引入外部的文件,一种是通过资源的方式,在文件中表现为resource,如<providers resource="providers.config"/>,另外一种嵌入式资源的方式,在文件中表现为embedded,如<sqlMap embedded="MapFiles.UserInfo.xml,MyBatisNetDemo"/>,这就需要将该文件设置为嵌入式资源,如下图所示:

 
在本项目中有一个实体类,它就是MyBatisNetDemo程序集中的UserInfo类,它对应的XML映射文件是项目中的MapFiles文件下的UserInfo.xml。
在SqlMap.config文件中这部分的配置如下:

 
 
  1. <sqlMaps> 
  2.   <sqlMap embedded="MapFiles.UserInfo.xml,MyBatisNetDemo"/> 
  3. </sqlMaps> 

App.config文件
为了调试时能得到运行过程中的相关信息,需要配置Log4Net,关于Log4Net的用法周公博客上有详尽的说明,这里就不在赘述了。在本项目中App.config文件的内容如下:

 
 
  1. <?xml version="1.0" encoding="utf-8" ?> 
  2. <configuration> 
  3.   <configSections> 
  4.     <sectionGroup name="iBATIS"> 
  5.       <section name="logging" type="IBatisNet.Common.Logging.ConfigurationSectionHandler, IBatisNet.Common" /> 
  6.     </sectionGroup> 
  7.     <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> 
  8.   </configSections> 
  9.   <iBATIS> 
  10.     <logging> 
  11.       <logFactoryAdapter type="IBatisNet.Common.Logging.Impl.Log4NetLoggerFA, IBatisNet.Common.Logging.Log4Net"> 
  12.         <arg key="configType" value="inline" /> 
  13.         <arg key ="showLogName" value="true" /> 
  14.         <arg key ="showDataTime" value="true" /> 
  15.         <arg key ="level" value="ALL" /> 
  16.         <arg key ="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:SSS" /> 
  17.       </logFactoryAdapter> 
  18.     </logging> 
  19.   </iBATIS> 
  20.   <!-- 下面的节点定义log4net --> 
  21.   <log4net> 
  22.     <!-- 定义输出的appenders --> 
  23.     <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender"> 
  24.       <param name="File" value="iBatisNet_log.txt" /> 
  25.       <param name="AppendToFile" value="true" /> 
  26.       <param name="MaxSizeRollBackups" value="2" /> 
  27.       <param name="MaximumFileSize" value="100KB" /> 
  28.       <param name="RollingStyle" value="Size" /> 
  29.       <param name="StaticLogFileName" value="true" /> 
  30.       <layout type="log4net.Layout.PatternLayout"> 
  31.         <param name="Header" value="[Header]\r\n" /> 
  32.         <param name="Footer" value="[Footer]\r\n" /> 
  33.         <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" /> 
  34.       </layout> 
  35.     </appender> 
  36.     <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender"> 
  37.       <layout type="log4net.Layout.PatternLayout"> 
  38.         <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] &lt;%X{auth}&gt; - %m%n" /> 
  39.       </layout> 
  40.     </appender> 
  41.     <!-- Set root logger level to ERROR and its appenders --> 
  42.     <root> 
  43.       <level value="DEBUG" /> 
  44.       <appender-ref ref="RollingLogFileAppender" /> 
  45.       <appender-ref ref="ConsoleAppender" /> 
  46.     </root> 
  47.  
  48.     <!-- Print only messages of level DEBUG or above in the packages --> 
  49.     <logger name="IBatisNet.DataMapper.Configuration.Cache.CacheModel"> 
  50.       <level value="DEBUG" /> 
  51.     </logger> 
  52.     <logger name="IBatisNet.DataMapper.Configuration.Statements.PreparedStatementFactory"> 
  53.       <level value="DEBUG" /> 
  54.     </logger> 
  55.     <logger name="IBatisNet.DataMapper.LazyLoadList"> 
  56.       <level value="DEBUG" /> 
  57.     </logger> 
  58.     <logger name="IBatisNet.DataAccess.DaoSession"> 
  59.       <level value="DEBUG" /> 
  60.     </logger> 
  61.     <logger name="IBatisNet.DataMapper.SqlMapSession"> 
  62.       <level value="DEBUG" /> 
  63.     </logger> 
  64.     <logger name="IBatisNet.Common.Transaction.TransactionScope"> 
  65.       <level value="DEBUG" /> 
  66.     </logger> 
  67.     <logger name="IBatisNet.DataAccess.Configuration.DaoProxy"> 
  68.       <level value="DEBUG" /> 
  69.     </logger> 
  70.   </log4net> 
  71. </configuration> 

做了上面的配置之外,还需要添加相关的dll引用,在本项目中所使用到的dll引用如下图所示:

 
至此,我们已经做好了所有的准备工作,可以进行下一步的编码工作了。

二、编码
编写实体类代码
在本项目中采用的数据表结构与本系列的第一篇一样(便于比较),如下:

 
 
  1. CREATE TABLE [dbo].[UserInfo](  
  2.         [UserID] [int] IDENTITY(1,1) NOT NULL,  
  3.         [UserName] [varchar](20) COLLATE Chinese_PRC_CI_AS NOT NULL,  
  4.         [RealName] [nvarchar](8) COLLATE Chinese_PRC_CI_AS NOT NULL,  
  5.         [Age] [tinyint] NOT NULL,  
  6.         [Sex] [bitNOT NULL,  
  7.         [Mobile] [char](11) COLLATE Chinese_PRC_CI_AS NULL,  
  8.         [Phone] [char](11) COLLATE Chinese_PRC_CI_AS NULL,  
  9.         [Email] [varchar](50) COLLATE Chinese_PRC_CI_AS NOT NULL,  
  10.      CONSTRAINT [PK_UserInfo] PRIMARY KEY CLUSTERED   
  11.     (  
  12.         [UserID] ASC 
  13.     )WITH (IGNORE_DUP_KEY = OFF)  
  14.     ) 

所对应的实体类的代码如下:

 
 
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4.  
  5. namespace MyBatisNetDemo  
  6. {  
  7.     public class UserInfo  
  8.     {  
  9.         /// <summary>  
  10.         /// 用户编号  
  11.         /// </summary>  
  12.         public int UserID { getset; }  
  13.         /// <summary>  
  14.         /// 用户名  
  15.         /// </summary>  
  16.         public string UserName { getset; }  
  17.         /// <summary>  
  18.         /// 真实姓名  
  19.         /// </summary>  
  20.         public string RealName { getset; }  
  21.         /// <summary>  
  22.         /// 年龄  
  23.         /// </summary>  
  24.         public byte Age { getset; }  
  25.         /// <summary>  
  26.         /// 性别  
  27.         /// </summary>  
  28.         public bool Sex { getset; }  
  29.         /// <summary>  
  30.         /// 电子邮件  
  31.         /// </summary>  
  32.         public string Email { getset; }  
  33.         /// <summary>  
  34.         /// 手机号  
  35.         /// </summary>  
  36.         public string Mobile { getset; }  
  37.         /// <summary>  
  38.         /// 电话  
  39.         /// </summary>  
  40.         public string Phone { getset; }  
  41.     }  

编写映射文件
前面说到了映射文件是数据库记录与实体类之间的桥梁,它指示了数据库字段与实体类属性之间如何建立联系,并且还指示了MyBatis如何去操作数据库。在本项目中的UserInfo.xml文件内容如下:

 
 
  1. <?xml version="1.0" encoding="utf-8" ?> 
  2. <sqlMap namespace="UserInfo" xmlns="/attachment/201012/214039647.jpg" target="_blank">

    三、单元测试代码
    为了照顾很多仍在使用NUnit作为单元测试工具的开发人员的习惯,我们的单元测试代码针对NUnit2.5.3,代码如下:

     
       
    1. using System;  
    2. using System.Collections.Generic;  
    3. using System.Linq;  
    4. using System.Text;  
    5. using NUnit.Framework;  
    6. using MyBatisNetDemo;  
    7.  
    8. namespace NUnitTest  
    9. {  
    10.     [TestFixture]  
    11.     public class MyBatisNetTest  
    12.     {  
    13.         private MyBatisNetCRUD instance = null;  
    14.         [SetUp]  
    15.         public void Initialize()  
    16.         {  
    17.             instance = new MyBatisNetCRUD();  
    18.         }  
    19.         [Test]  
    20.         public void Count()  
    21.         {  
    22.             Assert.Greater(instance.Count(), 0);  
    23.         }  
    24.         [Test]  
    25.         public void Create()  
    26.         {  
    27.             UserInfo userInfo = new MyBatisNetDemo.UserInfo { UserName = "www1", Age = 40, Email = "zhoufoxcn1@gmail.com", Mobile = "13567891234", Phone = "02786543210", RealName = "test", Sex = false };  
    28.  
    29.             Assert.True(instance.Create(userInfo));  
    30.         }  
    31.         [Test]  
    32.         public void Read()  
    33.         {  
    34.             UserInfo info =instance.Read(2);  
    35.             //Assert.IsNotNull(info);  
    36.             Assert.AreEqual(info.UserID, 2);  
    37.         }  
    38.         [Test]  
    39.         public void GetUserList()  
    40.         {  
    41.             IList<UserInfo> userList = instance.GetUserList();  
    42.             Assert.Greater(userList.Count,0);  
    43.         }  
    44.  
    45.         [Test]  
    46.         public void GetUserListPaging()  
    47.         {  
    48.             IList<UserInfo> userList = instance.GetUserList(10,20);  
    49.             Assert.Greater(userList.Count, 0);  
    50.         }  
    51.  
    52.         [Test]  
    53.         public void Update()  
    54.         {  
    55.             UserInfo info = instance.Read(1);  
    56.             Assert.True(instance.Update(info));  
    57.         }  
    58.         [Test]  
    59.         public void Delete()  
    60.         {  
    61.             int maxUserId = instance.GetMaxUserId();  
    62.             Assert.True(instance.Delete(maxUserId));  
    63.         }  
    64.         [Test]  
    65.         public void GetMaxUserId()  
    66.         {  
    67.             int result = instance.GetMaxUserId();  
    68.             Assert.True(result > 0);  
    69.         }  
    70.     }  

    上面的代码在NUnit2.5.3中测试通过。
    四、总结
    作为一种数据库与实体类的映射框架二不是一个ORM框架,和ADO.NET相比MyBatis不用太多考虑ADO.NET的细节(比如是用SqlConnection还是用OleDbConnecion,还有如何打开和关闭数据库连接等),因而比较容易跨数据库;和NHibernate这样的ORM相比它又能让我们更多地操纵如何与数据库交互,性能上更容易控制一些(前提是必须有比较精通书库的开发人员或者DBA),同时它也比NHibernate更容易学习一些。
    当然MyBatis也有它的一些不足,比如在UserInfo.xml中我们要编写大量的SQL语句和添加很多<select>、<insert>、<update>、<delete>节点,当然这些不足可以通过一个自动代码生成工具来解决。
    从个人选择上来说,我更愿意选择MyBatisNet,今后的项目中我可能会更多的使用MyBatisNet。另外从我一个在银行从事开发的朋友得到的反馈,他们用Java做银行项目选择的也是MyBatisNet的Java版——MyBatis,这是出于对性能的考虑。
    没有最好的,只有最合适的。如何选择合适的技术,取决于我们队将要运行的环境的判断,这来自于经验分析。周公
    2010-12-17

转载于:https://www.cnblogs.com/chaunqi/archive/2011/01/20/tt79.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
【优质项目推荐】 1、项目代码均经过严格本地测试,运行OK,确保功能稳定后才上传平台。可放心下载并立即投入使用,若遇到任何使用问题,随时欢迎私信反馈与沟通,博主会第一时间回复。 2、项目适用于计算机相关专业(如计科、信息安全、数据科学、人工智能、通信、物联网、自动化、电子信息等)的在校学生、专业教师,或企业员工,小白入门等都适用。 3、该项目不仅具有很高的学习借鉴价值,对于初学者来说,也是入门进阶的绝佳选择;当然也可以直接用于 毕设、课设、期末大作业或项目初期立项演示等。 3、开放创新:如果您有一定基础,且热爱探索钻研,可以在此代码基础上二次开发,进行修改、扩展,创造出属于自己的独特应用。 欢迎下载使用优质资源!欢迎借鉴使用,并欢迎学习交流,共同探索编程的无穷魅力! 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip 基于业务逻辑生成特征变量python实现源码+数据集+超详细注释.zip
提供的源码资源涵盖了安卓应用、小程序、Python应用和Java应用等多个领域,每个领域都包含了丰富的实例和项目。这些源码都是基于各自平台的最新技术和标准编写,确保了在对应环境下能够无缝运行。同时,源码中配备了详细的注释和文档,帮助用户快速理解代码结构和实现逻辑。 适用人群: 这些源码资源特别适合大学生群体。无论你是计算机相关专业的学生,还是对其他领域编程感兴趣的学生,这些资源都能为你提供宝贵的学习和实践机会。通过学习和运行这些源码,你可以掌握各平台开发的基础知识,提升编程能力和项目实战经验。 使用场景及目标: 在学习阶段,你可以利用这些源码资源进行课程实践、课外项目或毕业设计。通过分析和运行源码,你将深入了解各平台开发的技术细节和最佳实践,逐步培养起自己的项目开发和问题解决能力。此外,在求职或创业过程中,具备跨平台开发能力的大学生将更具竞争力。 其他说明: 为了确保源码资源的可运行性和易用性,特别注意了以下几点:首先,每份源码都提供了详细的运行环境和依赖说明,确保用户能够轻松搭建起开发环境;其次,源码中的注释和文档都非常完善,方便用户快速上手和理解代码;最后,我会定期更新这些源码资源,以适应各平台技术的最新发展和市场需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值