Ibatisnet Quick Start

准备工作

1. 下载ibatis软件包(http://ibatis.apache.org/dotnetdownloads.html)。

2. 创建测试数据库,并在数据库中创建一个Person 表,其中包含三个字段:

Name Type Size

PER_ID Long Integer 4 not null

PER_FIRST_NAME nvarchar 40 not null

PER_LAST_NAME nvarchar 40 not null

PER_BIRTH_DATE DateTime 8

PER_WEIGHT_KG float 8

PER_HEIGHT_M float 8

3. 为了在开发过程更加直观,我们需要将ibatisnet日志打开以便观察ibatinets运作的细节。

ibatisnet采用IBatisNet.Common.Logging.Log4Net,就是使用Log4Net纪录日志的包装。在Web.config中增加下面的配置内容:

<configSections>
 <sectionGroup name="iBATIS">
 <section name="logging" type="IBatisNet.Common.Logging.ConfigurationSectionHandler, IBatisNet.Common" />
 </sectionGroup>
 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" />
</configSections>
<iBATIS>
 <logging> 
 <logFactoryAdapter type="IBatisNet.Common.Logging.Impl.Log4NetLoggerFA, IBatisNet.Common.Logging.Log4Net">
 <arg key="configType" value="inline" />
 <arg key ="showLogName" value="true" />
 <arg key ="showDataTime" value="true" />
 <arg key ="level" value="ALL" />
 <arg key ="dateTimeFormat" value="yyyy/MM/dd HH:mm:ss:SSS" />
 </logFactoryAdapter> 
 </logging>
 </iBATIS> 
 <!-- This section contains the log4net configuration settings -->
 <log4net>
 <!-- Define some output appenders -->
 <appender name="RollingLogFileAppender" type="log4net.Appender.RollingFileAppender">
 <param name="File" value="log.txt" />
 <param name="AppendToFile" value="true" />
 <param name="MaxSizeRollBackups" value="2" />
 <param name="MaximumFileSize" value="100KB" />
 <param name="RollingStyle" value="Size" />
 <param name="StaticLogFileName" value="true" />
 <layout type="log4net.Layout.PatternLayout">
 <param name="Header" value="[Header]\r\n" />
 <param name="Footer" value="[Footer]\r\n" />
 <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] - %m%n" />
 </layout>
 </appender>
 <appender name="ConsoleAppender" type="log4net.Appender.ConsoleAppender">
 <layout type="log4net.Layout.PatternLayout">
 <param name="ConversionPattern" value="%d [%t] %-5p %c [%x] &lt;%X{auth}&gt; - %m%n" />
 </layout>
 </appender> 
 <!-- Set root logger level to ERROR and its appenders -->
 <root>
 <level value="DEBUG" />
 <appender-ref ref="RollingLogFileAppender" />
 <appender-ref ref="ConsoleAppender" />
 </root>
 <!-- Print only messages of level DEBUG or above in the packages -->
 <logger name="IBatisNet.DataMapper.Configuration.Cache.CacheModel">
 <level value="DEBUG" />
 </logger>
 <logger name="IBatisNet.DataMapper.Configuration.Statements.PreparedStatementFactory">
 <level value="DEBUG" />
 </logger>
 <logger name="IBatisNet.DataMapper.LazyLoadList">
 <level value="DEBUG" />
 </logger>
 <logger name="IBatisNet.DataAccess.DaoSession">
 <level value="DEBUG" />
 </logger>
 <logger name="IBatisNet.DataMapper.SqlMapSession">
 <level value="DEBUG" />
 </logger>
 <logger name="IBatisNet.Common.Transaction.TransactionScope">
 <level value="DEBUG" />
 </logger>
 <logger name="IBatisNet.DataAccess.Configuration.DaoProxy">
 <level value="DEBUG" />
 </logger>
 </log4net>

构建IBatisNet基础代码

IBatisNet 基础代码包括:

1. IBatisNet 实例配置

一个典型的配置文件如下(具体配置项目的含义见后):

<?xml version="1.0" encoding="utf-8"?>
<sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
 <!-- Rem : If used via a DataAccess context, properties tag will be ignored 
 <properties resource="../../database.config"/> -->
 <properties embedded="database.config, IBatisNetDemo"/>
 <settings>
 <setting useStatementNamespaces="${useStatementNamespaces}"/>
 <setting cacheModelsEnabled="true"/>
 <setting validateSqlMap="false"/>
 </settings>
 <!-- Optional if resource -->
 <providers embedded="providers.config,IBatisNetDemo"/>
 <!-- ==== SqlClient configuration ========= -->
 <!-- Rem : If used via a DataAccess context, database tag will be ignored -->
 <database>
 <!-- Optional ( default ) -->
 <provider name="sqlServer1.1"/>
 <dataSource name="iBatisNet" connectionString="data source=localhost;database=Northwind;user id=sa;password=;connection reset=false;connection lifetime=5; min pool size=1; max pool size=50"/>
 </database>
 <sqlMaps>
 <!-- user via embedded-->
 <sqlMap embedded="Map.SqlClient.Person.xml,IBatisNetDemo"/>
 </sqlMaps>
</sqlMapConfig> 

2. PO(Plain Ordinary Object)

下面是我们用作示例的一个PO:

[Serializable]

 public class Person
 {
 private int id;
 private string firstName;
 private string lastName;
 private DateTime? birthDate;
 private double? weightInKilograms;
 private double? heightInMeters;
 public Person() { }
 public int Id
 {
 get { return id; }
 set { id = value; }
 }
 public string FirstName
 {
 get { return firstName; }
 set { firstName = value; }
 }
 public string LastName
 {
 get { return lastName; }
 set { lastName = value; }
 }
 public DateTime? BirthDate
 {
 get { return birthDate; }
 set { birthDate = value; }
 }
 public double? WeightInKilograms
 {
 get { return weightInKilograms; }
 set { weightInKilograms = value; }
 }
 public double? HeightInMeters
  {
 get { return heightInMeters; }
 set { heightInMeters = value; }
 }
} 

3.映射文件

与Hibernate 不同。因为需要人工编写SQL 代码,IBatisNet 的映射文件一般采

用手动编写(通过Copy/Paste,手工编写映射文件也并没想象中的麻烦)。

针对上面PO 的映射代码如下:

<?xml version="1.0" encoding="utf-8" ?>
<sqlMap namespace="Person" xmlns="http://ibatis.apache.org/mapping" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" >
 <alias>
 <typeAlias alias="Person" type="IBatisNetDemo.Domain.Person,IBatisNetDemo" />
 </alias>
 <resultMaps>
 <resultMap id="SelectAllResult" class="Person">
 <result property="Id" column="PER_ID" />
 <result property="FirstName" column="PER_FIRST_NAME" />
 <result property="LastName" column="PER_LAST_NAME" />
 <result property="BirthDate" column="PER_BIRTH_DATE" />
 <result property="WeightInKilograms" column="PER_WEIGHT_KG" />
 <result property="HeightInMeters" column="PER_HEIGHT_M" />
 </resultMap>
 </resultMaps>
 <statements>
 <select id="SelectAllPerson" resultMap="SelectAllResult">
 select
 PER_ID,
 PER_FIRST_NAME,
 PER_LAST_NAME,
 PER_BIRTH_DATE,
 PER_WEIGHT_KG,
 PER_HEIGHT_M
 from PERSON
 </select>
 <select id="SelectByPersonId" resultClass="Person" parameterClass="int">
 select
 PER_ID,
 PER_FIRST_NAME,
 PER_LAST_NAME,
 PER_BIRTH_DATE,
 PER_WEIGHT_KG,
 PER_HEIGHT_M
 from PERSON
 where PER_ID = #value#
 </select>
 <insert id="InsertPerson" parameterclass="Person" >
 <selectKey property="Id" type="post" resultClass="int">
 ${selectKey}
 </selectKey> 
 insert into Person
 ( PER_FIRST_NAME,
 PER_LAST_NAME,
 PER_BIRTH_DATE,
 PER_WEIGHT_KG,
 PER_HEIGHT_M)
 values
 (#FirstName#,#LastName#,#BirthDate#, #WeightInKilograms#, #HeightInMeters#)
 </insert>
 <update id="UpdatePerson"
 parameterclass="Person">
 <![CDATA[ update Person set
 PER_FIRST_NAME =#FirstName#,
 PER_LAST_NAME =#LastName#,
 PER_BIRTH_DATE =#BirthDate#,
 PER_WEIGHT_KG=#WeightInKilograms#,
 PER_HEIGHT_M=#HeightInMeters#
 where
 PER_ID = #Id# ]]>
 </update>
 <delete id="DeletePerson" parameterclass="Person">
 delete from Person
 where
 PER_ID = #Id#
 </delete>
 </statements>
</sqlMap>

从上面的映射文件可以看出,通过<insert>、<delete>、<update>、

<select>四个节点,我们分别定义了针对Person 对象的增删改查操作。在这

四个节点中,我们指定了对应的SQL 语句,以update节点为例:

……
<update id=" UpdatePerson" ⑴
parameterClass="Person"> ⑵
<![CDATA[⑶
 update Person set ⑷
 PER_FIRST_NAME =#FirstName#,⑸
 PER_LAST_NAME =#LastName#, ⑹
 PER_BIRTH_DATE =#BirthDate#,
 PER_WEIGHT_KG=#WeightInKilograms#,
 PER_HEIGHT_M=#HeightInMeters#
 where
PER_ID = #Id# ⑺]]>
</update>
……

⑴ ID

指定了操作ID,之后我们可以在代码中通过指定操作id 来执行此节点所定

义的操作,如:

SqlMap.Update("UpdatePerson", person);

ID设定使得在一个配置文件中定义两个同名节点成为可能(两个update节

点,_____以不同id区分)

⑵ parameterClass

指定了操作所需的参数类型,此例中update 操作以

IBatisNetDemo.Domain.Person类型的对象作为参数,目标是将提供的Person

实例更新到数据库。

parameterClass="Person"中,user为“IBatisNetDemo.Domain.Person”

类的别名,别名可通过typeAlias节点指定,如示例配置文件中的:

<typeAlias alias="Person" type="IBatisNetDemo.Domain.Person,IBatisNetDemo" />⑶ <![CDATA[……]]>

通过<![CDATA[……]]>节点,可以避免SQL 中与XML 规范相冲突的字符对

XML映射文件的合法性造成影响。

⑷ 执行更新操作的SQL,这里的SQL 即实际数据库支持的SQL 语句,将由

IBatisNet填入参数后交给数据库执行。

⑸ SQL中所需的用户名参数,“# FirstName #”在运行期会由传入的Person对象的FirstName

属性填充。

⑹ SQL 中所需的用户性别参数“# LastName #”,将在运行期由传入的user 对象的

LastName属性填充。

⑺ SQL中所需的条件参数“#id#”,将在运行期由传入的Person对象的Person属性

填充。

对于这个示例,IBatisNet在运行期会读取id 为“UpdatePerson”的update节点

的SQL定义,并调用指定的user对象的对应getter方法获取属性值,并用此

属性值,对SQL中的参数进行填充后提交数据库执行。

此例对应的应用级代码如下,其中演示了IBatisNet SQLMap的基本使用方法:

private static SqlMapper sqlMap;
public BaseService()
{
 Assembly assembly = Assembly.Load("IBatisNetDemo");
  Stream stream = assembly.GetManifestResourceStream("IBatisNetDemo.sqlmap.config");
 DomSqlMapBuilder builder = new DomSqlMapBuilder();
 sqlMap = builder.Configure( stream );
 };

其中,SqlMapper是IbatisNet运作的核心,所有的操作均通过SqlMapper实例完成。这个例子中我将所有的配置文件按照资源文件方式存放,所以从程序集去加载sqlmap.config文件。

可以看出,对于应用层而言,程序员面对的是传统意义上的实体(数据)对象,而不是ADO.NET中的DataReader或者DataTable/DataSet,这使得我们控制最终的数据操作方式,通过Sql的优化来获得最佳的数据库执行效能,这在依赖SQL自动生成的“全自动”ORM机制中是难以实现的。 例子代码 http://files.cnblogs.com/shanyou/IBatisNet.rar

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏智能大石头

C#嵌入x86汇编——一个GPIO接口的实现

开始进入工业自动化,买的工控机带有GPIO接口,可用于直接控制继电器。 从厂家拿到接口手册一看,居然是汇编直接操作端口,基本上是IN/OUT指令了。接口很简单,...

2526
来自专栏landv

c语言-键盘扫描码

1962
来自专栏Android知识点总结

3-AIV--使用ContentProvider获得所有图片路径

1922
来自专栏张善友的专栏

IBatisNet基础组件

DomSqlMapBuilder DomSqlMapBuilder,其作用是根据配置文件创建SqlMap实例。可以通过这个组件从Stream, Uri, Fil...

3155
来自专栏张善友的专栏

使用 Roslyn 编译器服务

.NET Core和 .NET 4.6中 的C# 6/7 中的编译器Roslyn 一个重要的特性就是"Compiler as a Service",简单的讲,就...

2028
来自专栏debugeeker的专栏

某代码查看器的保护突破

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xuzhina/article/detai...

681
来自专栏逆向技术

内核开发知识第一讲.内核中的数据类型.重要数据结构.常用内核API函数.

  在内核中.程序的编写不能简单的用基本数据类型了. 因为操作系统不同.很有可能造成数据类型的长度不一.而产生重大问题.所以在内核中.

1702
来自专栏林德熙的博客

C# 如何在项目引用x86 x64的非托管代码

因为现在的项目使用的是 AnyCpu 在 x86 的设备使用的是x86,在x64使用的是x64,但是对于非托管代码,必须要在x64使用x64的dll,在x86使...

3951
来自专栏大内老A

Dora.Interception: 一个为.NET Core度身定制的AOP框架

多年从事框架设计开发使我有了一种强迫症,那就是见不得一个应用里频繁地出现重复的代码。之前经常Review别人的代码,一看到这样的程序,我就会想如何将这些重复的代...

2735
来自专栏跟着阿笨一起玩NET

对比MS Test与NUnit Test框架

项目中进行Unit Test时,肯定会用到框架,因为这样能够更快捷、方便的进行测试。

872

扫码关注云+社区

领取腾讯云代金券