iBatis 2.x版本以及之前的版本ibatis一直属于Apache公司,3.0.x 之后转投到Google Code旗下,名字也由ibatis改为mybatis,两者最主要的区别就是mybatis一定程度上简化了编码的过程,开发者不需要去写dao的实现类,只需写一个dao的接口,然后再写一个xml配置文件,这样整个mybatis就配置好了。对于dao接口的使用直接在service里面调用就可以了,但是ibatis则不可以,必须要写dao的实现类,方法实现里面一般要加上return getSqlMapClientTemplate().queryForList()之类的模板调用语句。所以说从这个层面讲mybatis可以称之为是ibatis的升级版本。还有就是在xml的配置文件里面标签元素以及sql语句的写法有差异,但是差别不大,主要是为了减少开发者在切换框架所带来的学习成本;其次,MyBatis 充分吸收了其他 ORM 框架好的实践。
根据iBatis的习惯,我们通常把全局配置文件命名为sqlMapConfig.xml,文件名本身并没有要求,在MyBatis中,也经常会将该文件命名为Configuration.xml,在iBatis中经常出现的“sqlMap”在 MyBatis 中被逐渐淡化了,除了此处,还比如 iBatis 配置文件的根元素为 <sqlMapConfig>,指定映射文件的元素为 <sqlMap>,以及 SqlMapClient 等等,这个变化正说明,iBatis 仅是以 SQL 映射为核心的框架,而在 MyBatis 中多以 Mapper、Session、Configuration 等其他常用 ORM 框架中的名字代替。在全局配置文件中可以配置的信息主要包括如下几个方面:
- properties --- 用于提供一系列的键值对组成的属性信息,该属性信息可以用于整个配置文件中。
- settings --- 用于设置 MyBatis 的运行时方式,比如是否启用延迟加载等。
- typeAliases --- 为 Java 类型指定别名,可以在 XML 文件中用别名取代 Java 类的全限定名。
- typeHandlers --- 在 MyBatis 通过 PreparedStatement 为占位符设置值,或者从 ResultSet 取出值时,特定类型的类型处理器会被执行。
- objectFactory --- MyBatis 通过 ObjectFactory 来创建结果对象。可以通过继承 DefaultObjectFactory 来实现自己的 ObjectFactory 类。
- plugins --- 用于配置一系列拦截器,用于拦截映射 SQL 语句的执行。可以通过实现 Interceptor 接口来实现自己的拦截器。
- environments --- 用于配置数据源信息,包括连接池、事务属性等。
- mappers --- 程序中所有用到的 SQL 映射文件都在这里列出,这些映射 SQL 都被 MyBatis 管理。
上面提及的大多数元素都不是必需的,通常 MyBatis 会为没有显式设置的元素提供缺省值。下面就两者在配置上的差异性如下:
1. 简单的全局配置文件示例
<!--iBatis 和 MyBatis 的全局配置文件使用不同的 DTD 约束,在将应用由iBatis 升级至 MyBatis 时需要注意(两者的映射文件 DTD 约束也不相同)-->
<!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= … />
<property name="url" value= … />
<property name="username" value="root"/>
<property name="password" value="root"/>
</dataSource>
</environment>
</environments>
<!-- 列出映射文件 -->
<mappers>
<mapper resource="footmark/mybatis/demo/UserInfoMapper.xml"/>
</mappers>
</configuration>
有了这些信息,MyBatis 便能够和数据库建立连接,并应用给定的连接池信息和事务属性。MyBatis 封装了这些操作,最终暴露一个 SqlSessionFactory 实例供开发者使用,从名字可以看出来,这是一个创建 SqlSession 的工厂类,通过 SqlSession 实例,开发者能够直接进行业务逻辑的操作,而不需要重复编写 JDBC 相关的样板代码。根据全局配置文件生成 SqlSession 的代码如下:
Reader reader = Resources.getResourceAsReader("Configuration.xml");
SqlSessionFactory sqlSessionFactory =
new SqlSessionFactoryBuilder().build(reader);
SqlSession sqlSession = sqlSessionFactory.openSession();
可以把上面的三行代码看做是 MyBatis 创建 SqlSession 的样板代码。其中第一行代码在类路径上加载配置文件,Resources 是 MyBatis 提供的一个工具类,它用于简化资源文件的加载,它可以访问各种路径的文件,不过最常用的还是示例中这种基于类路径的表示方式。
2. 在映射文件中配置SQL语句
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<select id="selectUser" parameterType="int" resultType="mybatis.demo.UserInfo">
select * from UserInfo where userid =#{userid}
</select>
3. 使用 SqlSession 执行映射文件中配置的 SQL 语句
UserInfo userinfo = (UserInfo) sqlSession.selectOne("mybatis.demo.UserInfoMapper.getUser", 2);System.out.println(userinfo);
sqlSession.close();
需要注意的是,SqlSession 的使用必需遵守上面的格式,即在 finally 块中将其关闭。以保证资源得到释放,防止出现内存泄露!
以上就是一个简单而完整的 MyBatis 程序。其中涉及了全局配置文件,映射文件,构建 SqlSession 对象,执行数据访问操作等四个步骤。
4. 两者设置属性的方式
<setting name="props1" value="value1"/><setting name="props2" value="value2"/>……
5. 两者配置事务管理器和数据源的方式
<dataSource type="SIMPLE">
<property name="JDBC.Driver" value="${driver}"/><!-- 其他数据源信息省略 --></dataSource>
<environment id="demo"><transactionManager type="JDBC"/><dataSource type="POOLED">
<property name="JDBC.Driver" value="${driver}"/><!-- 其他数据源信息省略 -->
</dataSource>
</environment>
通过 <environments> 来进行数据源管理,主要是为了简化在多套数据源配置之间的切换,比如开发和发布使用不同的配置。
6. 指定映射文件的方式
<sqlMap resource=... />
<sqlMap resource=... />
<mapper resource=... /><mapper resource=... />
到目前为止,我们主要讨论了 XML 形式的全局配置,其实这也不是唯一选择,MyBatis 还提供了通过代码来进行配置的方式。
7. 在mybatis中使用代码进行配置
TransactionFactory txFactory = new JdbcTransactionFactory();
Environment env = new Environment("demo", txFactory, ds);
Configuration cfg = new Configuration(env);
cfg.addMapper(UserInfoMapper.class);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(cfg);
8. 将映射的 SQL 语句与接口中的方法绑定
public interface UserInfoMapper
{
@Select("select * from userinfo where userid = #{userid}")public UserInfo getUserInfo(int userid);
}
//UserInfo userinfo = (UserInfo) sqlSession.selectOne("mybatis.demo.UserInfoMapper.selectUser", 2);UserInfoMapper userinfoMapper =sqlSession.getMapper(UserInfoMapper.class);UserInfo userinfo = userinfoMapper.getUserInfo(1);System.out.println(userinfo);
sqlSession.close();
9. 调用存储过程方式的差异
{ ? = call pkgExample.getValues(p_id => ?) }
{ ? = call pkgExample.getValues(p_id => ?)}