iBatis 的核心就在于映射文件 (Data Map XML File) 。在映射文件里可以定义包括要执行各种 SQL 语句,存储过程,输入参数映射,返回结果映射,缓存机制,并且能通过几种相对比较复杂的配置实现对象之间的关联关系和延迟加载。这也是 iBatis 区别 ORM 框架的,具备更灵活性,更高性能的关键所在。
配置文件可以写得很简单,也可以很复杂。复杂配置文件也是出于更好的设计,更好性能,更好扩展性方面的目的。再复杂的配置文件也是有限的,一个映射文件包括: Mapped Statements 、 Parameter Maps 、 Result Maps 、 Cache Models 几个主要的配置,还包括命名空间的配置,类型别名(前一篇中有介绍)的配置。
1 . Mapped Statements :顾名思义就是映射的语句声明。它是整个 iBatis 配置核心的核心,真正将被执行的 SQL 语句(或存储过程)都是必须在这里被显式声明。在 Mapped Statements 里可以包含有: statement 、 select 、 insert 、 update 、 delete 、 procedure 这 6 种不同的语句类型。从词面理解相信就可以了解到这些类型功能的一大半了。 statement 可以包含所有类型的 SQL 语句(存储过程),它是一个泛泛的语句配置,没特别明确的职责,相反,其它 5 种类型的语句配置就是专门负责各种不同的 SQL 语句。下面这张图列出了各种类型的语句的不同职责和调用方法。
2 . Parameter Maps :参数映射的配置,它是被用来向一个语句 (statement) 提供所需参数的配置。每一个 Parameter Maps 都有一个自己的 ID ,在需要的时候需要在 statement 的 parameterMap 属性中提供它的 ID 。但是对一个语句来说,它并不是必须,在 iBatis 中还支持内联参数 (Inline Parameter Maps) 的形式,我们不需单独写一个 Parameter Maps 配置,只需要向 parameterClass 提供参数的类型,可以是元数据类型,复合数据类型, IDictionary 数型的弱类型对象 ( 使用 key,value 的键值对 ) 。在内部访问数据类型的时候只使用 #property# 的形式访问对应的属性值。
注意:在任何地方使用到的 parameterClass 类型如果是一个元数据类型( int,string etc ),都需要使用 #value# 的形式的来访问它的值。
3 . Result Maps :返回结果的映射关系配置,就是列与属性的对应关系。在 statement 中使用 resultMap 属性来指定一个结果映射。对一个 statement 来说, resultMap 也不是必须的,同样的,它仍然可以被 resultClass 给代替,因为如果返回出结果数据集的列名跟数据对象的属性相同的话,它会自动去匹配,但是它不保证所有列都被会被正确映射(当某列名在对象中找不对应的属性名,这列值将不被处理)。而 resultMap 则不同,如果已经在 resultMap 中定义将要使用到列或属性在结果集或数据对象中不存在,将会被认为是错误的,将会抛出异常。通过上面的表可以看到 insert,update,delete 三种语句类型是没有 resultMap 和 resultClass ,因为原则上来说,它们的操作是没有必要返回结果集。
注意:如果在一个 statement 中同时指定了 resultMap 和 resultClass 属性的话,那将会优先使用 resultMap 。同时 result Map 也是一个实现对象复杂查询功能的重要手段,如: result map 的继承(与 discriminator 配合使用),对象的 1..1 、 1..N 关系查询。
4 . Cache Model :缓存模型。使用在 Cache Model 中定义好的缓存机制,只需在查询语句配置的 cacheModel 属性就可以很容易地缓存查询返回的数据集。在 iBatis 中提供了三种的类型的缓存模式 (Memory , LRU,FIFO) 算法。三种算法主要在于静态过期策略上的不同,而它们都有相同的动态过期依赖策略,即可以设置执行哪些 statement 时,缓存过期。
注意: iBaits 的缓存模型正常情况是非常好用的,但是因为缓存过期策略上的封装性,它在多个服务器,负载平衡场景下还是有它的局限性。