随着大数据技术的兴起和快速发展,人们更多的开始关注HDFS、HBase、Hive等技术。但是谈到强一致性,我们又不得不回归现实,只能继续沿用RDBMS存储强一致性的数据。我们日常接触到的绝大多数的应用(从App到游戏,从互联网应用到SAP)都是基于数据的,应用程序执行的过程也是不断进行数据处理的过程,而应用的设计是面向对象的,数据库更多是面向数据的,两种不同思维造成系统理解、设计的复杂性。同时随着业务复杂度的不断提高,对数据库的依赖也不断增加,逐渐造成系统与数据库耦合过于紧密。

随着面向对象、系统解耦的要求,我们希望能有一种技术实现将数据库结构转化成易于理解的程序数据结构。通过对程序数据的处理,转化为对数据库的操作。而这正是ORM(对象关系映射object Relational Mapping)的一个理论基础。

ORM方法论基于三个核心原则:

简单性:以最基本的形式建模数据。

传达性:数据库结构被任何人都能理解的语言文档化。

精确性:基于数据模型创建正确标准化了的结构。

一、ORM与IBatis

早些年在Java领域有一个非常知名的框架SSH(Spring + Struts +Hibernate)。他们各自承担这不同的职责,实现了表现层、业务层和数据持久化层分离,降低了各层耦合。其中Hibernate则主要是实现了业务层与数据化持久层的解耦。Hibernate建立的理论基础是ORM。它是建立将面向对象的数据转化和操作映射为数据持久化操作的一种技术。

在ORM的领域中除了Hibernate还有很多其他框架。例如EntityFrameword、IBatis等。我们今天要介绍的就是IBatis,这个被称为“半自动化”的ORM框架。

要介绍IBatis首先要说一下“半自动化”这个定语。之所有成IBatis为“半自动化”,是相对于Hibernate而言的。Hibernate可以实现不编写Sql语句实现将业务数据操作转化为数据库操作。IBatis没有像Hibernate那样进行全面的封装,它并没有抛弃Sql语句,甚至它不会减少Sql语句的编写量,它只是提供了一种将Sql语句与系统分离的方式,这也给我们留下了足够了空间发挥Sql的强大语法。

二、IBatis原理

IBatis的基本原理的理解可以从理解官方文档中的这个图开始

IBatis以SqlMap为核心,将输入参数、输出结果进行持久化语句与CLR类型的转化。输入参数类(Parameter object)经过SqlMap中设置的数据处理方式,并结合持久化数据处理方式(ADO.NET),从而产生输出结果类(Result object)。对于.NET应用程序业务处理来说,实现了类的方法处理,从而实现了应用逻辑与数据持久化的隔离。

从上图可以看出,输入参数Parameter object和输出结果Result object均支持集合类型、基本类型、值类型。其中间为核心的数据转化过程。数据转化过程是通过XML配置进行约束的。本文章为技术实践文章,因此重点为IBatis相关配置文件的使用。

三、IBatis配置文件

1、SqlMap.config

IBatis基本运行环境的核心配置文件为SqlMap.config文件。它类似于应用程序的App.config和Web.config。IBatis的其他文件均是通过此配置文件加载到系统中的。基本的SqlMap.config如下图所示:

SqlMap.config主要包括几部分:Settings、providers、database、sqlMaps

Settings主要进行IBatis全局基础配置,它包括三个配置项

节点名

说明

默认值

useStatementNamespaces

是否使用语句命名空间,这里的命名空间指的是映射文件中sqlMap节点的namespace属性。即如果该参数设为"true", 语句调用时需追加命名空间。

FALSE

cacheModelsEnabled

配置是否启用IBatis的配置项缓存机制

TRUE

validateSqlMap

配置是否启用SqlMapConfig.xsd schema验证映射文件

FALSE

其中useStatementNamespaces是在系统环境中可能需要应用的。当值为“true”调用语句时需要添加其配置文件头中命名空间名称。例如

当useStatementNamespaces="true",调用时则需要通过名称“Complex.ComplexMap”,如果为false则通过名称"ComplexMap"进行调用。

Providers配置数据驱动提供类配置文件的路径和文件名。

此配置中对应的文件中描述了多种数据驱动方式,通过配置可以保证IBatis支持市面上主流的数据(如Oracle\MsSql\MySql\sqlite\access等)。如需更换数据库,需要将配置文件中相应启动器的Enabled设置为“true”,并修改Database节中的配置即可。

Database主要用来进行数据库驱动器配置和数据库连接字符串的配置。

provider的值应与providers配置文件中的name对应,并需要将providers配置文件中enabled设置为“true”。

dataSource的值为数据库连接字符串。为了更好的匹配连接字符,减少修改连接字符串的复杂度,可采用properties进行预定义处理。

sqlMaps可以在配置节中添加XML映射文件的位置,以指定项目内所包含的所有映射文件。引用xml文件有三种方式

参数

说明

resource

指定数据驱动配置文件从项目的根目录进行加载,如resource="providers.config"

url

指定数据驱动配置文件从文件的绝对路径进行加载,如url="c:\IBatis\Resources\providers.config"

-或者-

url="file://c:\IBatis\Resources\providers.config"

embedded

指定数据驱动配置文件可以作为程序集的资源文件进行加载,如embedded="Resources.providers.config, MyApp.Data"

配置文件中还有一些其他的配置方式(如properties、alias、typeHandlers),这里就不一一介绍。

2、SqlMap.XML

SqlMap主要包括三部分,入参配置(Parameter)、返回结果配置(Result)、数据操作Sql配置(statements)。

parameter

用于配置入参格式,通过配置传入到statements中,parameter可以用过parameterClass或parameterMap两种方式传入。

parameterClass可配置为应用程序类别名,将相应的类实例传入到IBatis框架,通过其属性名作为SqlMap语句匹配元素进行配置,从而生成相应的Sql语句。

parameterMap可以对parameterClass进行扩展,从而实现空值转化、字段匹配等功能,通过配置的方式实现对空值、名称匹配等的处理。

Result

Resul也包括两种形式,resultClass和resultMap。resultClass配置可以将返回值映射为设定的类的实例,可以将查询结果等映射到相应的类中。

resultMap对resultClass扩展,可以设置数据查询字段与类数据字段的对应关系。

属性

说明

parameterMap

参数映射,需结合parameterMap节点对映射关系加以定义,对于存储过程之外的statement而言,建议使用parameterClass作为参数配置方式,一方面避免了参数映射配置工作,另一方面其性能表现更加出色

parameterClass

参数类。指定了参数类型的完整类名(包括命名空间),可以通过别名避免每次书写冗长的类名

resultMap

结果映射,需结合resultMap节点对映射关系加以定义

resultClass

结果类。指定了结果类型的完整类名(包括命名空间),可以通过别名避免每次书写冗长的类名

其中parameterMap和resultMap格式类似,主要包含如下属性:

属性

说明

property

指定类中的一个属性

column

定义的参数名称

direction

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

dbType

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

type

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

nullValue

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

size

用于指定最大值

注:parameter和result都会涉及到类的属性,按照C#语言特性,属性等均是区分大小写的,因此在进行XML配置时,需要特别注意。

Statements

IBatis进行类和Sql进行相互转化的核心。他主要由id、parameter、result、动态Sql组成,前面初步介绍了id、parameter、result,以下终端介绍动态Sql语句。

为了更灵活的进行Sql语句匹配,IBatis进行了定义了多个运算符。

运算符

条件

说明

例程

isEqual

二元条件

相等

<isEqual prepend="and" property="StartDate" compareValue="25/12/2004">

isNotEqual

二元条件

不相等

<isNotEqual prepend="AND" property="year" compareValue="0">

isGreaterEqual

二元条件

大于等于静态值

<isGreaterEqual compareValue="3" >

isGreaterThan

二元条件

大于

