一.   介绍

平常做企业级应用,需求变化是经常的事,而很多基础代码重复也是很让人头疼的问题。所以很多人会使用一些ORM框架来增强项目的可维护性、可扩展性。IBatis.Net就是一个比较易用的ORM框架,使用起来较为方便、灵活。IBatis.Net是从Ibatis的Java版本移植过来的.NET版本。iBATIS作为一种独特的Data Mapper,使用SQL映射的方式将对象持久化至关系型数据库。简单的理解就是它将我们在数据访问层实现的C#逻辑代码,变为通过关系数据库与对象的映射,将SQL逻辑放到外部的XML配置文件中,以方便以后的维护。

这个框架有两个主要的组成部分,一个是SQL Maps,另一个是Data Access Objects。Sql Maps是这个框架的核心部分,通过使用Sql Maps你可以显著的节约数据库操作的代码量。SQL Maps使用一个简单的XML文件来实现从实体到SQL statements的映射。使用DAO,封装了对数据的访问,你可以动态配置你的应用程序来访问不同的实体存储机制。隐藏持久性层实现的细节,Data Access Objects允许你通过一个简单接口的来操作数据。

二.   准备工作

下面先让我们来动手实践一下,看看如何使用和调用IbatisNet。

1.  下载IbatisNet软件包: http://ibatis.apache.org/dotnetdownloads.cgi

iBATIS.NET Downloads

官方网站还提供了一个示例项目:NPetShop Example Application

2.  建立测试数据库,并在数据库中创建一个Person 表:

字段

类型

大小

PER_ID

int

4

PER_FIRST_NAME

nvarchar

40

PER_LAST_NAME

nvarchar

40

PER_BIRTH_DATE

DateTime

8

PER_WEIGHT_KG

float

8

PER_HEIGHT_M

float

8

三.   开发步骤

1.逻辑结构

   

2.建立项目

打开VS.NET,新建一个"ASP.NET Web应用程序"项目。

3.添加引用

在项目中添加下面dll的引用:

IBatisNet.Common.dll

IBatisNet.DataMapper.dll

IBatisNet.DataAccess.dll

4.在项目中,添加配置文件 SqlMap.config

该文件为IBatis.net默认的配置文件,不能缺少,当然可以不必是Sql.config,但是如果改为其他的名字的话需要在前台代码中说明,请参考下面的内容providers.config:该文件必须存在,并且不能改变它的文件名,该文件描述了如何连接数据库,无须配置

结合上面示例中的IbatisNet配置文件,下面对配置文件中各节点的说明:

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

<sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper"

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

<!-- 常量属性,通过单独文件properties.config加载-->

<properties resource="properties.config"/>

<!-- 常量属性,通过程序集资源中 加载

<properties embedded="database.config, IBatisNetDemo"/>-->

<settings>

<setting useStatementNamespaces="${useStatementNamespaces}"/>

<setting cacheModelsEnabled="true"/>

<setting validateSqlMap="false"/>

</settings>

<!-- 数据驱动提供类配置文件的路径和文件名 -->

<providers resource="providers.config"/>

<!-- 设置数据库连接信息    -->

<database>

<provider name="${provider}"/>

<dataSource name="IBatisNetTest" connectionString="${connectionString}"/>

</database>

<!-- 指定项目内映射的文件的位置-->

<sqlMaps>

<!-- 从程序集中

<sqlMap embedded="${root}Person.xml,${assembly}" />-->

<!-- 从文件中-->

<sqlMap resource="@Maps/Person.xml" />

</sqlMaps>

</sqlMapConfig>

详细说明:

(1) properties节点

可以根据需要配置一些常量属性。如果这些属性有很多的话可以单独写一个文件里面,再通过resource(或url, embedded分别是引用url和编译在程序中的资源文件)属性引用进来。

properties 节点参数

参数

描述

resource

指定the properties文件从application的根目录进行加载

resource="properties.config"

url

指定the properties文件从文件的绝对路径进行加载

