对于简单的iBatis应用场合来说,我想大部分都是集中在与SqlMapper对象打交道。这个类应该说是一个工具类,因为我们一般都是直接调用这个类的方法去执行QUID操作,但是它却不是真正的去做这些事情。因为iBatis内部有很多的类,对象之间的关系是非常复杂的,如果让客户直接去使用它内部方法,无疑增加了使用的复杂性,同样也会产生很多的冗余代码。因此这里它使用外观设计模式,通过SqlMapper类封装了iBatis执行数据库访问的复杂操作,包括打开一个会话(Session),获取返回IMappedStatement对象实例,执行数据库访问,关闭连接等相关操作。这样我们在使用iBatis API的时候就可以非常简单调用的一个方法,就可以做所有的事情了。比如查询接口public IList QueryForList(string statementName, parameterObject),它的内部实现代码是这样的。
}
IMappedStatement Name);
statement1
= this.GetMappedStatement(statement
try
{
list1 erObject);
= statement1.ExecuteQueryForList(session1,
paramet
}
catch
{
throw;
}
finally
那这些代码如果直接在客户代码中去实现,可想而知工作量会有多大。并且还法保证正确性。 以上简单看了一个SqlMapper的作用,那该怎样实例化这个对象呢?实例化它也是一个非常简单的事情。在iBatisNet中,SqlMapper对象默认是一个单件模式的实现。通过Mapper类的静态Instance属性来实例化一个SqlMapper对象。这样的设计可能有一部分是出于性能方面的考虑。因为在初始化SqlMapper对象,需要初始
iBatis运行环境配置,读取和初步解析包含的各个映射文件,所以在在系统运行时第一次调用iBatisNet API的时候,可能会需要比较长来处理这个配置。Mapper.Instance属性的实现如下:
所以在使用API的时候可以像下面的这么简单:
当然,如果愿意而且有必要的话,也完全可以由自己来实例化这个对象,我们可以直接使用DomSqlMapBuilder,它为我们提供这样的扩展能力,通过它的多种实例方法都可以返回出SqlMapper对象:Build,Configure,ConfigureAndWatch。在需要用到多个数据库或是多种不同数据库类型的场合下,这种方法是非常有用的。
注意:在使用一个接口时,使用的statementName要在对应类型的statement类型。比如在使用Insert接口时,如果你指定的是一个select类型配置语句的话,那将会抛出异常。因为每一种statement类型都对应一种类型,比如如select 类型的配置语句对应的是SelectMappedStatement类,它是从MappedStatement继承下来,而它的ExcuteInsert方法是这样实现的
这样就保证了每一种语句类型的职责明确。
系列(5) ParameterMap
在用进行数据库访问操作中,最麻烦的就是准备DbCommand必须为它添加DbParameter,特别是当要传的参数特别多的情况下,数据访问层的很多代码都是花在这里。iBatis的ParameterMap配置就是针对这个问题所提出的一种解决方案,基于xml的配置,把字段名和对象的属性对应起来,通过运行时的一些工作,自动为DbCommand提供它所需的参数集合。从而避免了我们直接写很多重复代码。
在Employees_ParameterMap.xml配置文件中:
使用的是内联参数映射的方式,语句的在执行查询时只需为它提供Employee类型的对象,它就会自动去读自己需要的EmployeeID,LastName属性的值,返回查询结果。在执行时它所执行的语句如下:
所需的参数的提供方式如下:
并且,在iBatis中还会指出各个参数的类型: