对于从事 Java EE 的开发人员来说,iBatis 是一个再熟悉不过的持久层框架了,在 Hibernate、JPA 这样的一站式对象 / 关系映射(O/R Mapping)解决方案盛行之前,iBaits 基本是持久层框架的不二选择。即使在持久层框架层出不穷的今天,iBatis 凭借着易学易用、轻巧灵活等特点,也仍然拥有一席之地。尤其对于擅长 SQL 的开发人员来说,iBatis 对 SQL 和存储过程的直接支持能够让他们在获得 iBatis 封装优势的同时而不丧失 SQL 调优的手段,这是 Hibernate/JPA 所无法比拟的。具体而言,使用 iBatis 框架的主要优势主要体现在如下几个方面:
首先,iBatis 封装了绝大多数的 JDBC 样板代码,使得开发者只需关注 SQL 本身,而不需要花费精力去处理例如注册驱动,创建 Connection,以及确保关闭 Connection 这样繁杂的代码。
其次,iBatis 可以算是在所有主流的持久层框架中学习成本最低,最容易上手和掌握的框架。虽说其他持久层框架也号称门槛低,容易上手,但是等到你真正使用时会发现,要想掌握并用好它是一件非常困难的事。在工作中我需要经常参与面试,我曾听到过很多位应聘者描述,他们所在的项目在技术选型时选择 Hibernate,后来发现难以驾驭,不得不将代码用 JDBC 或者 iBatis 改写。
3.0 版本的发布 ,iBatis 主页上的一则 “Apache iBATIS has been retired” 的声明在社区引起了一阵不小的波澜。在 Apache 寄居六年之后,iBatis 将代码托管到 Google Code。在声明中给出的主要理由是,和 Apache 相比,Google Code 更有利于开发者的协同工作,也更能适应快速发布。于此同时,iBatis 更名为 MyBatis。
从 iBatis 到 MyBatis,不只是名称上的变化,MyBatis 提供了更为强大的功能,同时并没有损失其易用性,相反,在很多地方都借助于 JDK 的泛型和注解特性进行了简化。iBatis 确实该退休了,因为一个更为出色的继任者经过 10 个 Beta 版本的蜕变已然出现在我们的面前。
针对常用的持久层框架而言(Hibernate、JPA、iBatis 等),通常需要配置两类文件:一类用于指定数据源、事务属性以及其他一些参数配置信息(通常是一个独立的文件,可以称之为全局配置文件);另一类则用于指定数据库表和程序之间的映射信息(可能不止一个文件,我们称之为映射文件)。MyBatis 也不例外,虽然其中的一部分可以通过注解的形式进行,但是这两部分内容本身仍是必不可少的。
根据 iBatis 的习惯,我们通常把全局配置文件命名为 sqlMapConfig.xml,文件名本身并没有要求,在 MyBatis 中,也经常会将该文件命名为 Configuration.xml (读完全文后读者也许会发现,在 iBatis 中经常出现的 “sqlMap” 在 MyBatis 中被逐渐淡化了,除了此处,还比如 iBatis 配置文件的根元素为 <sqlMapConfig>,指定映射文件的元素为 <sqlMap>,以及 SqlMapClient 等等,这个变化正说明,iBatis 仅是以 SQL 映射为核心的框架,而在 MyBatis 中多以 Mapper、Session、Configuration 等其他常用 ORM 框架中的名字代替,体现的无非是两个方面:首先是为了减少开发者在切换框架所带来的学习成本;其次,MyBatis 充分吸收了其他 ORM 框架好的实践,MyBatis 现在已不仅仅是一个 SQL 映射框架了)。在全局配置文件中可以配置的信息主要包括如下几个方面:
全局配置文件Configuration.xml:
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE configuration PUBLIC "-//mybatis.org//DTD Config 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-config.dtd">
<configuration>
<environments default="demo">
<environment id="demo" >
<transactionManager type="JDBC" />
<dataSource type="POOLED">
<property name="driver" value="oracle.jdbc.OracleDriver" />
<property name="url" value="jdbc:oracle:thin:@192.168.0.105:1521:orcl" />
<property name="username" value="scott" />
<property name="password" value="accp" />
</dataSource>
</environment>
</environments>
<mappers>
<mapper resource="org/han/entity/DeptMapper.xml" />
</mappers>
</configuration>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="org.han.entity.DeptMapper"><!-- 可以创建该映射器接口,并提供该方法 -->
<select id="getDeptById" parameterType="java.lang.Integer" resultType="org.han.entity.Dept">
select * from scott.Dept where deptno = #{id}
</select>
</mapper>
加载配置信息并创建SqlSession:
Reader reader = Resources.getResourceAsReader("Configuration.xml");
SqlSessionFactory SessionFactory = new SqlSessionFactoryBuilder()
.build(reader);
SqlSession session = SessionFactory.openSession();
try {
Dept d = (Dept) session.selectOne(
"org.han.entity.DeptMapper.getDeptById", 10);
} catch (Exception e) {
// TODO: handle exception
session.rollback();
e.printStackTrace();
} finally {
session.close();
}