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 语句:
SELECTPRODUCTID,
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 语句先有个感性认识:
SELECTPRODUCTID,
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 到底应该用在哪里,这很重要。
系列文章: