返回

Mybatis中的SQL语句执行流程

后端

在Java开发中,需要与数据库交互的地方不胜枚举,Mybatis作为ORM框架的代表之一,一直发挥着重要作用。Mybatis的强大之处在于它可以将SQL语句和Java对象映射起来,简化了开发人员的编码工作。那么,当我们在Java中执行一条Mybatis的SQL语句时,背后都发生了什么呢?本文将带你深入解析Mybatis中的SQL执行流程。

当我们在Java中执行一条Mybatis的SQL语句时,会发生以下一系列过程:

  1. Mybatis加载映射文件和配置文件

    首先,Mybatis会加载映射文件和配置文件。映射文件是Java对象和数据库表之间映射关系的XML文件,而配置文件则是用来配置Mybatis的一些全局参数。

  2. Mybatis创建SqlSessionFactory

    根据映射文件和配置文件,Mybatis会创建一个SqlSessionFactory对象。SqlSessionFactory是Mybatis的核心对象,它负责创建SqlSession对象。

  3. Mybatis创建SqlSession对象

    当我们需要执行一条SQL语句时,Mybatis会创建一个SqlSession对象。SqlSession对象代表着一个数据库会话,它可以执行SQL语句并返回结果。

  4. SqlSession对象执行SQL语句

    SqlSession对象执行SQL语句时,会先将SQL语句发送给数据库服务器。然后,数据库服务器执行SQL语句并返回结果。最后,SqlSession对象将结果返回给Java程序。

  5. Mybatis将结果映射成Java对象

    SqlSession对象返回的结果是数据库记录,而我们需要的是Java对象。因此,Mybatis会将结果映射成Java对象。这个过程是通过反射来实现的。

  6. Mybatis关闭SqlSession对象

    当我们不再需要SqlSession对象时,需要将其关闭。这可以释放SqlSession对象占用的资源。

以上是Mybatis中SQL语句执行的大致流程。现在,让我们深入分析一下SQL执行入口的源码。

SQL执行入口源码分析

SQL执行入口的源码位于org.apache.ibatis.executor.SimpleExecutor类中。该类是Mybatis中负责执行SQL语句的类。

public class SimpleExecutor extends BaseExecutor {

    public Object query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) {
        Statement stmt = null;
        try {
            flushStatements();
            stmt = prepareStatement(ms.getStatement(), parameter, rowBounds);
            return queryFromStatement(stmt, resultHandler);
        } finally {
            closeStatement(stmt);
        }
    }

    private Statement prepareStatement(String sql, Object parameter, RowBounds rowBounds) {
        Connection connection = getConnection(ms.getConnection());
        Statement statement = null;
        try {
            statement = connection.prepareStatement(sql);
            setParameters(statement, parameter);
            if (rowBounds != null) {
                applyRowBounds(statement, rowBounds);
            }
        } catch (SQLException e) {
            closeStatement(statement);
            throw ExceptionFactory.wrapException("Error preparing statement. Cause: " + e, e);
        }
        return statement;
    }

    private void setParameters(Statement statement, Object parameter) {
        ParameterHandler parameterHandler = parameterHandlerFactory.createParameterHandler(statement, parameter);
        parameterHandler.setParameters();
    }

    private Object queryFromStatement(Statement statement, ResultHandler resultHandler) {
        try {
            return resultSetHandlerFactory.handleResultSets(statement, resultHandler);
        } finally {
            closeStatement(statement);
        }
    }
}

从上面的代码可以看出,SQL执行入口的方法是query()方法。该方法首先调用flushStatements()方法来刷新已经执行过的SQL语句。然后,调用prepareStatement()方法来准备要执行的SQL语句。prepareStatement()方法首先获取一个数据库连接,然后调用prepareStatement()方法来创建Statement对象。最后,调用setParameters()方法来设置SQL语句的参数。

接下来,query()方法调用queryFromStatement()方法来执行SQL语句。queryFromStatement()方法首先调用resultSetHandlerFactory.handleResultSets()方法来处理结果集。然后,调用closeStatement()方法来关闭Statement对象。

这就是Mybatis中SQL语句执行入口的源码分析。通过分析源码,我们可以更好地理解Mybatis的底层实现。