IBatisNet基础组件

DomSqlMapBuilder

DomSqlMapBuilder,其作用是根据配置文件创建SqlMap实例。可以通过这个组件从Stream, Uri, FileInfo, or XmlDocument instance 来读取sqlMap.config文件。

SqlMap

SqlMap是IBatisnet的核心组件,提供数据库操作的基础平台。SqlMap可通过DomSqlMapBuilder创建。

Assembly assembly = Assembly.Load("IBatisNetDemo");

Stream stream = assembly.GetManifestResourceStream("IBatisNetDemo.sqlmap.config");

DomSqlMapBuilder builder = new DomSqlMapBuilder();

sqlMap = builder.Configure( stream );

SqlMap是线程安全的,也就是说,在一个应用中,可以共享一个SqlMap实例。

SqlMap提供了众多数据操作方法,下面是一些常用方法的示例,具体说明文档参见 ibatis net doc,或者ibatisnet的官方开发手册。

SqlMap基本操作示例

例1:数据写入操作(insert、update、delete)

SqlMap.BeginTransaction();  Person person = new Person();  Person.FirstName = “Zhang”;  Person.LastName = “shanyou”; int Id = (int) SqlMap.Insert("InsertPerson", person);  SqlMap.CommitTransaction();.

例2:数据查询:

Int Id = 1; Person person = SqlMap.QueryForObject<Person>("", Id); return person;

例3:在指定对象中存放查询结果:

Int Id = 1; Person person =  new Person(); person = SqlMap.QueryForObject<Person>("GetBirthday", Id, person); return person;

例4:执行批量查询(Select)

IList<Person> list = null; list = SqlMap.QueryForList<Person>("SelectAllPerson", null);  return list;

例5:查询指定范围内的数据(Select)

IList<Person> list = null; list = SqlMap.QueryForList<Person>("SelectAllPerson", null, 0, 40); return list;

例6:结合RowDelegate进行查询:

public void RowHandler(object obj, IList list) {   Product product = (Product) object;   product.Quantity = 10000; } SqlMapper.RowDelegate handler = new SqlMapper.RowDelegate(this.RowHandler); IList list = sqlMap.QueryWithRowDelegate("getProductList", null, handler);

例7:分页查询(Select)

PaginatedList list = sqlMap.QueryForPaginatedList (“getProductList”, null, 10); list.NextPage(); list.PreviousPage();

例8:基于Map的批量查询(select)

IDictionary map = sqlMap.QueryForMap (“getProductList”, null, “productCode”); Product p = (Product) map[“EST-93”];

OR映射

相对于Nhibernate等ORM实现来说,IBatisnet的映射配置更为直接,下面是一个典型的配置文件:

<?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>
  <cacheModels>
 <cacheModel id="person-cache" implementation="MEMORY" >
 <flushInterval hours="24"/>
 <flushOnExecute statement="UpdateAccountViaInlineParameters"/>
 <flushOnExecute statement="UpdateAccountViaParameterMap"/>
 <property name="Type" value="Weak"/>
  </cacheModel>
 </cacheModels>
 <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>
<!—statement配置 à
 <statements>
 <select id="SelectAllPerson" resultMap="SelectAllResult" cacheModel="account-cache">
 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>

可以看到,映射文件主要分为两个部分:模块配置和Statement配置。

模块配置包括:

1、typeAlias节点

定义了本映射文件中的别名,以避免过长变量值的反复书写,此例中通过typeAlias节点为类“IBatisNetDemo.Domain.Person”定义了一个别名“Person”,这样在本配置文件中的其他部分,需要引用“IBatisNetDemo.Domain.Person”类时,只需以其别名替代即可。

2、cacheModel节点

定义了本映射文件中使用的Cache机制:

<cacheModel id="person-cache" implementation="MEMORY" >       <flushInterval hours="24"/>       <flushOnExecute  statement="UpdateAccountViaInlineParameters"/>       <flushOnExecute  statement="UpdateAccountViaParameterMap"/>       <property name="Type" value="Weak"/>     </cacheModel>

这里声明了一个名为“person-cache”的cacheModel,之后可以在Statement声明中对其进行引用:

<select id="SelectAllPerson" resultMap="SelectAllResult" cacheModel=" person-cache">       select       PER_ID,       PER_FIRST_NAME,       PER_LAST_NAME,       PER_BIRTH_DATE,       PER_WEIGHT_KG,       PER_HEIGHT_M       from PERSON         </select>

这表明对通过id为SelAllPerson的“Select Statement”获取的数据,使用CacheModel “person-cache”进行缓存。之后如果程序再次用此Satement进行数据查询。即直接从缓存中读取数据,而不需再去数据库查询。

CacheModel主要有几个配置点:

参数

描述

flushInterval

设定缓存有效期,如果超过此设定值,则将此CacheModel缓存清空

CacheSize

本Cachemodel中最大的数据对象数量

flushOnExecute

指定执行特定的Statement时,将缓存清空。如UpdatePerson操作将更新数据库中用户信息,这将导致缓存中的数据对象与数据库中的实际数据发生偏差,因此必须将缓存清空以避免脏数据的出现。

3、resultMaps节点

resultMaps实现dotnet实体到数据库字段的映射配置:

<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>

Statement配置:

Statement配置包含了数个与Sql Statement相关的节点,<statement>元素是一个通用的能够包容任意类型sql的元素。我们可以用更多细节的元素。

这些细节元素提供更好的错误检查以及一些更多的功能。(例如,一个插入函数能够返回数据库自动生成的key)。以下表格总结了声明类型元素以及他们的特性和属性。

Statement Element

Attributes

Child Elements

Methods

<statement>

id parameterClass resultClass parameterMap resultMap cacheModel xmlResultName (Java only)

All dynamic elements

insert update delete All query methods

<insert>

id parameterClass parameterMap

All dynamic elements <selectKey> <generate> (.NET only)

insert update delete

<update>

id parameterClass parameterMap

All dynamic elements <generate>  (.NET only)

insert update delete

<delete>

id parameterClass parameterMap

All dynamic elements <generate>  (.NET only)

insert update delete

<select>

id parameterClass resultClass parameterMap resultMap cacheModel

All dynamic elements <generate> (.NET only)

All query methods

<procedure>

id parameterClass resultClass parameterMap resultMap xmlResultName (Java only)

All dynamic elements

insert update delete All query methods

其中,statement最为通用,它可以代替其余的所有节点。除statement之外的节点对应于SQL中的同名操作(procedure对应存储过程)。使用Statement定义所有操作,缺乏直观性,建议在开发中根据操作目的,各自选用对应的节点名加以说明。一方面,使得配置文件更加直观,另一方面,也可以借助xsd对i节点声明进行更有针对性的检查,以避免配置上的失误。

<statement id=”statementName”   [parameterMap=”nameOfParameterMap”]   [parameterClass=”some.class.Name”]   [resultMap=”nameOfResultMap”]   [resultClass=”some.class.Name”]   [cacheModel=”nameOfCache”] >     select * from PRODUCT where PRD_ID = [?|#propertyName#]    order by [$simpleDynamic$]   </statement>

其中“[ ]”包围的部分为可能出现的配置项,各参数说明见下表。具体的使用方法参见IBatisNet官方文档。

参数

描述

parameterMap

参数映射,需结合parameterMap节点对映射关系加以定义,对于存储过程之外的statement而言,建议使用parameterClass作为参数配置方式,一方面避免了参数映射配置工作,另一方面其性能表现更加出色

parameterClass

参数类。指定了参数类型的完整类名(包括命名空间),可以通过别名避免每次书写冗长的类名

resultMap

结果映射,需结合resultMap节点对映射关系加以定义

resultClass

结果类。指定了结果类型的完整类名(包括命名空间),可以通过别名避免每次书写冗长的类名

cacheModel

Statement对应的Cache模块

一般而言,对于insert、update、delete、select语句,优先采用parameterClass和resultClass.。paremeterMap使用较少,而ResultMap则大多用于存储过程处理和查询。存储过程相对而言比较封闭(很多情况下需要调用现有的存储过程),其参数名和返回的数据字段命名往往不符合dotnet编程的命名规范)。使用resultMap建立字段名同Dotnet对象的属性之间的映射关系就非常有效。另一方面,由于通过ResultMap指定了字段名和字段类型,ibatisnet无需再通过ado.net来动态获取字段信息,在一定程度上也提升了性能。

