mybatis(四):执行流程

时间:2021-03-10 17:07:06

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封装对象。