iBatis.net技术实践
随着大数据技术的兴起和快速发展,人们更多的开始关注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技术实践的更多相关文章
- fir.im 持续集成技术实践
互联网时代,人人都在追求产品的快速响应.快速迭代和快速验证.不论是创业团队还是大中型企业,都在探索属于自己的敏捷开发.持续交付之道.fir.im 团队也在全面实施敏捷,并推出新持续集成服务 - flo ...
- 让互联网更快:新一代QUIC协议在腾讯的技术实践分享
本文来自腾讯资深研发工程师罗成在InfoQ的技术分享. 1.前言 如果:你的 App,在不需要任何修改的情况下就能提升 15% 以上的访问速度,特别是弱网络的时候能够提升 20% 以上的访问速度. 如 ...
- 【公开课】【阿里在线技术峰会】魏鹏:基于Java容器的多应用部署技术实践
对于公开课,可能目前用不上这些,但是往往能在以后想解决方案的时候帮助到我.以下是阿里对公开课的整理 摘要: 在首届阿里巴巴在线峰会上,阿里巴巴中间件技术部专家魏鹏为大家带来了题为<基于Java容 ...
- Redis数据库云端最佳技术实践
欢迎大家前往腾讯云+社区,获取更多腾讯海量技术实践干货哦~ 本文由腾讯云数据库 TencentDB发表于云+社区专栏 邹鹏,腾讯高级工程师,腾讯云数据库Redis负责人,多年数据库.网络安全研发经验. ...
- 让AI简单且强大:深度学习引擎OneFlow技术实践
本文内容节选自由msup主办的第七届TOP100summit,北京一流科技有限公司首席科学家袁进辉(老师木)分享的<让AI简单且强大:深度学习引擎OneFlow背后的技术实践>实录. 北京 ...
- 腾讯技术分享:GIF动图技术详解及手机QQ动态表情压缩技术实践
本文来自腾讯前端开发工程师“ wendygogogo”的技术分享,作者自评:“在Web前端摸爬滚打的码农一枚,对技术充满热情的菜鸟,致力为手Q的建设添砖加瓦.” 1.GIF格式的历史 GIF ( Gr ...
- 子弹短信光鲜的背后:网易云信首席架构师分享亿级IM平台的技术实践
本文原文内容来自InfoQ的技术分享,本次有修订.勘误和加工,感谢原作者的分享. 1.前言 自从2018年8月20日子弹短信在锤子发布会露面之后(详见<老罗最新发布了“子弹短信”这款IM,主打熟 ...
- IPv6技术详解:基本概念、应用现状、技术实践(下篇)
本文来自微信技术架构部的原创技术分享. 1.前言 在上篇<IPv6技术详解:基本概念.应用现状.技术实践(上篇)>,我们讲解了IPV6的基本概念. 本篇将继续从以下方面展开对IPV6的讲解 ...
- IPv6技术详解:基本概念、应用现状、技术实践(上篇)
本文来自微信技术架构部的原创技术分享. 1.前言 普及IPV6喊了多少年了,连苹果的APP上架App Store也早已强制IPV6的支持,然并卵,因为历史遗留问题,即使在IPV4地址如果饥荒的情况下, ...
随机推荐
- MVC使用jQuery从视图向控制器传递Model,数据验证,MVC HTML辅助方法小结
//MVC HTML辅助类常用方法记录 (1)@Html.DisplayNameFor(model => model.Title)是显示列名, (2)@Html.DisplayFor(model ...
- 固定GridView标题栏,冻结列功能实现
<%@ Page Language="C#" %> <%@ Import Namespace="System.Data" %> < ...
- hiveQL去重
去重: 以id进行分组,然后取出每组的第一个 ; 以id进行分组,按照create_time降序排序后,然后取出每组的第一个 ; 将去重后的数据重新存储 ; 去重之后与其他表join算匹配数 sele ...
- MySQL主从复制 + Mycat实现读写分离
说明:两台MySQL服务器都是使用CentOS6.5系统,MySQL版本为mysql-5.7.17 MySQL一主一被实现主从复制 注意:写包括insert,delete,update 操作:读只有s ...
- MySql5.7创建数据库与添加用户、删除用户及授权
MySql安装启动成功后(不会的可以查看上篇MySql5.7安装及配置),首先我们需要创建数据库,然后创建一个用户去操作这个数据库: 一.创建数据库 在MySql命令行中输入: create data ...
- iOS 11 & iPhone X 适配资料集
本文主要简单谈谈并收集一些关于 iOS 11 & iPhone X 的适配及设计指南. iPhone X 众所周知,iPhone X 屏幕与其他的 iPhone 设备均不同,苹果称 iPhon ...
- Java爬虫
作为一位Java爬虫的初学者,分享一下自己的心得.所用到的jar包 org.codehaus.jettison.jar jsoup-1.7.3.jar个人认为爬虫的实现机制:获取Docume对象-&g ...
- codeforces 258D
D. Little Elephant and Broken Sorting time limit per test 2 seconds memory limit per test 256 megaby ...
- 翻译:MLAPP(2.3节 一些常见的离散分布)
笔者:尝试翻译MLAPP(Machine Learning: a Probabilistic Perspective)一书,供机器学习的学者参考,如有错误理解之处请指出,不胜感激!(如需转载,请联系本 ...
- 06-从零玩转JavaWeb-数组在内存当中的存放形式
一.JVM的内存划分 想要了解数组的内存存储,先要了解JVM的整体内存划分,详细参见第04JVM内存详解 二.数组在JVM当中的存储详解 假如我们有如下代码: 上面代码当中,创建数组的过程我们可以把 ...