url="c:/Web/MyApp/Resources/properties.config"

或者

url="file://c:/Web/MyApp/Resources/properties.config"

embedded

指定文件可以作为程序集的资源文件进行加载'

embedded=" database.config, IBatisNetDemo"

上面例子中properties.config文件的配置如下:

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

<settings>

<!—应用程序和配置属性设置-->

<add key="provider" value="sqlServer2.0" />

<add key="connectionString"     value="server=127.0.0.1;database=TVSystem;uid=sa;pwd=1" />

<add key="root" value="IBatisNetTest.Maps." />

<add key="assembly" value="IBatisNetTest" />

<add key="userid" value="sa" />

<add key="password" value="" />

<add key="database" value="Northwind" />

<add key="datasource" value="localhost" />

<add key="selectKey" value="select @@IDENTITY as value" />

<add key="directory" value="Maps" />

<add key="useStatementNamespaces" value="false" />

</settings>

下面解释一下这个文件的节点参数

properties.config节点参数

参数

描述

key

定义key (variable) 名字

key="username"

value

定义DataMapper 中使用的 key的值

value="mydbuser"

(2) setting节点

Setting节点参数

参数

描述

cacheModelsEnabled

是否启用sqlMap上的缓存机制

Example: cacheModelsEnabled="true"

Default: true (enabled)

useStatementNamespaces

是否使用Satement命名空间,这里的命名空间指的是映射文件中sqlMap节点的namespace属性,如上例中针对Person表的映射文件sqlMap节点

<sqlMap namespace="Person" xmlns="http://ibatis.apache.org/mapping"

xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance> 这里,指定了此sqlMap节点下定义的操作均丛属于"Person"命名空间在useStatementNamespaces="true"的情况下,Statement调用需追加命名空间,如:sqlMap.Update("Person.UpdatePerson",person);否则直接通过Statement名称调用即可,如sqlMap.Update("UpdatePerson",person);但请注意此时需要保证所有映射文件中,statement定义无重名

Example: useStatementNamespaces="false"

Default: false (disabled)

validateSqlMap

是配置要不要启示SqlMapConfig.xsd schema验证映射文件.

Example: validateSqlMap="false"

Default: false (disabled)

(3) provider节点

配置数据驱动提供类配置文件的路径和文件名,通过resource(或url, embedded分别是引用url和编译在程序中的资源文件)属性引用进来,参数的含义同properties。

ADO.NET是通过数据访问提供程序(Provider)访问数据库。IBatisNet使用的是插件式结构来使用这些数据库提供程序,每一个Provider对应于providers.config文件中定义的一个provider项。1.3版本的Provider.config文件中定义了已经实现的16个provider,通过设置这个文件中的几个参数来决定使用哪个数据库提供程序。

         sqlServer1.0 - Microsoft SQL Server 7.0/2000 provider available with .NET Framework 1.0

         sqlServer1.1 -Microsoft SQL Server 7.0/2000 provider available with .NET Framework 1.1

         sqlServer2.0 - Microsoft SQL server 7.0/2000/2005 provider available with .NET Framework 2.0

         OleDb1.1 - OleDb provider available with .NET Framework 1.1

         Odbc1.1 - Odbc provider available with .NET Framework 1.1

         oracle9.2 - Oracle provider V9.2.0.401

         oracle10.1 - Oracle provider V10.1.0.301

         oracleClient1.0 - MS Oracle provider V1.0.5 available with .NET Framework 1.1

         ByteFx - ByteFx MySQL provider V0.7.6.15073

         MySql - MySQL provider V1.0.4.20163

         SQLite3 - SQLite.NET provider V0.21.1869.3794

         Firebird1.7 - Firebird SQL .NET provider V1.7.0.33200

         PostgreSql0.7 - Npgsql provider V0.7.0.0

         PostgreSql0.7.1 - Npgsql provider V0.7.1.0

         iDb2.10 - IBM DB2 iSeries provider V10.0.0.0

         Informix -- informix NET Provider, 2.81.0.0

