iBatis.Net(6):Data Map(深入)

在上一篇中,我写了几个最最基本的DataMap映射,但是如果仅仅是这些功能的话,那iBatis真就有点愧对它的粉丝啦,我个人的理解,iBatis真的可以让开发者眼前一亮的特性在于它的动态SQL,在这一篇中,就会详细的阐述它

在一个数据映射定义文件中,可以存在多个 Cache Models,Type Aliases,Result Maps,Parameter Maps,Statements,而且可以在不同的数据映射中使用

数据操作指令映射

<statement id=”statement name”

    [parameterMap=”parameterMap name”]

    [parameterClass=”classname|alias”]

    [resultMap=”resultMap name”]

    [resultClass=”classname|alias”]

    [listClass=”classname|alias”]

    [cacheModel=”cacheModel name”]

    [extends=”statement name”]

>

select|insert|update|delete ……where property=[?|property name]

</statement>

在这里

id:statement的id属性是必须的,也是唯一的,它是SQL指令的名字,在查询API中使用它作为第一个参数来确定使用的数据指令,

parameterMap:在带有参数的SQL语句中,使用一个parameterMap定义各个值与“?或者参数的对应,例如

<parameterMap id=”demo” class=”Customers”>

    <parameter property=”CustomerIdent”/>

    <parameter property=”ConpanyName”/>

    <parameter property=”ComtantName”/>

</parameterMap>

<statement id=”SelectCustomers” parameterMap=”demo” resultMap=”******”>

Insert into Customers (CustomerIdent,ConpanyName,ComtantName)values(?,?,?)

</statement>

parameterClass ":我们也可以使用parameterClass来指定传入一个实体类的类型,在实际引用中parameterClass的使用通常比parameterMap多一点

resultMap/resultClass:与前两个属性想对应,不过这是两个输出结果属性的定义,区别是,返回的列名与执行Class或者Map中的属性的对应是自动的,是不需要我们手动指定的

listClass:为了支持数据库操作中获取对象列表,DataMapper提供了对强类型对象集合的支持,通过listClass属性可以指定一个CollectionBase类,同时还必须为它指定一个resultClass属性,以确定集合中存放的对象类型

cacheModel:如果需要对查询结果进行缓存设置,可以在statement中指定一个cacheModel元素,cacheModel的定义如下:

<cacheModels>
    <cacheModel id="demo" implementation="LRU">
      <flushInterval hours="24"/>
      <flushOnExecute statement="SelectAllCustomers"/>
      <property name="size" value="1000"/>
    </cacheModel>
  </cacheModels>

这里表示把SelectAllCustomers查询的最后1000条数据保存24小时

extends:在编写SQL语句的时候,经常会遇到重复使用某一段SQL语句的情况,这时,就可以使用extends来避免这种重复,例如
<select id="SelectAllCustomers" resultMap="Customer">
      Select * from Customers
    </select>

    <select id="SelectAllCustomerOrderByCustomerID" resultMap="Customer" extends="SelectAllCustomers">
      order by CustomerID
    </select>

parameterMap的属性

它可以接受三个属性,id/class/extends,其中是有id是必须的,class用于声明使用的实体类名称,可以是别名,也可以是全名,extends,可想而知,不解释

在它下一级节点中应该包含若干个parameter元素,来指定对象属性与当前变量的映射规则,parameter有如下常用属性:

property:指定类中的一个属性

columu:定义的参数名称

direction:用于声明存储过程的参数方向(input,output,inputoutput)

dbType:用于指定property映射到数据库中的数据类型

type:用于为参数的对象指定CLR类型

nullValue:指定在property为何值时,将会在存储数据时候,替换为null,这是经常会被用到的

size:用于指定最大值

resultMap的属性

它的属性很多是和parameterMap想对应的,但是值得一提的是它下面可以添加一个constructor元素来匹配一个构造函数例如

resultMaps>
    <resultMap id="Customer" class="Customers">
      <constructor>
        <argument argumentName="CustomerIdent" column="CustomerID"/>
        <argument argumentName="CompanyName" column="CompanyName"/>
      </constructor>
      <result property="CustomerIdent" column="CustomerID"/>
      <result property="CompanyName" column="CompanyName"/>
      <result property="ContactName" column="ContactName"/>
      <result property="ContactTitle" column="ContactTitle"/>
      <result property="Address" column="Address"/>
      <result property="City" column="City"/>
      <result property="Region" column="Region"/>
      <result property="PostalCode" column="PostalCode"/>
      <result property="Country" column="Country"/>
      <result property="Phone" column="Phone"/>
      <result property="Fax" column="Fax"/>
    </resultMap>
  </resultMaps>

当然,这个的前提是Customers类中有这样一个构造函数

存储过程

<procedure id="demoProcedure" parameterMap="procedureDemo">
      CustOrderHist
    </procedure>

这里有一点区别就是,只可以使用parameterMap,而不可以使用parameterClass,其实想一想,您难道还会为每一个存储过程定义个传入的实体类吗?还有一点,就是他的参数完全是按照 parameterMap中的定义自动匹配的

对SQL片段的引用

