iBatis.Net系列(四) iBatisNet API基础

有了对 iBatis 配置系统的一些认识后,现在就先来简单了解一下, iBatis 是通过什么的方式去调用映射文件的 SQL 语句的。这对我们接下来深入了解有很大的帮助。

对于简单的 iBatis 应用场合来说,我想大部分都是集中在与 SqlMapper 对象打交道。这个类应该说是一个工具类,因为我们一般都是直接调用这个类的方法去执行 QUID 操作,但是它却不是真正的去做这些事情。因为 iBatis 内部有很多的类,对象之间的关系是非常复杂的,如果让客户直接去使用它内部方法,无疑增加了使用的复杂性,同样也会产生很多的冗余代码。因此这里它使用外观设计模式,通过 SqlMapper 类封装了 iBatis 执行数据库访问的复杂操作,包括打开一个会话 (Session) ,获取返回 IMappedStatement 对象实例,执行数据库访问,关闭连接等相关操作。这样我们在使用 iBatis API 的时候就可以非常简单调用的一个方法,就可以做所有的事情了。比如查询接口 public IList QueryForList (string statementName, object parameterObject) ,它的内部实现代码是这样的。

IList list1;

      
bool  flag1  =   false ;

      IDalSession session1 
=   this ._sessionHolder.LocalSession;

      
if  (session1  ==   null )

      {

            session1 
=   new  SqlMapSession( this .DataSource);

            session1.OpenConnection();

            flag1 
=   true ;

      }

      IMappedStatement statement1 
=   this .GetMappedStatement(statementName);

      
try

      {

            list1 
=  statement1.ExecuteQueryForList(session1, parameterObject);

      }

      
catch

      {

            
throw ;

      }

      
finally

      {

            
if  (flag1)

            {

                  session1.CloseConnection();

            }

      }

      
return  list1;


那这些代码如果直接在客户代码中去实现,可想而知工作量会有多大。并且还法保证正确性。

以上简单看了一个 SqlMapper 的作用,那该怎样实例化这个对象呢?实例化它也是一个非常简单的事情。在 iBatisNet 中, SqlMapper 对象默认是一个单件模式的实现。通过 Mapper 类的静态 Instance 属性来实例化一个 SqlMapper 对象。 这样的设计可能有一部分是出于性能方面的考虑。因为在初始化 SqlMapper 对象,需要初始 iBatis 运行环境配置,读取和初步解析包含的各个映射文件,所以在在系统运行时第一次调用 iBatisNet API 的时候,可能会需要比较长来处理这个配置。 Mapper.Instance 属性的实现如下:

public   static  SqlMapper Instance()

{

      
if  (Mapper._mapper  ==   null )

      {

            
lock  ( typeof (SqlMapper))

            {

                  
if  (Mapper._mapper  ==   null )

                  {

                        Mapper.InitMapper();

                  }

            }

      }

      
return  Mapper._mapper;

}


所以在使用 API 的时候可以像下面的这么简单:

Mapper .Instance().Insert("ContentObject_DefaultInsert" , p_dataObject);

当然,如果愿意而且有必要的话,也完全可以由自己来实例化这个对象,我们可以直接使用 DomSqlMapBuilder ,它为我们提供这样的扩展能力,通过它的多种实例方法都可以返回出 SqlMapper 对象: Build Configure ConfigureAndWatch 在需要用到多个数据库或是多种不同数据库类型的场合下,这种方法是非常有用的。

 

注意:在使用一个接口时,使用的

statementName
要在对应类型的
statement
类型。比如在使用
Insert
接口时,如果你指定的是一个
select
类型配置语句的话,那将会抛出异常。因为每一种
statement
类型都对应一种类型,比如如
select
类型的配置语句对应的是
SelectMappedStatement
类,它是从
MappedStatement


继承下来,而它的
ExcuteInsert
方法是这样实现的


public   override   object  ExecuteInsert(IDalSession session,  object  parameterObject)

{

      
throw   new  DataMapperException( " Update statements cannot be executed as a query insert. " );

}




这样就保证了每一种语句类型的职责明确。



阿不 http://hjf1223.cnblogs.com
原文地址:https://www.cnblogs.com/cpcpc/p/2123140.html