提供程序要求安装相关类库,每一个provider 元素都有"enabled" 属性来控制是否启用这个providers. 一个provider 可以通过 "default"属性标识为默认的提供程序。

(4) database节点

数据库的信息,包括使用哪些数据库驱动和数据连接字符串的配置。

Database节点参数

参数

描述

provider

数据库访问所使用的provider.config文件定义的provider

dataSource

特定的数据库连接字符串

(5) typeHandler节点

定义数据库类型到dotnet数据类型的处理,不同的数据库都有一些特殊的数据库字段类型需要特殊处理,就可以通过这个功能实现。比如说Blob字段在不同的数据库中处理不一样。大家可以去看看Ibatisnet源代码就清楚这个功能的实现原理,对于我们的设计会有很大的启发

(6) sqlMaps节点

sqlMap节点指定了映射文件的位置,配置中可以出现多个sqlMap节点,以指定项目内所包含的所有映射文件。

5.创建实体类

定义Person的实体类,该对象类将与数据库进行映射。

[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; }

}

}

6.添加Person的映射文件Person.xml

相对于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="IBatisNetLib.Person,IBatisNetLib" />

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

<!--statement配置-->

<statements>

<select id="Exists" resultClass="int" parameterclass="int">

select count(1) 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>

<select id="SelectAllPerson" resultMap="SelectAllResult">

Select *

from PERSON

</select>

<select id="SelectByPersonId" resultMap="SelectAllResult" 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>

</statements>

</sqlMap>

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

模块配置包括:

(1)Type Alias节点

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

(2)cacheModel节点

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

<cacheModel id="person-cache" implementation="MEMORY" >

"/>

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

(4)Statement配置:

⑴ 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中的参数进行填充后提交数据库执行。

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开发使用小结 之二 本文示例项目源码下载 动软代码生成器新增对IBatisNet的代码生成插件

四.   IBatisNet组件使用

1.  DomSqlMapBuilder

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

2.  SqlMap

SqlMapper是IBatisnet的核心组件,提供数据库操作的基础平台。所有的操作均通过SqlMapper实例完成。SqlMapper可通过DomSqlMapBuilder创建。

这个例子中我们可以将所有的配置文件按照嵌入资源文件方式存放,从程序集去加载sqlmap.config文件。也可以直接以文件方式加载sqlmap.config。

///
<summary>

/// IsqlMapper实例

///
</summary>

///
<returns></returns>

public
static
ISqlMapper sqlMap ;

private
string fileName = "sqlMap.Config";

public BaseSqlMapDao()

{

//从程序集资源中加载

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

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

//DomSqlMapBuilder builder = new DomSqlMapBuilder();

//sqlMap = builder.Configure(stream);

//从文件加载创建实例

DomSqlMapBuilder builder = new
DomSqlMapBuilder();

sqlMap = builder.Configure(fileName);

}

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

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

3.  SqlMap基本操作示例

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

SqlMap.BeginTransaction();

Person person = new Person();

Person.FirstName = "li";

Person.LastName = "tianping";

int Id = (int) SqlMap.Insert("InsertPerson", person);

SqlMap.CommitTransaction();

例2:数据查询:

Int Id = 1;

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

return person;

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

IList<Person> list = null;

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

return list;

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

IList<Person> list = null;

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

return list;

例5:结合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);

4.  存储过程操作

下面特别说明一下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实现的)。

五.   IBatisNet封装类:BaseSqlMapDao

为了日后的重复使用和代码简洁,我们可以像DbHelperSQL一样,对SqlMap的各种操作进行封装。

using System;

using System.Collections;

using System.Collections.Generic;

using System.Text;

using System.IO;

using System.Web;

using System.Reflection;

using IBatisNet.Common;

using IBatisNet.Common.Pagination;

using IBatisNet.DataMapper;

using IBatisNet.DataMapper.Exceptions;

using IBatisNet.DataMapper.Configuration;