<isGreaterThan prepend="AND" property="Id" compareValue="0"  >

isLessEqual

二元条件

小于等于

<isLessEqual compareValue="3" >

isLessThan

二元条件

小于

<isLessThan compareValue="3" >

isNotEmpty

一元条件

是否不为 null 或不为空

<isNotEmpty prepend="and" property="LastName"  >

isEmpty

一元条件

是否为 null或空

isNotNull

一元条件

检查属性是否不为 null。

<isNotNull prepend="AND" property="FirstName">

isNotParameterPresent

检查是否不存在参数对象

<isNotParameterPresent prepend=”AND”>

isNotPropertyAvailable

一元条件

检查是否不存在该属性

isNull

一元条件

检查属性是否为 null。

isParameterPresent

检查是否存在参数对象(不为 null)。

isPropertyAvailable

一元条件

检查是否存在该属性

iterate

运算符的使用主要是针对输入参数的。

二元运算符

<isEqual property="name" compareValue="1" prepend="and">
a1= 'abc'
</isEqual>

输入参数name属性的值等于1时,将在sql中组合 a1= 'abc',否则不进行Sql组合。

类似isNotEqual、isGreaterEqual、isGreaterThan、isLessEqual、isLessThan等均为类似的用法。

一元运算符

<isEmpty property="name" prepend="and">
a1= 'abc'
</isEqual>

输入参数name属性的值为空时,将在sql中组合 a1= 'abc',否则不进行Sql组合。

数组运算符

将数组转为化sql语句的一种方式,例如

 <iterate property="Ids" open="(" close=")"  conjunction="," ="">
#Ids[]#
</iterate>

将数组转化为类似于“(1,2,3,4,5)”的Sql语句。

通过一系列的配置我们将程序的一个方法或一个对数据库的操作转化为一个SqlMap.Xml中的配置,方法入参转化为parameter,方法出参转化为result,而方法名转化为id,从而实现了面向对象的业务方法转化为数据库操作。

IBatis除了以上语法要点,还包括一些其他语法例如extends、缓存等。完整的语法支持,保证了IBatis对绝大多数场景的支持。本文在很多知识点只是进行了简单的说明,远远没有展示IBatis的全貌。只有通过不断的学习积累,并灵活应用才能发挥其强大的配置功能,才能更好的发挥IBatis的功能,实现真正的业务与数据的分离。

