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
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 搞它!!!Linux构建远程YUM仓库与NFS共享存储服务
- 排障集锦:九九八十一难之第四难! yum下载软件发现已存在的 RPM 数据库问题,无法下载,
- 搞它!!!深入了解DNS域名解析服务,教你搭建一个属于自己的DNS服务器(正向解析、反向解析、泛域名解析、邮件交换解析、别名解析、分离解析,主从结构解析)
- Nginx Ingress 高并发实践
- 搞它!!!2020年了,你还不会PXE+kickstart 一键式部署安装系统么
- shell脚本快速入门系列—————— shell脚本编程规范
- shell脚本快速入门系列之------条件语句(if、case)
- 搞它!!!2020年了你还不会Cobbler自动装机么(装机步骤,优化内容详解,导入系统镜像步骤,cobbler-web管理认证方式
- 搞它!!!深入了解FTP文件传输服务
- 搞它!!!CentOS 7.6 安装和配置samba文件共享服务
- shell脚本快速入门系列之------变量
- 弄它!!! 深入了解STP生成树协议
- kali linux下的常用bash命令
- shell脚本快速入门之-----linux设置 自定义脚本开机启动,一键式部署网卡配置文件
- jdbc连接oracle语法