栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

mybaits执行流程流程(总)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

mybaits执行流程流程(总)

一mybaits执行流程流程(总)

二.mybatis的几大“组件”

我这里说的“组件”,可以理解为Mybatis执行过程中的很重要的几个模块。

2.1 SqlSessionFactoryBuilder

从名称长可以看出来使用的建造者设计模式(Builder),用于构建SqlSessionFactory对象

1.解析mybatis的xml配置文件,然后创建Configuration对象(对应标签);

2.根据创建的Configuration对象,创建SqlSessionFactory(默认使用DefaultSqlSessionFactory);

2.2 SqlSessionFactory

从名称上可以看出使用的工厂模式(Factory),用于创建并初始化SqlSession对象(数据库会话)

1.调用openSession方法,创建SqlSession对象,可以将SqlSession理解为数据库连接(会话);

2.openSession方法有多个重载,可以创建SqlSession关闭自动提交、指定ExecutorType、指定数据库事务隔离级别…

package org.apache.ibatis.session;
import java.sql.Connection;
 
public interface SqlSessionFactory {
    
    SqlSession openSession();
 
    
    SqlSession openSession(boolean autoCommit);
 
    
    SqlSession openSession(Connection connection);
 
    
    SqlSession openSession(TransactionIsolationLevel level);
 
    
    SqlSession openSession(ExecutorType execType);
 
    SqlSession openSession(ExecutorType execType, boolean autoCommit);
    SqlSession openSession(ExecutorType execType, TransactionIsolationLevel level);
    SqlSession openSession(ExecutorType execType, Connection connection);
 
    
    Configuration getConfiguration();
}
2.3 SqlSession

session,译为“会话、会议”,数据的有效时间范围是在会话期间(会议期间),会话(会议)结束后,数据就清除了。

​ 也可以将SqlSession理解为一个数据库连接(但也不完全正确,因为创建SqlSession之后,如果不执行sql,那么这个连接是无意义的,所以数据库连接在执行sql的时候才建立的)。

SqlSession是一个接口,定义了很多操作数据库的方法声明:

public interface SqlSession extends Closeable {
    
    Connection getConnection();
 
    
     T selectOne(String statement);
     List selectList(String statement);
    int update(String statement, Object parameter);
    int delete(String statement, Object parameter);
 
    
    void rollback();
    void commit();
 
    
    void clearCache();
 
    // 此处省略了很多方法
}

SqlSession只是定义了执行sql的一些方法,而具体的实现由子类来完成,比如SqlSession有一个接口实现类DefaultSqlSession。

MyBatis中通过Executor来执行sql的,在创建SqlSession的时候(openSession),同时会创建一个Executor对象,如下:

@Override
public SqlSession openSession() {
    return openSessionFromDataSource(configuration.getDefaultExecutorType(), null, false);
}
 
private SqlSession openSessionFromDataSource(ExecutorType execType, TransactionIsolationLevel level, boolean autoCommit) {
    Transaction tx = null;
    try {
        final Environment environment = configuration.getEnvironment();
        final TransactionFactory transactionFactory = getTransactionFactoryFromEnvironment(environment);
        tx = transactionFactory.newTransaction(environment.getDataSource(), level, autoCommit);
 
        // 利用传入的参数,创建executor对象
        final Executor executor = configuration.newExecutor(tx, execType);
        return new DefaultSqlSession(configuration, executor, autoCommit);
    } catch (Exception e) {
        closeTransaction(tx); // may have fetched a connection so lets call close()
        throw ExceptionFactory.wrapException("Error opening session.  Cause: " + e, e);
    } finally {
        ErrorContext.instance().reset();
    }
}
2.4 Executor

Executor(人称“执行器”)是一个接口,定义了对JDBC的封装;

//列出了5个Executor(baseExecutor是抽象类),其实Executor只有三种:
public enum ExecutorType {
    SIMPLE, // 简单
    REUSE,  // 复用
    BATCH;  // 批量
}

CacheExecutor其实是一个Executor代理类,包含一个delegate,需要创建时手动传入(要入simple、reuse、batch三者之一);

ClosedExecutor,所有接口都会抛出异常,表示一个已经关闭的Executor;

创建SqlSession时,默认使用的是SimpleExecutor;

​ 上面说了,Executor是对JDBC的封装。当我们使用JDBC来执行sql时,一般会先预处理sql,也就是conn.prepareStatement(sql),获取返回的PreparedStatement对象(实现了Statement接口),再调用statement的executeXxx()来执行sql。

​ 也就是说,Executor在执行sql的时候也是需要创建Statement对象的,下面以SimpleExecutor为例:

2.5 StatementHandler

在JDBC中,是调用Statement.executeXxx()来执行sql;

在MyBatis,也是调用Statement.executeXxx()来执行sql,此时就不得不提StatementHandler,可以将其理解为一个工人,他的工作包括

1.对sql进行预处理;

2.调用statement.executeXxx()执行sql;

3.将数据库返回的结果集进行对象转换(ORM);

public interface StatementHandler {
    
    Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException;
 
    
    void parameterize(Statement statement) throws SQLException;
 
    
    void batch(Statement statement) throws SQLException;
 
    
    int update(Statement statement) throws SQLException;
 
    
     List query(Statement statement, ResultHandler resultHandler) throws SQLException;
     
     Cursor queryCursor(Statement statement) throws SQLException;
    BoundSql getBoundSql();
    ParameterHandler getParameterHandler();
}

baseStatementHandler

2.6 ParameterHandler

ParameterHandler的功能就是sql预处理后,进行设置参数:

public interface ParameterHandler {
 
    Object getParameterObject();
 
    void setParameters(PreparedStatement ps) throws SQLException;
}

ParamterHandler有一个DefaultParameterHandler,下面是其重写setParameters的代码:

2.7 ResultSetHandler

当执行statement.execute()后,就可以通过statement.getResultSet()来获取结果集,获取到结果集之后,MyBatis会使用ResultSetHandler来将结果集的数据转换为Java对象(ORM映射)

public interface ResultSetHandler {
    
     List handleResultSets(Statement stmt) throws SQLException;
     
     Cursor handleCursorResultSets(Statement stmt) throws SQLException;
    void handleOutputParameters(CallableStatement cs) throws SQLException;
}

ResultSetHandler有一个实现类,DefaultResultHandler,其重写handlerResultSets方法,如下:

2.8 TypeHandler

TypeHandler主要用在两个地方:

1.参数绑定,发生在ParameterHandler.setParamenters()中。

MyBatis中,可以使用来定义结果的映射关系,包括每一个字段的类型,比如下面这样:


    
    

TypeHandler,可以对某个字段按照xml中配置的类型进行设置值,比如设置sql的uid参数时,类型为INTEGER(jdbcType)。

2.获取结果集中的字段值,发生在ResultSetHandler处理结果集的过程中。

TypeHandler的定义如下:

public interface TypeHandler {
 
    
    void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
 
    
    T getResult(ResultSet rs, String columnName) throws SQLException;
 
    
    T getResult(ResultSet rs, int columnIndex) throws SQLException;
 
    T getResult(CallableStatement cs, int columnIndex) throws SQLException;
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/643602.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号