iBatis.net技术实践的更多相关文章

  1. fir.im 持续集成技术实践

    互联网时代,人人都在追求产品的快速响应.快速迭代和快速验证.不论是创业团队还是大中型企业,都在探索属于自己的敏捷开发.持续交付之道.fir.im 团队也在全面实施敏捷,并推出新持续集成服务 - flo ...

  2. 让互联网更快:新一代QUIC协议在腾讯的技术实践分享

    本文来自腾讯资深研发工程师罗成在InfoQ的技术分享. 1.前言 如果:你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度,特别是弱网络的时候能够提升 20% 以上的访问速度. 如 ...

  3. 【公开课】【阿里在线技术峰会】魏鹏:基于Java容器的多应用部署技术实践

    对于公开课,可能目前用不上这些,但是往往能在以后想解决方案的时候帮助到我.以下是阿里对公开课的整理 摘要: 在首届阿里巴巴在线峰会上,阿里巴巴中间件技术部专家魏鹏为大家带来了题为<基于Java容 ...

  4. Redis数据库云端最佳技术实践

    欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB发表于云+社区专栏 邹鹏,腾讯高级工程师,腾讯云数据库Redis负责人,多年数据库.网络安全研发经验. ...

  5. 让AI简单且强大:深度学习引擎OneFlow技术实践

    本文内容节选自由msup主办的第七届TOP100summit,北京一流科技有限公司首席科学家袁进辉(老师木)分享的<让AI简单且强大:深度学习引擎OneFlow背后的技术实践>实录. 北京 ...

  6. 腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践

    本文来自腾讯前端开发工程师“ wendygogogo”的技术分享,作者自评:“在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦.” 1.GIF格式的历史 GIF ( Gr ...

  7. 子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践

    本文原文内容来自InfoQ的技术分享,本次有修订.勘误和加工,感谢原作者的分享. 1.前言 自从2018年8月20日子弹短信在锤子发布会露面之后(详见<老罗最新发布了“子弹短信”这款IM,主打熟 ...

  8. IPv6技术详解:基本概念、应用现状、技术实践(下篇)

    本文来自微信技术架构部的原创技术分享. 1.前言 在上篇<IPv6技术详解:基本概念.应用现状.技术实践(上篇)>,我们讲解了IPV6的基本概念. 本篇将继续从以下方面展开对IPV6的讲解 ...

  9. IPv6技术详解:基本概念、应用现状、技术实践(上篇)

    本文来自微信技术架构部的原创技术分享. 1.前言 普及IPV6喊了多少年了,连苹果的APP上架App Store也早已强制IPV6的支持,然并卵,因为历史遗留问题,即使在IPV4地址如果饥荒的情况下, ...

随机推荐

  1. js 将一大段时间均分为很多个小时间段

    最近写项目,遇到一个将选中时间段平均分割为若干小段,然后根据小段时间在数据库查询求均值的问题,后台大哥犯懒,非说后台做不了,让我分好传给他ヾ(. ̄□ ̄)ツ゜゜゜好气呦,但还要保持微笑,我就是这么懂礼貌 ...

  2. 平板不能设置代理的情况下利用随身wifi进行http代理访问

    需求来源:平板或手机是个封闭系统无法给wifi设置代理,需要利用filllder进行抓包,内容篡改等实验 拥有硬件资源:PC机器 + 小米随身wifi 方案1: NtBind Dns + Nginx ...

  3. 学习笔记之08试用div做网页(滨院)-小作业

    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/ ...

  4. Selenium 设置浏览器下载 Firefox 和Chrome

    当我们在使用Selenium运行自动化测试时,偶尔需要用到下载功能,但浏览器的下载可能会弹出下载窗口,或者下载路径不是我们想要保存的位置,所以在通过Selenium启动浏览器时需要做相关的设置,将使这 ...

  5. Kotlin——最详细的控制语句使用

    在前面 的章节中讲解了Kotlin语言中的数据类型.变量与常量的定义.不了解请参见前面的内容: Kotlin从无到有系列之数据类型介绍. Kotlin从无到有系列之变量.常量.注释的使用. 下面详细为 ...

  6. Java这些冷知识你知道吗?

    1)jvm有很多种,其实jvm是一个标准,sun做的那个叫hotspot,作者就是后来v8的作者lars bak,其他公司也做过jvm,其中做得比较好的有bea的jrockit,其他的包括ibm的r9 ...

  7. HTML笔记<note2>

    文本标记 我是正常的文本段落 我是用b标记的加粗文本 我是用strong定义的强调文本 i标记的倾斜文本 em强调文本 del标记的删除线 del标记的下划线文本 特殊字符标记 显示 说明 空格&am ...

  8. javascript编写一个简单的编译器(理解抽象语法树AST)

    javascript编写一个简单的编译器(理解抽象语法树AST) 编译器 是一种接收一段代码,然后把它转成一些其他一种机制.我们现在来做一个在一张纸上画出一条线,那么我们画出一条线需要定义的条件如下: ...

  9. Zernike不变矩

    1.Zernike矩介绍 Zernike矩是基于 Zernike多项式的正交化函数,所利用的正交多项式集是 1个在单位圆内的完备正交集.Zernike矩是复数矩 ,一般把 Zernike矩的模作为特征 ...

  10. Leetcode题解(23)

    69. Sqrt(x) 题目 分析,题目实现求一个int数的平方根,最暴力的算法就是逐个遍历,从1开始到x,判断是否有一个数i,其中满足i*i<=x,并且(i+1)*(i+1)>x;这个算 ...