MyBatis的前身就是iBatis,iBatis本是apache的一个开源项目,2010年这个项目由apahce sofeware foundation 迁移到了google code,并且改名为MyBatis。
iBATIS 一词来源于“internet”和“abatis”的组合,是一个基于Java的持久层框架。iBATIS提供的持久层框架包括SQL Maps和Data Access Objects(DAO),同时还提供一个利用这个框架开发的 JPetStore实例。(来源于百度)
MyBatis主要完成两件事:
(1)根据JDBC规范建立与数据库的连接;
(2)通过Annotaion/XML + JAVA反射技术,实现Java对象与关系数据库之间相互转化。
Mybatis的应用是围绕着一个SqlSessionFactory实例(即SqlSession工厂,从中可以获取到SqlSession对象,所有的数据库操作都是通过SqlSession类进行的)展开的。SqlSessionFactoryBuilder根据XML映射文件创建SqlSessionFactory。下面是一段创建SqlSession的代码:
// 1、加载配置文件 String cfgName = "mybatis-cfg.xml"; InputStream input = Resources.getResourceAsStream(cfgName); // 2、根据配置文件创建SqlSessionFactory对象 SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder(); SqlSessionFactory sqlSessionFactory = factoryBuilder.build(input); // 3、得到SqlSession对象 SqlSession sqlSession = sqlSessionFactory.openSession();
从上面的代码可以看出,SqlSessionFactory是从SqlSessionFactoryBuilder中构建出来的,下面是SqlSessionFactoryBuilder的一些源码片段,如下:
/**
* 根据配置信息创建默认的SqlSessionFactory对象
*/
public SqlSessionFactory build(Configuration config) {
// DefaultSqlSessionFactory是SqlSessionFactory的默认实现方式
// org.apache.ibatis.session.defaults.DefaultSqlSessionFactory
return new DefaultSqlSessionFactory(config);
}
/**
* 根据资源输入流创建一个SqlSessionFactory
*/
public SqlSessionFactory build(InputStream inputStream,
String environment, Properties properties) {
try {
// MyBatis配置XML解析器
XMLConfigBuilder parser = new XMLConfigBuilder(inputStream, environment, properties);
// 从parser中获取一个Configuration对象
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
inputStream.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
/**
* 用输入的字节流来创建一个SqlSessionFactory对象
*/
public SqlSessionFactory build(Reader reader,
String environment, Properties properties) {
try {
// org.apache.ibatis.builder.xml.XMLConfigBuilder
XMLConfigBuilder parser = new XMLConfigBuilder(reader, environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}通过上面的例子看到,SqlSession的实例是从SqlSessionFactory类中调用openSession()方法获得的。SqlSession包含了执行sql所需要的所有方法,我们可以通过SqlSession实例直接运行映射的sql语句,如下:
// 1、加载配置文件
String cfgName = "mybatis/mybatis-cfg.xml";
InputStream input = Resources.getResourceAsStream(cfgName);
// 2、根据配置文件创建SqlSessionFactory对象
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = factoryBuilder.build(input);
// 3、得到SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
// 执行在mapper文件中定义的selectBlog SQL语句,可以传递一个参数。
Blog blog = sqlSession.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
} finally {
// 关闭sqlSession,释放数据库资源
sqlSession.close();
}上面的方法是基于Mybatis的旧版本,在最新的版本中有更清晰的方法,通过一个java接口作为参数返回一个给定的sql映射(即对象的方式进行调用)。
// 1、加载配置文件
String cfgName = "mybatis/mybatis-cfg.xml";
InputStream input = Resources.getResourceAsStream(cfgName);
// 2、根据配置文件创建SqlSessionFactory对象
SqlSessionFactoryBuilder factoryBuilder = new SqlSessionFactoryBuilder();
SqlSessionFactory sqlSessionFactory = factoryBuilder.build(input);
// 3、得到SqlSession对象
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
// 存在一个BlogMapper配置文件或者通过注解进行配置SQL语句
BlogMapper mapper = sqlSession.getMapper(BlogMapper.class);
// 通过对象的方式调用
Blog blog = mapper.selectBlog(101);
} finally {
// 关闭sqlSession,释放数据库资源
session.close();
}看到这里,您可能会对什么才是SqlSession和Mapper类真正要执行的SQL语句非常好奇。
下面我们看一下例子(Mapper配置文件):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
"https://mybatis.org/dtd/mybatis-3-mapper.dtd">
<!-- namespace指定本mapper文件中的SQL语句所属的命名空间 -->
<mapper namespace="org.mybatis.example.BlogMapper">
<!-- 定义一个ID=selectBlog的查询语句,接收一个名为id的参数 -->
<select id="selectBlog" parameterType="int" resultType="Blog">
select * from Blog where id=#{id}
</select>
</mapper>这个例子非常简单,是轻量级的。您可以定义众多类似这样的sql语句。这个文件在命名空间"org.mybatis.example.BlogMapper"中,定义了一个叫做"selectBlog"的sql语句。这样就可以使用一个绝对唯一路径“org.mybatis.example.BlogMapper.selectBlog”定位到这个sql语句上。如下所示:
Blog blog = (Blog)session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);注意:
这是一个绝对唯一的Java类调用方法类似的。这个名字可以直接映射到命名空间的映射类,以及具有相匹配的名称、参数和返回类型映射select语句的方法。这使得您可以很简单地调用映射接口的方法,这里是例子:
BlogMapper mapper = session.getMapper(BlogMapper.class); Blog blog = mapper.selectBlog(101);
如您所见,第二种方法更简洁,不需要对返回值进行强制转换。到目前为止,我们已经了解Mybatis如何将xml映射文件与Java类映射去执行sql语句的,具体xml映射文件的含义请查询mybatis官方网站的资料,再此不在介绍。
点击学习 MyBatis 教程,了解更多的 MyBatis 知识!