MyBatis简介和原理介绍

Mybatis的应用是围绕着一个SqlSessionFactory实例(即SqlSession工厂,从中可以获取到SqlSession对象,所有的数据库操作都是通过SqlSession类进行的)展开的。SqlSessionFactoryBuilder根据XML映射文件创建SqlSessionFactory。下面是一段创建SqlSession的代码:

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 知识!

尺有所短;寸有所长。物有所不足;智有所不明。——屈原《卜居》
0 不喜欢
说说我的看法 -
全部评论(
没有评论
关于
本网站属于个人的非赢利性网站,转载的文章遵循原作者的版权声明,如果原文没有版权声明,请来信告知:hxstrive@outlook.com
公众号