namespace IBatisNetLib

{

///
<summary>

/// 基于IBatisNet的数据访问基类

///
</summary>

public
class
BaseSqlMapDao

{

///
<summary>

/// IsqlMapper实例

///
</summary>

///
<returns></returns>

public
static
ISqlMapper sqlMap;

#region 构造ISqlMapper

private
string fileName = "sqlMap.Config";

public BaseSqlMapDao()

{

//从程序集中加载

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

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

//DomSqlMapBuilder builder = new DomSqlMapBuilder();

//sqlMap = builder.Configure(stream);

//从文件加载创建实例

DomSqlMapBuilder builder = new
DomSqlMapBuilder();

sqlMap = builder.Configure(fileName);

}

#endregion

///
<summary>

/// 是否存在

///
</summary>

///
<param name="tableName">表名</param>

///
<returns></returns>

protected
bool ExecuteExists(string statementName, object parameterObject)

{

try

{

object obj = sqlMap.QueryForObject(statementName, parameterObject);

int cmdresult;

if ((Object.Equals(obj, null)) || (obj == null))

{

cmdresult = 0;

}

else

{

cmdresult = int.Parse(obj.ToString());

}

if (cmdresult == 0)

{

return
false;

}

else

{

return
true;

}

}

catch (Exception e)

{

throw (e);

}

}

///
<summary>

/// 执行添加

///
</summary>

///
<param name="statementName">操作名</param>

///
<param name="parameterObject">参数</param>

protected
object ExecuteInsert(string statementName, object parameterObject)

{

try

{

return sqlMap.Insert(statementName, parameterObject);

}

catch (Exception e)

{

throw
new
DataMapperException("Error executing query '" + statementName + "' for insert. Cause: " + e.Message, e);

}

}

///
<summary>

/// 执行添加,返回自动增长列

///
</summary>

///
<param name="statementName">操作名</param>

///
<param name="parameterObject">参数</param>

///
<returns>返回自动增长列</returns>

protected
int ExecuteInsertForInt(string statementName, object parameterObject)

{

try

{

object obj=sqlMap.Insert(statementName, parameterObject);

if (obj != null)

{

return
Convert.ToInt32(obj);

}

else

{

return 0;

}

}

catch (Exception e)

{

throw
new
DataMapperException("Error executing query '" + statementName + "' for insert. Cause: " + e.Message, e);

}

}

///
<summary>

/// 执行修改

///
</summary>

///
<param name="statementName">操作名</param>

///
<param name="parameterObject">参数</param>

///
<returns>返回影响行数</returns>

protected
int ExecuteUpdate(string statementName, object parameterObject)

{

try

{

return sqlMap.Update(statementName, parameterObject);

}

catch (Exception e)

{

throw
new
DataMapperException("Error executing query '" + statementName + "' for update. Cause: " + e.Message, e);

}

}

///
<summary>

/// 执行删除

///
</summary>

///
<param name="statementName">操作名</param>

///
<param name="parameterObject">参数</param>

///
<returns>返回影响行数</returns>

protected
int ExecuteDelete(string statementName, object parameterObject)

{

try

{

return sqlMap.Delete(statementName, parameterObject);

}

catch (Exception e)

{

throw
new
DataMapperException("Error executing query '" + statementName + "' for delete. Cause: " + e.Message, e);

}

}

///
<summary>

/// 得到列表

///
</summary>

///
<typeparam name="T">实体类型</typeparam>

///
<param name="statementName">操作名称,对应xml中的Statement的id</param>

///
<param name="parameterObject">参数</param>

///
<returns></returns>

protected
IList<T> ExecuteQueryForList<T>(string statementName, object parameterObject)

{

try

{

return sqlMap.QueryForList<T>(statementName, parameterObject);

}

catch (Exception e)

{

throw
new
DataMapperException("Error executing query '" + statementName + "' for list. Cause: " + e.Message, e);

}

}

///
<summary>

/// 得到指定数量的记录数

///
</summary>

///
<typeparam name="T"></typeparam>

///
<param name="statementName"></param>

///
<param name="parameterObject">参数</param>

///
<param name="skipResults">跳过的记录数</param>

///
<param name="maxResults">最大返回的记录数</param>

///
<returns></returns>

protected
IList<T> ExecuteQueryForList<T>(string statementName, object parameterObject, int skipResults, int maxResults)

{

try

{

return sqlMap.QueryForList<T>(statementName, parameterObject, skipResults, maxResults);

}

catch (Exception e)

{

throw
new
DataMapperException("Error executing query '" + statementName + "' for list. Cause: " + e.Message, e);

}

}

///
<summary>

/// 得到分页的列表

///
</summary>

///
<param name="statementName">操作名称</param>

///
<param name="parameterObject">参数</param>

///
<param name="pageSize">每页记录数</param>

///
<returns></returns>

protected
IPaginatedList ExecuteQueryForPaginatedList(string statementName, object parameterObject, int pageSize)

{

try

{

return sqlMap.QueryForPaginatedList(statementName, parameterObject, pageSize);

}

catch (Exception e)

{

throw
new
DataMapperException("Error executing query '" + statementName + "' for paginated list. Cause: " + e.Message, e);

}

}

///
<summary>

/// 查询得到对象的一个实例

///
</summary>

///
<typeparam name="T">对象type</typeparam>

///
<param name="statementName">操作名</param>

///
<param name="parameterObject">参数</param>

///
<returns></returns>

protected T ExecuteQueryForObject<T>(string statementName, object parameterObject)

{

try

{

return sqlMap.QueryForObject<T>(statementName, parameterObject);

}

catch (Exception e)

{

throw
new
DataMapperException("Error executing query '" + statementName + "' for object. Cause: " + e.Message, e);

}

}

}

}

