上一篇:什么是iBATIS(1)
2.5 iBATIS快速上手
iBATIS框架非常简单,它上手起来同样简单。有多简单呢?使用iBATIS只要五分钟我们就可以创建一个完整的应用程序了——当然这不是大型的ERP(Enterprise Resource Planning)解决方案,也不是大规模的电子商务网站,只是一个简单的命令行工具,它可以执行iBATIS SQL Map中的SQL语句并返回结果到控制台。下面这个例子将配置一个简单的静态SQL语句,查询一个简单的数据表,将结果输出到控制台,效果如下:
输出的数据实在不算漂亮,但足够我们了解iBATIS基本的工作原理了。在下面几个小节中,我们会一步步实现这个功能。
2.5.1 安装数据库
为了建立这个示例程序,我们将使用MySQL数据库。iBATIS框架适用于任何提供了ADO.NET Provider的数据库。您只要提供一个Provider名称,然后配好连接字符串。
安装数据库服务器已经超出了本书的范围,所以我们假定您已经安装了数据库,而且能正常工作。这里的MySQL脚本将创建数据表,然后添加一些示例数据:
# Table structure for table 'user'
#
CREATE TABLE USER_ACCOUNT (
USERID INT(3) NOT NULL AUTO_INCREMENT,
USERNAME VARCHAR(10) NOT NULL,
PASSSWORD VARCHAR(30) NOT NULL,
GROUPNAME VARCHAR(10),
PRIMARY KEY (USERID)
);
#
# Data for table 'user'
#
INSERT INTO USER_ACCOUNT (USERNAME, PASSSWORD, GROUPNAME)
VALUES ('LMEADORS', 'PICKLE', 'EMPLOYEE');
INSERT INTO USER_ACCOUNT (USERNAME, PASSSWORD, GROUPNAME)
VALUES ('JDOE', 'TEST', 'EMPLOYEE');
COMMIT;
如果您已经安装了其它类型的数据库服务器,希望在那上面执行同样的SQL查询,本例的脚本也可以使用。不过需要改变SqlMap.xml中的SQL,以及SqlMap.config中的数据库相关配置。要使它正常工作,需要使用正确地Provider名称和连接字符串。
2.5.2 编写代码
因为这个例子是我们的第一个完整的例子,同时也作为iBATIS的介绍,所以代码比真实的程序要简单得多。我们将在后面讨论类型安全和异常处理,这里暂不考虑。代码清单2.4包含了完整的代码。{
string groupName = "EMPLOYEE";
IList users = Mapper.Instance().QueryForList("getAllUsers", groupName);
Console.WriteLine("Selected " + users.Count + " records.");
string outputFormat = "UserName={0}, Password={1}, UserId={2}, GroupName={3}";
for (int i = 0; i < users.Count; i++)
{
Hashtable user = users[i] as Hashtable;
Console.WriteLine(string.Format(outputFormat, user["USERID"], user["USERNAME"], user["PASSWORD"], user["GROUPNAME"]));
}
Console.ReadLine();
}
就这么简单,我们已经配置了iBATIS,执行了SQL语句,然后使用大约10行C#代码将结果打印了出来。这就是一个功能齐全的iBATIS应用程序所需要的所有C#代码。稍后,我们会解释事实的真相,现在先了解一下基本的配置。
2.5.3 配置iBATIS(预览)
我们打算在下一章中深入探讨iBATIS的配置,所以这里只是简单提及一下,您不会在这里看到各个选项的详细解释,但可以了解一些基本的信息。
首先,看一下SqlMap.config文件。这是iBATIS的切入点,它将所有SQL映射文件(SQL Map)整合在了一起。清单2.5包含了我们示例程序中的SqlMap.config文件。
<sqlMapConfig xmlns="http://ibatis.apache.org/dataMapper" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<providers resource="providers.config" />
<!-- Data Source -->
<database>
<provider name="MySql" />
<dataSource name="iBatisInAction" connectionString="Server=localhost;Port=3306;Database=TestSchema;Uid=root;Pwd=root;" />
</database>
<!-- Sql Map files -->
<sqlMaps>
<sqlMap resource="Maps/UserAccount.xml" />
</sqlMaps>
</sqlMapConfig>
也许您已经猜到,我们在这里告诉iBATIS如何连接到数据库,以及用到了哪些SQL Map文件。它是一个XML文件,首先是命名空间的信息;然后声明了引用的provider定义文件,这个文件中定义了各种可能需要的ADO.NET Provider的信息;接下来是数据源的相关配置,provider节点定义了使用的ADO.NET Provider的信息,dataSource节点则是连接字符串的配置;最后要配置SQL Map,这里我们仅用到一个SQL Map文件,实际上它的个数是不受限制的。该配置文件还提供有其它几种选项,我们会在下一章详细讲解。
您已经看到了主配置文件,那再来看看SQL Map文件(清单2.6)。这个文件包含了我们要执行的SQL语句。
<sqlMap namespace="Test" xmlns="http://ibatis.apache.org/mapping" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<statements>
<select id="getAllUsers" parameterClass="string" resultClass="hashtable">
SELECT * FROM USER_ACCOUNT WHERE GROUPNAME = #groupName#
</select>
</statements>
</sqlMap>
在清单2.6中的XML代码中,我们接受一个字符串类型的值(parameterClass)传给GROUPNAME参数,然后将结果映射至Hashtable(resultClass)。
注意:不推荐使用Hashtable之类的对象作为领域对象(Domain Object),但该例子同时显示了iBATIS中映射的灵活性。我们不需要总是使用POCO(Plain Old CLR Object)来进行映射——也可以直接映射到Hashtable或基元类型(int, string等)。
信不信由你,你现在已经看到了使用iBATIS所必需的所有代码及配置文件。
2.6 未来: iBATIS将去向何处?
iBATIS在最近几个月得到了很大的推动。现在,团队得到了成长,产品已经迁移,我们也开始讨论支持新的平台。下面我们来详细地看一下。
2.6.1 Apache软件基金会(ASF)
最近iBATIS成为了ASF的一员。我们选择转移到Apache是因为我们相信他们的使命感,尊重他们的态度。Apache不仅仅是一些服务器和基础设施(infrastructure);它是一个系统,是开源软件真正的家。Apache专注于软件所处的社区而不是其背后的技术,没有了社区,软件也将不复存在。
iBATIS不再受单个实体(single entity)的控制,也不依赖于单个实体,这对iBATIS的用户来说意味着什么呢?没有人拥有iBATIS——它属于社区。Apache保护其中的软件,确保它们处于正确的轨道。Apache许可(license)不像GPL(General Public License)这样的许可可能会限制人们对开源软件的使用。Apache许可不是viral的,这意味着您可以在商业环境中自由地使用软件,而不用担心去顺从一些不合理的条件。
虽然Apache没有专注于基础设施(infrastructure),他们却拥有相当好的基础设施。当前iBATIS使用Subversion作源代码控制(SVN),Atlassian的JIRA进行问题跟踪,Atlassian的Confluence作协同Wiki文档,Apache的邮件列表服务器在开发团队、用户和社区间进行交流。
Apache可以保护iBATIS,只要有人愿意使用,它就会存在。
2.6.2 更为简单,小巧,减少依赖
不像其它一些框架,iBATIS不会致力于扩展至新的领域。iBATIS项目非常专注,对于每一个发行版本,我们只希望它能够更为简单、小巧,并保持与其它第三方类库的独立性。
我们相信iBATIS有很多创新的空间。iBATIS可以从许多新的技术和设计理念中汲取营养,使得配置更为简单,容易使用。例如,C#和Java都有内置的属性(attribute)功能,在未来的版本中,iBATIS可能会加以利用,减少配置所需的XML文件。
此外,对于开发工具而言,仍有很大的提升空间。iBATIS的设计可以将其与IDE这样的图形化工具良好地整合在一起。iBATIS的配置也有可能会通过数据库结构生成,实际上,当前已有这样的工具。在我们的网站您可以看到类似工具的示例:http://ibatis.apache.org.
2.6.3 更多的扩展(exension)和插件(plug-in)
当前iBATIS已经有了一些扩展。我们将在第12章详细讨论。您可能已经实现了自己的事务管理,数据源,缓存管理等等。但我们的目标是让iBATIS更具可扩展性。我们希望对JDBC架构几乎每一个层都有可插入(pluggable)的设计,这样就可以实现我们自己的ResultSet处理器和SQL执行引擎。从而可以帮助我们以合适的方式处理更为复杂或者遗留下来的系统。这也允许开发人员更好的利用某些数据库或应用程序服务器的专有特性。
2.6.4 更多的平台和语言
如您所注意到的,我们在1、2两章讨论了.NET和Java版本的iBATIS。在本书的剩余部分中,我们将集中讨论Java版本的API,其中的大部分内容同样适用于.NET平台。我们会在附录部分更详细地讨论.NET版本的使用。iBATIS已经有了Ruby版本的实现,但Ruby与其它语言有很大不同,因此iBATIS for Ruby与其它版本的实现也有很大差别。我们不会在本书中讨论Ruby版本的实现。
译注:作为.NET开发人员,我会尽量将书中的Java版本实现转化为C#版本。
除了Java和C#,iBATIS团队已经在讨论,准备为其实现其它语言的版本,包括PHP5和Python。如果在一个平台下,您的选择局限在低层次的数据库API和高层次的O/RM工具,我们相信,iBATIS会为其贡献很大的力量。iBATIS处于中间地带(middle ground),允许您的所有应用程序以一致的方式实现。
我们也在讨论起草一份规范,使iBATIS在不同平台间更容易迁移,以确保合理的一致性。当然,我们希望iBATIS能够充分利用每种语言和平台的特性,但我们也希望能够达到一定程度的相似性,这样它们可以统称为iBATIS,使用一种语言/平台的开发人员能够比较容易地理解另一种语言/平台下的iBATIS实现。
2.7 总结
在本章中,您了解了iBATIS作为一种独特的Data Mapper,使用SQL映射的方式将对象持久化至关系型数据库。iBATIS在Java和.NET平台下有着一致的实现,这对于应用程序中持久层的一致性有重要的意义。
您还了解了iBATIS的工作原理。一般地,iBATIS会运行编写良好的JDBC或ADO.NET代码,而这些如果由手工编写,则会难以维护。相比于JDBC或ADO.NET,iBATIS所需的代码大大减少,也更加简单。
我们讨论了iBATIS——尽管它的设计很简单——为何同时适用于小型程序和大型的企业级应用程序。iBATIS拥有诸多特性,满足企业级应用程序的持久化需求。诸如Row handler这样的特性允许对大量的数据进行高效地处理,每次一行记录,确保您不会耗尽系统的内存。
我们还讨论了iBATIS区别于竞争对手的一些特性,列出了适合使用iBATIS的场景。这些特性包括:
- 简单——iBATIS是当前公认的最简单的持久层框架。
- 生产力——简练的代码和简单的配置将等价的JDBC代码减少到了62%。
- 性能——架构的增强,比如Join映射提高了数据访问的速度。
- 分离关注点——iBATIS改善了设计,有利于将来的维护。
- 分工——iBATIS帮助把任务分解并允许团队充分利用拥有的资源。
- 可移植性——iBATIS可以实现为任何特性完整(full-featured)的语言。
在我们的“广告”之后,我们也承认,iBATIS并非银弹,因为任何框架都不是。我们讨论了不太适合使用iBATIS的情况。例如,如果您对应用程序和数据库拥有完全的控制权,那么完善的O/RM工具是最好的选择。另一方面,如果您的应用程序主要使用动态生成的SQL,那么原生的JDBC/ADO.NET是更好的选择。我们也曾提到,iBATIS主要为关系型数据库设计,如果您使用文本文件、XML、Excel样式表或其它的非关系型数据库技术,那么您最好使用其它的API。
最后,我们讨论了iBATIS的未来。我们的团队有很多很棒的设计目标,Apache软件基金会将确保有一个活跃的社区,在未来的几年内给予支持。下载本文相关代码。
下一篇:iBATIS基础:iBATIS的安装和配置