下面特别说明一下ibatisnet对Stored Procedures的处理,iBatis数据映射把存储过程当成另外一种声明元素。示例演示了一个基于存储过程的简单数据映射。

<!-- Microsot SQL Server --> <procedure id="SwapEmailAddresses" parameterMap="swap-params"> ps_swap_email_address </procedure> ... <parameterMap id="swap-params"> <parameter property="email1" column="First_Email" /> <parameter property="email2" column="Second_Email" /> </parameterMap> <!-- Oracle with MS OracleClient provider --> <procedure id="InsertCategory" parameterMap="insert-params"> prc_InsertCategory </procedure> ... <parameterMap id="insert-params"> <parameter property="Name" column="p_Category_Name"/> <parameter property="GuidString" column="p_Category_Guid" dbType="VarChar"/> <parameter property="Id" column="p_Category_Id" dbType="Int32" type="Int"/> </parameterMap> <!-- Oracle with ODP.NET 10g provider --> <statement id="InsertAccount" parameterMap="insert-params"> prc_InsertAccount </statement> ... <parameterMap id="insert-params"> <parameter property="Id" dbType="Int32"/> <parameter property="FirstName" dbType="VarChar2" size="32"/> <parameter property="LastName" dbType="VarChar2" size="32"/> <parameter property="EmailAddress" dbType="VarChar2" size="128"/> </parameterMap>

示例是调用存储过程swapEmailAddress的时候将会在数据库表的列和两个email地址之间交换数据,参数对象亦同。参数对象仅在属性被设置成INOUT或者OUT的时候才会被修改。否则,他们将不会被修改。当然,不可变得参数对象是不会被修改的,比如string.

.Net中,parameterMap属性是必须的。DBType,参数方向,大小由框架自动发现的。(使用CommandBuilder实现的)

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏debugeeker的专栏

某代码查看器的保护突破

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

7810
来自专栏Android相关

Android中的Proguard介绍

ProGuard是一个Java Class文件的Shrinker,optimizer,obfuscator以及Preverifier。

17630
来自专栏一个番茄说

让你在WebView中用JS调Native Object

之所做这个东西,源于之前项目中需要把一些页面用webView来呈现,但是web中需要调用native的方法,比如获取本地存的某些数据、调用摄像头等等,这里也就是...

12330
来自专栏散尽浮华

Linux下针对服务器网卡流量和磁盘的监控脚本

27740
来自专栏张善友的专栏

使用 Roslyn 编译器服务

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

22280
来自专栏Java架构师学习

带你深入了解Java线程中的那些事

引言 说到Thread大家都很熟悉,我们平常写并发代码的时候都会接触到,那么我们来看看下面这段代码是如何初始化以及执行的呢? public class Thre...

36080
来自专栏大内老A

ASP.NET MVC基于标注特性的Model验证:DataAnnotationsModelValidator

对于ASP.NET MVC基于标注特性的Model验证,很多人只知道应用在数据类型及其属性上用于定义验证规则和错误消息的ValidationAttribute。...

244100
来自专栏MasiMaro 的技术博文

Windows平台下的内存泄漏检测

在C/C++中内存泄漏是一个不可避免的问题,很多新手甚至有许多老手也会犯这样的错误,下面说明一下在windows平台下如何检测内存泄漏。 在windows平...

28220
来自专栏林德熙的博客

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

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

47310
来自专栏技术博客

Json.Net6.0入门学习试水篇

  JSON(JavaScript Object Notation) 是一种轻量级的数据交换格式。简单地说,JSON 可以将 JavaScript 对象中表示的...

12020

扫码关注云+社区

领取腾讯云代金券