mybatis:框架结构 & 执行流程

Posted angelica-duhurica

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mybatis:框架结构 & 执行流程相关的知识,希望对你有一定的参考价值。

技术图片

实现流程

// 读取mybatis-config.xml文件
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");

// 初始化mybatis,创建SqlSessionFactory类的实例
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);

// 创建Session实例
SqlSession session = sqlSessionFactory.openSession();

// <方法一>获得xml映射文件中定义的操作语句
User user = session.selectOne("mapper.UserMapper.selectUserById", 1);

// <方法二>获得mapper接口的代理对象,直接调用接口的方法
UserMapper um = session.getMapper(UserMapper.class);
User user2 = um.selectUserById(1);

// 提交事务
session.commit();

// 关闭Session
session.close();

xml如下:

<?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="mapper.UserMapper">
    <!-- 自定义返回结果集 -->
    <resultMap id="userMap" type="User">
        <id property="id" column="id" javaType="java.lang.Integer"/>
        <result property="username" column="username" javaType="java.lang.String"/>
        <result property="password" column="password" javaType="java.lang.String"/>
        <result property="account" column="account" javaType="java.lang.Integer"/>
    </resultMap>

    <select id="selectUserById" parameterType="int" resultMap="userMap">
        select * from `user` where id = #id
    </select>
</mapper>

mapper接口如下:

public interface UserMapper 
    User selectUserById(int id) throws Exception;

源码查看

以查询为例,在SqlSession<接口>的默认实现DefaultSqlSession中:

private final Configuration configuration;
private final Executor executor;

@Override
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) 
    try 
        MappedStatement ms = configuration.getMappedStatement(statement);
        return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
     catch (Exception e) 
        hrow ExceptionFactory.wrapException("Error querying database.  Cause: " + e, e);
     finally 
        rrorContext.instance().reset();
    

注意到两个全局变量。

其中Configuration是一个类,其中有关的具体实现如下:

protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection")
      .conflictMessageProducer((savedValue, targetValue) ->
          ". please check " + savedValue.getResource() + " and " + targetValue.getResource());

public MappedStatement getMappedStatement(String id, boolean validateIncompleteStatements) 
    if (validateIncompleteStatements) 
        buildAllStatements();
    
    // 这里的id就是上述代码块中的statement,也就是具体实现中的“mapper.UserMapper.selectUserById”
    return mappedStatements.get(id);

而Executor是一个接口,正如在图中所述,它有两个实现。我们看默认的缓存执行器。

@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException 
    BoundSql boundSql = ms.getBoundSql(parameterObject);
    CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
    return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);

总结

工厂加载核心配置文件,同时创建会话;会话里面有执行者;执行sql语句,在执行sql语句的过程中通过MappedStatement封装对象。

以上是关于mybatis:框架结构 & 执行流程的主要内容,如果未能解决你的问题,请参考以下文章

深入理解java:4.3.1. 框架编程之MyBatis---SQL语句执行的完整流程

MyBatis架构与流程

mybatis执行流程源码分析

MyBatis框架原理3:缓存

Mybatis框架

Java单体应用 - 常用框架 - 08.MyBatis