调用该基类实现映射文件的数据访问代码:

using System;

using System.Collections.Generic;

using System.Text;

namespace IBatisNetLib

{

public
class
PersonService : BaseSqlMapDao

{

public PersonService()

{

}

///
<summary>

/// 是否存在该记录

///
</summary>

public
bool Exists(object Id)

{

return ExecuteExists("Exists", Id);

}

public
void Insert(Person person)

{

ExecuteInsert("InsertPerson", person);

}

public
void Update(Person person)

{

ExecuteUpdate("UpdatePerson", person);

}

public
void Delete(Person person)

{

ExecuteDelete("DeletePerson", person);

}

public
IList<Person> GetAllPerson()

{

IList<Person> list = null;

list = ExecuteQueryForList<Person>("SelectAllPerson", null);

return list;

}

public
Person GetPerson(object Id)

{

Person person = ExecuteQueryForObject<Person>("SelectByPersonId", Id);

return person;

}

}

}

IbatisNet开发使用小结的更多相关文章

  1. andriod socket开发问题小结

    andriod socket开发问题小结 个人信息:就读于燕大本科软件project专业 眼下大四; 本人博客:google搜索"cqs_2012"就可以; 个人爱好:酷爱数据结构 ...

  2. 前端开发个人小结 · Retrospection的博客

    序 2018年转眼来到了最后一个月,算下来我进入前端之门也有一年了,虽然下半年由于忙于筹备毕业论文的相关事项,前端这一块有所放下,但是想想还是给自己这一年的学习做一个总结. 现代化软件开发确实是一个复 ...

  3. 项目完成小结 - Django3.x版本 - 开发部署小结 (2)

    前言 好久没更新博客了,最近依然是在做之前博客说的这个项目:项目完成 - 基于Django3.x版本 - 开发部署小结 这项目因为前期工作出了问题,需求没确定好,导致了现在要做很多麻烦的工作,搞得大家 ...

  4. ios学习开发阶段小结

    总结一下,开发了1个月10天的ios经验. 先晒成绩单:两个实验性质的app,一个wifi管家,一个图片壁纸软件 技术小结: 1.熟悉基本的各种ns语法:#import,#include,@class ...

  5. iPhone图形开发绘图小结

    iPhone图形开发绘图教程是本文要介绍的内容,介绍了很多关于绘图类的使用,先来看详细内容讲解. 1.绘图总结: 绘图前设置: CGContextSetRGBFillColor/CGContextSe ...

  6. 项目完成 - 基于Django3.x版本 - 开发部署小结

    前言 最近因为政企部门的工作失误,导致我们的项目差点挂掉,客户意见很大,然后我们只能被动进入007加班状态,忙得嗷嗷叫,直到今天才勉强把项目改完交付,是时候写一个小结. 技术 因为前期需求不明确,数据 ...

  7. Android app开发知识小结

    Android知识小结 这是一个知识的总结,所以没有详解的讲解. 一.分辨率Android中dp长度.sp字体使用.px像素.in英寸.pt英寸1/72.mm毫米 了解dp首先要知道density,d ...

  8. iBatis + SQL Server 项目开发实战小结

    几年前跟随项目经理做的一个ERP小项目,自己业余时间整理的开发手册,供参考. 开发环境配置:编程环境为Microsoft Visual Studio 2010,数据库是SQL Server 2008 ...

  9. AIR for IOS开发问题小结

    昨天终于成功地向APP STORE提交了应用,个人感觉用AIR做IOS开发就是个坑啊.出了问题之后,问苹果的技术支持,人家说“对于非XCODE环境下开发及发布所造成的问题我们在资料库中无法找到相应的解 ...