在编写SqlMaps的时候,经常需要把一个SQL语句进行拆分,然后在不通的地方引用它我们可以使用sql和include的组合来完成

例如

<sql id="test">
      order by CustomerID
    </sql>

    <select id="SelectAllCustomerOrderByCustomerID" resultMap="Customer">
      order by CustomerID
      <include refid="test"/>
    </select>

XML转义字符

在XML文档中,有些字符是有特殊含义的,最经典的就是“>”,“<”,在iBatis的映射文件中,可以XML语法CDATA来规避这个问题

<select id="test" resultClass="User">
      <![CDATA[
        select * from User where age>18
      ]]>
    </select>  

缓存模式

这个话题,我将在下一篇中写到,继续关注吧,呵呵

动态SQL 重头戏终于来啦

其实上面所有的一切内容,其他很多框架几乎都可以实现的,但是为什么小白和很多人一样钟情与iBatis呢,我想就是动态SQL是一个很大的原因,也许您在小的项目中,并不会感觉这回给您带来多少好处,但是一旦对数据库的操作有非常复杂,而且零碎的判断条件一大堆的时候,这种动态SQL的,对于项目的开发效率等等都会有很大的提高,

想象我们在使用ADO.NET的时候,会在很多情况下使用判断语句,然后一点一点的拼接字符串,如果你连着一个礼拜都在做这样的事情,想象一下。。。。。。

而在iBatis.Net中,就提出了一种相对比较好的解决方案(相对,只是保守的说),考虑以下的一个例子

<select id="SelectAllCustomers" resultMap="Customer" parameterClass="Customers">
      Select * from Customers where 1=1
      <dynamic>
        <isNotNull property="CustomerIdent" prepend="And">
          CustomerID=#CustomerIdent#
        </isNotNull>
      </dynamic>
    </select>

这种情况下,如果我们传入的Customers实例中,CustomerIdent属性是一个NULL,则会生成的SQL语句就是

Select * from Customers where 1=1

如果CustomerIdent不为NULL,生成的SQL语句就是

Select * from Customer where 1=1 and CustomerID=#CustomerIdent#

这样,很明显,我们通过判断Customers实例中属性是否为空,而生成了两条不同的SQL语句,这比我们通过if-else来判断的方式,不知道要方便多少倍

在所有的动态属性中,大概可以分为一元条件元素,二元条件元素(比较条件元素)和 参数检查条件元素,在使用二元条件元素的时候,需要添加一个comparevalue属性作为比较对象

一元条件元素:

isPropertyAvailable/isNotPropertyAvailable

isNull/isNotNull

isEmpty/isNotEmpty

二元条件元素:

isEqual/isNotEqual

isGreaterEqual/isGreaterThan

isLessEqual/isLessThan

参数检查条件元素:

isParameterPresent/isNotParameterPresent

iterate

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

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏码农之路_构建基础

基于汇编的 C/C++ 协程 - 切换上下文

既然本系列讲的是基于汇编的 C/C++ 协程,那么这篇文章我们就来讲讲使用汇编来进行上下文切换的原理。

1906
来自专栏JAVA高级架构

Java 面试题:百度前200页都在这里了

基本概念 操作系统中 heap 和 stack 的区别 什么是基于注解的切面实现 什么是 对象/关系 映射集成模块 什么是 Java 的反射机制 什么是 ACI...

3396
来自专栏云瓣

Node.js编程之异步

异步操作 Node采用V8引擎处理JavaScript脚本,最大特点就是单线程运行,一次只能运行一个任务。这导致Node大量采用异步操作(asynchronou...

2915
来自专栏java达人

最有价值的50道java面试题(一)

来自骆昊的技术专栏 1、面向对象的特征有哪些方面? 答:面向对象的特征主要有以下几个方面: 1)抽象:抽象是将一类对象的共同特征总结出来构造类的过程,...

22010
来自专栏学习力

《Java从入门到放弃》JavaSE入门篇:异常

1533
来自专栏简书专栏

Python面对对象编程

面向过程:根据业务逻辑从上到下写代码 函数式:将某功能代码封装到函数中,日后便无需重复填写,仅调用函数即可 面对对象:对函数进行分类和封装,让开发"更好更快...

643
来自专栏iOS技术杂谈

Python Garbage Collection 与 Objective-C ARCPython GC 与 Objective-C ARC

转载请注明出处 https://cloud.tencent.com/developer/user/1605429 Python GC 与 Objective-C...

2777
来自专栏JAVA同学会

mysql如何执行关联查询与优化

在数据库中执行查询(select)在我们工作中是非常常见的,工作中离不开CRUD,在执行查询(select)时,多表关联也非常常见,我们用的也比较多,那么my...

513
来自专栏恰同学骚年

【译】.NET中六个重要的概念:栈、堆、值类型、引用类型、装箱和拆箱

  一来是为了感受国外优秀技术社区知名博主的高质量文章,二来是为了复习对.NET技术的基础拾遗达到温故知新的效果,最后也是为了锻炼一下自己的英文读写能力。因为是...

472
来自专栏好好学java的技术栈

“面试不败计划”:集合、日期、异常、序列化、其他知识点

862

扫描关注云+社区