MyBatis知多少(4)MyBatis的优势
MyBatis是一个混合型解决方案。它汲取了所有这些解决方案中最有价值的思想并将它们融会贯通。下表总结了MyBatis从我们之前讨论的那些方案中所汲取的思想。
方 案 | 相同的优点 | 解决的问题 |
存储过程 | MyBatis对SQL进行了封装和外部化,使SQL从你 的应用程序代码中分离出来。MyBatis具有与存储 过程相似的API,但MyBatis的这些API是面向对象 的。MyBatis也完全支持对存储过程的直接调用 | 业务逻辑从数据库中分离出来,应用程序更容易部署与测试,也具有更好的可移植性 |
内联SQL | MyBatis允许SQL以其最自然的方式书写。没有字符串拼接,没有参数“设置”,没有结果“获取” | MyBatis对应用程序代码没有任何影响。不需要任何预编译器,并且你能够完全访问 SQL的所有特性,而不只是一个子集 |
动态SQL | MyBatis提供了若干特性以支持基于参数的动态 构建査询。不需要“査询构建工具”这样的API | MyBatis不要求SQL被写成一堆字符串的拼接,中间还夹杂着应用程序的代码 |
O/RM | MyBatis支持许多与O/RM工具一样的特性,例如 延迟加载、连接抓取、高速缓存、运行时代码生成 以及继承 | MyBatis可用于任意数据模型与任意对象模型的组合。它对这两者中的任何一个的设 计没有任何约束和要求 |
现在你已经理解MyBatis的根本思想了,接下来将讨论MyBatis持久层所具有的两个最重要的特性:外部化SQL和封装SQL。这两个概念展现了MyBatis框架的核心价值,并启用了这个框 架所能实现的许多高级特性。
外部化的SQL
我们可以从过去的软件开发中学习到的一条经验就是“总是将一个大系统设计为多个子系统,每个子系统的功能都相对集中”。应该尽可能地将那些需要由不同的开发角色处理的任务分离开,例如,用户界面设计人员专职设计用户界面,应用程序开发人员专职开发应用程序,数据库管理人员专职管理数据库。即使只有一个人来扮演所有这些角色,这种分离也能够使你拥有一个漂 亮的分层设计,使你总是能专注于系统的某个特定部分。如果将SQL嵌入到Java源代码中,那么这 些SQL对于数据库管理人员或者对于使用相同数据库的.NET开发人员来说就没有任何用处。外部化将SQL从应用程序的源代码中分离出来,从而使得两者都更加清晰。这样做就保证了SQL语句与任何特定的语言或平台都相对地独立。大多数现代开发语言都将SQL表现为一个字符串类型,这就 使得那些较长的SQL语句需要使用字符串拼接操作。考虑下面这个简单的SQL语句:
SELECT PRODUCTID, NAME, DESCRIPTION, CATEGORY • FROM PRODUCT WHERE CATEGORY = ?
当在现代编程语言(例如Java)中嵌入一个这样的字符串数据类型时,这个原本很简单的SQL 语句就变成了一团“乱七八糟”的字符串,难以管理了。
String s = "SELECT" + " PRODUCTID," + " NAME," + " DESCRIPTION," + " CATEGORY" + " FROM PRODUCT" + " WHERE CATEGORY = ?"
如果忘记在FROM子句前留一个空格,那么就会引起SQL错误。很容易想象,如果你有一条复杂的SQL语句,那将会引起多大的麻烦。
这时MyBatis的一个主要优点就体现出来了:使用MyBatis你就拥有按照最自然的方式书写SQL 的能力。以下代码让你对经iBATIS映射后的SQL语句先有个感性认识:
SELECT PRODUCTID, NAME, DESCRIPTION, CATEGORY FROM PRODUCT WHERE CATEGORY = #categoryId#
注意该SQL不论是结构还是简单性都没有变化。它与之前的SQL最大的不同之处就在于参数的格式变为了#kategoryld#,这个格式通常是特定于语言的细节,MyBatis却使得它易移植且更具可读性。
现在我们已经将SQL从源代码中分离了出来,并且放在了一个可以更自然地使用的地方,接 下来只要将它重新与我们的软件建立起连接,就可以执行它了。
封装化的SQL
计算机编程领域一个最古老的概念就是模块化。在一个过程化的应用程序中,代码可能被分 成许多文件、函数和过程。在面向对象的应用程序中,代码常常被组织为类和方法。封装 (encapsulation)是模块化的一种形式,它不仅将代码组织到一个内聚的模块中,而且还将实现细 节隐藏了起来而仅仅向调用该类的代码暴露出它的接口。
封装的概念稍做扩展也可以应用到持久层中。可以通过定义SQL的输入和输出(例如它的界面)来封装它,这样应用程序的其他部分就不需要知道具体的SQL语句了。如果你是一个面向对 象的软件开发人员,那么可以像理解接口与实现的分离一样来理解这种封装。如果你是一个SQL 开发人员,那么可以像理解存储过程对SQL的隐藏一样来理解这种封装。
MyBatis使用XML (extensible Markup Language,可扩展标记语言)来封装SQL。所以选择 XML是因为它具有很好的跨平台性,并且得到了行业内的广泛采用,还有就是XML可能会像SQL 一样被长期使用下去,其生命可能会比其他任何一种语言或文件格式都长。MyBatis使用XML映射SQL语句的输入和输出。大多数的SQL语句都会有一个或更多的参数,会产生一堆表格化的数 据作为结果。或者说,结果被组织成了一系列的行和列。iBATIS允许你很容易地将输入输出参数 映射为某些对象的特性(property)。如下例所示:
<select id=categoryByld" parameterClass="string" resultClass="category"> SELECT CATEGORYID, NAME, DESCRIPTION FROM CATEGORY WHERE CATEGORYID = #categoryld#
注意包围在SQL语句周围的XML元素。这就是对SQL的封装。这个简单的<select>元素定 义了我们的语句的名字、输入参数类型以及输出结果类型。对于一个面向对象的软件开发人员来说,这就像是一个方法的签名。
通过对SQL的外部化和封装,我们获得了简单性和一致性。关于MyBatis的API如何使用以及SQL映射的语法细节,我们将在后面讨论。在此之前,我们首先应该知道,在架构应用程序中,MyBatis到底应该用在哪里,这很重要。
系列文章:
MyBatis知多少(4)MyBatis的优势的更多相关文章
- MyBatis知多少(26)MyBatis和Hibernate区别
iBatis和Hibernate之间有着较大的差异,但两者解决方案很好,因为他们有特定的领域.我个人建议使用MyBatis的,如果: 你想创建自己的SQL,并愿意维持他们. 你的环境是由关系数据模型驱 ...
- MyBatis知多少(26)调试
这是很容易,同时与iBATIS的工作程序进行调试. iBATIS有内置的日志支持,并适用于下列日志库,并在这个顺序搜索他们. Jakarta Commons日志记录(JCL). Log4J JDK 日 ...
- MyBatis知多少(25)动态SQL
使用动态查询是MyBatis一个非常强大的功能.有时你已经改变WHERE子句条件的基础上你的参数对象的状态.在这种情况下的MyBatis提供了一组可以映射语句中使用,以提高SQL语句的重用性和灵活性的 ...
- MyBatis知多少(24)存储过程
使用MyBatis配置来调用存储过程.为了理解这一章,首先需要了解我们是如何在MySQL中创建一个存储过程. 在继续对本节学习之前,可以自行学习MySQL存储过程. 我们已经在MySQL下有EMPLO ...
- MyBatis知多少(23)MyBatis结果映射
resultMap的元素是在MyBatis的最重要和最强大的元素.您可以通过使用MyBatis的结果映射减少高达90%的JDBC编码,在某些情况下,可以让你做JDBC不支持的事情. ResultMap ...
- MyBatis知多少(22)MyBatis删除操作
本节从表中使用MyBatis删除记录. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( id INT NOT NULL auto_increment, f ...
- MyBatis知多少(21)更新操作
上一章展示了如何使用MyBatis对表进行读取操作.本章将告诉你如何在一个表中使用MyBatis更新记录. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( ...
- MyBatis知多少(20)MyBatis读取操作
上篇展示了如何使用MyBatis执行创建操作表.本章将告诉你如何使用MyBatis来读取表. 我们已经在MySQL下有EMPLOYEE表: CREATE TABLE EMPLOYEE ( id INT ...
- MyBatis知多少(19)MyBatis操作
若要使用iBATIS执行的任何CRUD(创建,写入,更新和删除)操作,需要创建一个的POJO(普通Java对象)类对应的表.本课程介绍的对象,将“模式”的数据库表中的行. POJO类必须实现所有执行所 ...
随机推荐
- RTMP协议
Real Time Messaging Protocol(实时消息传送协议协议)概述 实时消息传送协议是Adobe Systems公司为Flash播放器和服务器之间音频.视频和数据传输开发的私有协 ...
- AndroidStudio的一些坑
以下环境为Android Studio 1.3.2,Gradle 2.7(as自带2.4,另下载的2.7) 编译时提示Multiple dex files define: Lcom/sina/weib ...
- 采用TL026等构成的宽带ALC放大器电路图
Building a Differential Amplifier An op-amp with no feedback is already a differential amplifier, am ...
- ORACLE 监听日志文件太大停止写监听日志引起数据库连接不上问题
生产库监听日志文件太大(达到4G多),发现oracle停止写监听日志,检查参数log_file,log_directory,log_status 均正常,数据库运行也正常. 经确认确实为监听日志过大引 ...
- Swift入门篇-闭包和函数
今天主要是给大家分享的是 swift中闭包的用法,我个人觉得闭包就是函数的简写方法,如果您函数不是很熟悉请查阅 swift入门篇-函数 1:函数类型 函数类型 var 变量 :(类型)->返回值 ...
- spring scope="prototype", scope="session"
转自: http://www.cnblogs.com/JemBai/archive/2010/11/10/1873954.html struts+spring action应配置为scope=&quo ...
- WindowsPhone-GameBoy模拟器开发六--[转]指令系统实现必读:补码
网上有同行写了些好文章,在此就不现丑了,贴上连接,放在这里为了补充系列的完整性 计算机为什么选用二进制补码 为什么补码重要?因为计算机中内存.寄存器里面存的数都是用补码表示的!
- NuGet学习笔记(转)
NuGet学习笔记(1)——初识NuGet及快速安装使用 http://kb.cnblogs.com/page/143190/ 1. NuGet是什么? NuGet is a Visual Studi ...
- EF中一对多的关系中,用单字段保存ID拼接字符串
model.SubjectTerms = model.SelectedSubjectTerm.Trim(',').Split(',').ToList().Select(x => new Subj ...
- gradle 如何操作命令行
如题: 官方做法: task startApp(type: Exec){task -> workingDir mWorkingDirRoot commandLine 'cd'} 后来我看到这篇文 ...