MyBatis 从selectOne到JDBC的源码解析

本文从MyBatis的selectOne方法入手,深入解析MyBatis查询执行流程,涉及SqlSession接口、Executor执行器和StatementHandler处理器。通过分析,了解MyBatis如何从顶层API到JDBC执行SQL,帮助理解MyBatis框架的工作原理。
摘要由CSDN通过智能技术生成

在我的博客阅读本文会有更好的阅读体验哦!博客: www.lxiaocode.com

最近看些 MyBatis 的源码,虽说不是很深入但是也对 MyBatis 的查询的执行流程有了整体的了解。本文将会从 selectOne 方法开始一直追溯到 JDBC 的访问数据库,来看一看 MyBatis 到底做了什么,简单的对 MyBatis 的查询接口有个简单的整体的了解。

文本会以 MyBatis 源码为主,不考虑 Spring 的封装。

第零步:MyBatis 查询示例

MyBtais 3 官网:https://mybatis.org/mybatis-3/zh/getting-started.html

在开始阅读源码之前,我们先来复习一下使用 MyBatis 调用查询接口进行查询的方法,下面是从 MyBatis 3 的官方中获取的查询示例:

// 使用 XML 构建 SqlSessionFactory
String resource = "org/mybatis/example/mybatis-config.xml";
InputStream inputStream = Resources.getResourceAsStream(resource);
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
// 获取 SqlSession 调用 selectOne 查询接口
try (SqlSession session = sqlSessionFactory.openSession()) {
   
  Blog blog = (Blog) session.selectOne("org.mybatis.example.BlogMapper.selectBlog", 101);
}

从上面的示例中可以看出,MyBatis 对我们开放的顶层 API 接口是由 SqlSession 接口所提供的。我们接下来就由 SqlSession.selectOne 为起点开始阅读 MyBatis 的查询接口源码。

第一步:SqlSession 顶层接口

1.1 SqlSession 接口

SqlSession 作为 MyBatis 的顶层接口,为我们提供了许多功能。通过这个接口,我们可以执行 SQL 命令、获取映射器和管理事务。本文会聚焦在 selectOne 方法上进行解析。

public interface SqlSession extends Closeable {
   
  <T> T selectOne(String statement);

  <T> T selectOne(String statement, Object parameter);
    
	// 此处省略其他方法...
}
1.2 DefaultSqlSession 实现类

从类名我们就知道,这是 SqlSeesion 接口的默认实现类。所以说 SelectOne 的默认实现也在这里。

// 这是 SqlSession 的默认实现
// 注意,这个类不是线程安全的
public class DefaultSqlSession implements SqlSession {
   

    // 配置文件
  private final Configuration configuration;
    // 执行器
  private final Executor executor;

  private final boolean autoCommit;
  private boolean dirty;
  private List<Cursor<?>> cursorList;

    // 两个构造器
  public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
   
    this.configuration = configuration;
    this.executor = executor;
    this.dirty = false;
    this.autoCommit = autoCommit;
  }

  public DefaultSqlSession(Configuration configuration, Executor executor) {
   
    this(configuration, executor, false);
  }

    // 无参查询接口
  @Override
  public <T> T selectOne(String statement) {
   
    return this.selectOne(statement, null);
  }

    // 1. 我们根据示例中调用的查询接口,最后会进入到这个实现方法中来。
    // 	  这个方法非常简单,会直接调用 selectList 方法进行查询
    //    然后检查返回是否为一条结果,如果存在多条结果则会抛出异常
  @Override
  public <T> T selectOne(String statement, Object parameter) {
   
    List<T> list = this.selectList(statement, parameter);
    if (list.size() == 1) {
   
      return list.get(0);
    } else if (list.size() > 1) {
   
      throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size(</
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值