随机推荐

  1. 12种超酷HTML5 SVG和CSS3浮动标签效果

    这是一组效果很炫酷的SVG和CSS3表单浮动标签特效.这组浮动标签特效共12种效果,这些浮动标签效果部分在元素的伪元素上使用CSS transitions和CSS animations完毕,一部分则使 ...

  2. JavaScript中childNodes、children、nodeValue、nodeType、parentNode、nextSibling详细讲解

    其中属性.元素(标签).文本都属于节点 <title></title> <scripttype="text/javascript"> windo ...

  3. Linux学习笔记总结--配置iptables防火墙

    将原有的iptables 文件保存一份 cp -p /etc/sysconfig/iptables /etc/sysconfig/iptables.bak 清空现有的规则 iptables -F ip ...

  4. CocoaPods导入第三方库头文件自动补齐

    使用了一段时间CocoaPods来管理Objective-c的类库,方便了不少.但是有一个小问题,当我在xcode输入import关键字的时候,没有自动联想补齐代码的功能,需要手工敲全了文件名,难以适 ...

  5. plupload使用指南(转)

    转自http://www.cnblogs.com/2050/p/3913184.html 现在随着html5技术的逐渐推广和普及,再去使用以flash为上传手段的SWFUpload显然就有点过时了,毕 ...

  6. git 删除配置的远程地址

    删除(origin 名称需根据你本地查询出来的想删除的名字, 查询命令为 git remote -v) git remote rm origin 添加(origin 名称可根据需要添加) git re ...

  7. Linux netstat命令参数解释

    netstat –ntlp 显示 tcp 的监听端口 netstat –ntlp 显示 tcp udp 的监听端口 netstat –r 显示路由表 netstat –rn 显示路由表不做名称解析(较 ...

  8. Java-hibernate的Hello World

     hibernate 是对jdbc进行轻量级封装的  orm 框架,充当项目的持久层. 要使用 hibernate首先就需要继续配置, 引包:下载hibernate然后加入jar包 同时引入mysql ...

  9. windows服务启动 1053错误

    1.问题描述 今天在启动一个Windows服务时,服务启动不了,且提示:1053错误 那么是什么导致了1053错误呢? 2.他山之石 百度了一下,发现有人作出下面的解释并给出了解决方法: “常常是因为 ...

  10. oracle查询最占用资源的查询

    从V$SQLAREA中查询最占用资源的查询 select b.username username,a.disk_reads reads,a.executions exec,a.disk_reads/d ...