IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> mybatis源码分析 各大组件简介 -> 正文阅读

[Java知识库]mybatis源码分析 各大组件简介

目录

主体配置

Configuration

Environment

TypeAliasRegistry

InterceptorChain

Interceptor

TypeHandlerRegistry

TypeHandler

缓存配置

Cache

PerpetualCache?

LruCache

BlockingCache

CacheKey

TransactionalCacheManager

TransactionalCache

数据源配置

DataSourceFactory

UnpooledDataSourceFactory

UnpooledDataSource

PooledDataSourceFactory

PooledDataSource

PoolState

PooledConnection?

mapper配置

ResultMap

ResultMapping

MappedStatement

KeyGenerator

SelectKeyGenerator

SqlSource

SqlSourceBuilder

DynamicSqlSource

RawSqlSource

StaticSqlSource

MixedSqlNode

StaticTextSqlNode

TextSqlNode

IfSqlNode

TrimSqlNode?

WhereSqlNode

SqlSession相关及四大对象

SqlSessionFactory

DefaultSqlSessionFactory

SqlSession

DefaultSqlSession

Executor

BaseExecutor

SimpleExecutor

BatchExecutor

ReuseExecutor

CachingExecutor

StatementHandler

BaseStatementHandler

SimpleStatementHandler

PreparedStatementHandler

CallableStatementHandler

RoutingStatementHandler

ParameterHandler

DefaultParameterHandler

ResultSetHandler

DefaultResultSetHandler

sql执行的其他相关

MapperRegistry

MapperProxyFactory

MapperMethod

SqlCommand?

MethodSignature?

BoundSql

DynamicContext

ParameterMapping

执行sql流程小结


主体配置

Configuration

有各种配置项,而且有对应的默认值。

有各种解析完后的MappedStatement,Cache,ResultMap,ParameterMap,KeyGenerator等。

有一个Environment

构造方法中注册了很多别名。

  //环境
  protected Environment environment;

  //---------以下都是<settings>节点-------
  protected boolean safeRowBoundsEnabled = false;
  protected boolean safeResultHandlerEnabled = true;
  protected boolean mapUnderscoreToCamelCase = false;
  protected boolean aggressiveLazyLoading = true;
  protected boolean multipleResultSetsEnabled = true;
  protected boolean useGeneratedKeys = false;
  protected boolean useColumnLabel = true;
  //默认启用缓存
  protected boolean cacheEnabled = true;
  protected boolean callSettersOnNulls = false;

  protected String logPrefix;
  protected Class <? extends Log> logImpl;
  protected LocalCacheScope localCacheScope = LocalCacheScope.SESSION;
  protected JdbcType jdbcTypeForNull = JdbcType.OTHER;
  protected Set<String> lazyLoadTriggerMethods = new HashSet<String>(Arrays.asList(new String[] { "equals", "clone", "hashCode", "toString" }));
  protected Integer defaultStatementTimeout;
  //默认为简单执行器
  protected ExecutorType defaultExecutorType = ExecutorType.SIMPLE;
  protected AutoMappingBehavior autoMappingBehavior = AutoMappingBehavior.PARTIAL;
  //---------以上都是<settings>节点-------

  protected Properties variables = new Properties();
  //对象工厂和对象包装器工厂
  protected ObjectFactory objectFactory = new DefaultObjectFactory();
  protected ObjectWrapperFactory objectWrapperFactory = new DefaultObjectWrapperFactory();
  //映射注册机
  protected MapperRegistry mapperRegistry = new MapperRegistry(this);

  //默认禁用延迟加载
  protected boolean lazyLoadingEnabled = false;
  protected ProxyFactory proxyFactory = new JavassistProxyFactory(); // #224 Using internal Javassist instead of OGNL

  protected String databaseId;
  /**
   * Configuration factory class.
   * Used to create Configuration for loading deserialized unread properties.
   *
   * @see <a href='https://code.google.com/p/mybatis/issues/detail?id=300'>Issue 300</a> (google code)
   */
  protected Class<?> configurationFactory;

  protected final InterceptorChain interceptorChain = new InterceptorChain();
  //类型处理器注册机
  protected final TypeHandlerRegistry typeHandlerRegistry = new TypeHandlerRegistry();
  //类型别名注册机
  protected final TypeAliasRegistry typeAliasRegistry = new TypeAliasRegistry();
  protected final LanguageDriverRegistry languageRegistry = new LanguageDriverRegistry();

  //映射的语句,存在Map里
  protected final Map<String, MappedStatement> mappedStatements = new StrictMap<MappedStatement>("Mapped Statements collection");
  //缓存,存在Map里
  protected final Map<String, Cache> caches = new StrictMap<Cache>("Caches collection");
  //结果映射,存在Map里
  protected final Map<String, ResultMap> resultMaps = new StrictMap<ResultMap>("Result Maps collection");
  protected final Map<String, ParameterMap> parameterMaps = new StrictMap<ParameterMap>("Parameter Maps collection");
  protected final Map<String, KeyGenerator> keyGenerators = new StrictMap<KeyGenerator>("Key Generators collection");

  protected final Set<String> loadedResources = new HashSet<String>();
  protected final Map<String, XNode> sqlFragments = new StrictMap<XNode>("XML fragments parsed from previous mappers");

  //不完整的SQL语句
  protected final Collection<XMLStatementBuilder> incompleteStatements = new LinkedList<XMLStatementBuilder>();
  protected final Collection<CacheRefResolver> incompleteCacheRefs = new LinkedList<CacheRefResolver>();
  protected final Collection<ResultMapResolver> incompleteResultMaps = new LinkedList<ResultMapResolver>();
  protected final Collection<MethodResolver> incompleteMethods = new LinkedList<MethodResolver>();

  /*
   * A map holds cache-ref relationship. The key is the namespace that
   * references a cache bound to another namespace and the value is the
   * namespace which the actual cache is bound to.
   */
  protected final Map<String, String> cacheRefMap = new HashMap<String, String>();

Environment

环境? 决定加载哪种环境(开发环境/生产环境)

内部有一个Builder用来构建

  //环境id
  private final String id;
  //事务工厂
  private final TransactionFactory transactionFactory;
  //数据源
  private final DataSource dataSource;
<environments default="development">
    <environment id="development">
        <transactionManager type="JDBC"/>
        <dataSource type="POOLED">
            <property name="driver" value="${jdbc.driver}"/>
            <property name="url" value="${jdbc.url}"/>
            <property name="username" value="${jdbc.username}"/>
            <property name="password" value="${jdbc.password}"/>
        </dataSource>
    </environment>
</environments>

TypeAliasRegistry

类型别名注册机,里面有Map<String, Class<?>>类型的TYPE_ALIASES

同时注册了很多别名

InterceptorChain

拦截器链,内部就是一个拦截器的List,List<Interceptor>类型的interceptors

Interceptor

拦截器接口

  //拦截
  Object intercept(Invocation invocation) throws Throwable;

  //插入
  Object plugin(Object target);

  //设置属性
  void setProperties(Properties properties);

TypeHandlerRegistry

类型处理器注册机

自动注册了很多javatype和jdbctype的处理器

//枚举型map
  private final Map<JdbcType, TypeHandler<?>> JDBC_TYPE_HANDLER_MAP = new EnumMap<JdbcType, TypeHandler<?>>(JdbcType.class);
  private final Map<Type, Map<JdbcType, TypeHandler<?>>> TYPE_HANDLER_MAP = new HashMap<Type, Map<JdbcType, TypeHandler<?>>>();
  private final TypeHandler<Object> UNKNOWN_TYPE_HANDLER = new UnknownTypeHandler(this);
  private final Map<Class<?>, TypeHandler<?>> ALL_TYPE_HANDLERS_MAP = new HashMap<Class<?>, TypeHandler<?>>();

TypeHandler

类型处理器接口

  //设置参数
  void setParameter(PreparedStatement ps, int i, T parameter, JdbcType jdbcType) throws SQLException;
  //取得结果,供普通select用
  T getResult(ResultSet rs, String columnName) throws SQLException;
  //取得结果,供普通select用
  T getResult(ResultSet rs, int columnIndex) throws SQLException;
  //取得结果,供SP用
  T getResult(CallableStatement cs, int columnIndex) throws SQLException;

缓存配置

Cache

缓存接口,定义了一些基本的缓存操作,所有缓存类都应该实现该接口。

PerpetualCache?

一个具有基本功能的缓存类,内部使用了 HashMap 实现缓存功能。

LruCache

一种具有 LRU 策略的缓存实现类。除此之外,MyBatis 还提供了具有 FIFO 策略的缓存 FifoCache。

keyMap是LinkedHashMap,注意:keyMap.put(key, key);

private final Cache delegate;
private Map<Object, Object> keyMap;
private Object eldestKey;

BlockingCache

实现了阻塞特性,该特性是基于 Java 重入锁实现的。同一时刻下,BlockingCache 仅允许一个线程访问指定 key 的缓存项,其他线程将会被阻塞住。

    private long timeout;
    private final Cache delegate;
    private final ConcurrentHashMap<Object, ReentrantLock> locks;

CacheKey

缓存key,一般缓存框架的数据结构基本上都是 Key-Value 方式存储,
MyBatis 对于其 Key 的生成采取规则为:[mappedStementId + offset + limit + SQL + queryParams + environment]生成一个哈希码

  private int multiplier;
  private int hashcode;
  private long checksum;
  private int count;
  private List<Object> updateList;

TransactionalCacheManager

事务缓存管理器,内部有一个Map<Cache, TransactionalCache> transactionalCaches

TransactionalCache

一种缓存装饰器,可以为 Cache 实例增加事务功能。脏读问题正是由该类进行处理的。

    private final Cache delegate;
    private boolean clearOnCommit;
    // 在事务被提交前,所有从数据库中查询的结果将缓存在此集合中
    private final Map<Object, Object> entriesToAddOnCommit;
    // 在事务被提交前,当缓存未命中时,CacheKey 将会被存储在此集合中
    private final Set<Object> entriesMissedInCache;

数据源配置

DataSourceFactory

数据源工厂,有三种内建的数据源类型 UNPOOLED POOLED JNDI

  //设置属性,被XMLConfigBuilder所调用
  void setProperties(Properties props);

  //生产数据源,直接得到javax.sql.DataSource
  DataSource getDataSource();

UnpooledDataSourceFactory

没有池化的数据源工厂

  protected DataSource dataSource;

  public UnpooledDataSourceFactory() {
    this.dataSource = new UnpooledDataSource();
  }

UnpooledDataSource

没有池化的数据源

  private ClassLoader driverClassLoader;
  //作为可选项,你可以传递数据库驱动的属性。要这样做,属性的前缀是以“driver.”开 头的,例如
  //driver.encoding=UTF8
  private Properties driverProperties;
  private static Map<String, Driver> registeredDrivers = new ConcurrentHashMap<String, Driver>();

  private String driver;
  private String url;
  private String username;
  private String password;

  private Boolean autoCommit;
  private Integer defaultTransactionIsolationLevel;

PooledDataSourceFactory

有连接池的数据源工厂,继承了UnpooledDataSourceFactory,this.dataSource = new PooledDataSource();

PooledDataSource

有连接池的数据源,这个是mybatis自己实行了一个连接池

  //有一个池状态
  private final PoolState state = new PoolState(this);

  //里面有一个UnpooledDataSource
  private final UnpooledDataSource dataSource;

  // OPTIONAL CONFIGURATION FIELDS
  //正在使用连接的数量
  protected int poolMaximumActiveConnections = 10;
  //空闲连接数
  protected int poolMaximumIdleConnections = 5;
  //在被强制返回之前,池中连接被检查的时间
  protected int poolMaximumCheckoutTime = 20000;
  //这是给连接池一个打印日志状态机会的低层次设置,还有重新 尝试获得连接, 这些情况下往往需要很长时间 为了避免连接池没有配置时静默失 败)。
  protected int poolTimeToWait = 20000;
  //发送到数据的侦测查询,用来验证连接是否正常工作,并且准备 接受请求。默认是“NO PING QUERY SET” ,这会引起许多数据库驱动连接由一 个错误信息而导致失败
  protected String poolPingQuery = "NO PING QUERY SET";
  //开启或禁用侦测查询
  protected boolean poolPingEnabled = false;
  //用来配置 poolPingQuery 多次时间被用一次
  protected int poolPingConnectionsNotUsedFor = 0;

  private int expectedConnectionTypeCode;

PoolState

池状态,里面有2个PooledConnection的list

  protected PooledDataSource dataSource;

  //空闲的连接
  protected final List<PooledConnection> idleConnections = new ArrayList<PooledConnection>();
  //活动的连接
  protected final List<PooledConnection> activeConnections = new ArrayList<PooledConnection>();
  //----------以下是一些统计信息----------
  //请求次数
  protected long requestCount = 0;
  //总请求时间
  protected long accumulatedRequestTime = 0;
  protected long accumulatedCheckoutTime = 0;
  protected long claimedOverdueConnectionCount = 0;
  protected long accumulatedCheckoutTimeOfOverdueConnections = 0;
  //总等待时间
  protected long accumulatedWaitTime = 0;
  //要等待的次数
  protected long hadToWaitCount = 0;
  //坏的连接次数
  protected long badConnectionCount = 0;

PooledConnection?

池化的连接

  private int hashCode = 0;
  private PooledDataSource dataSource;
  //真正的连接
  private Connection realConnection;
  //代理的连接
  private Connection proxyConnection;
  private long checkoutTimestamp;
  private long createdTimestamp;
  private long lastUsedTimestamp;
  private int connectionTypeCode;
  private boolean valid;

mapper配置

ResultMap

结果映射

  private String id;
  private Class<?> type;
  private List<ResultMapping> resultMappings;
  private List<ResultMapping> idResultMappings;
  private List<ResultMapping> constructorResultMappings;
  private List<ResultMapping> propertyResultMappings;
  private Set<String> mappedColumns;
  private Discriminator discriminator;
  private boolean hasNestedResultMaps;
  private boolean hasNestedQueries;
  private Boolean autoMapping;

ResultMapping

结果映射的一个字段

  private Configuration configuration;
  private String property;
  private String column;
  private Class<?> javaType;
  private JdbcType jdbcType;
  private TypeHandler<?> typeHandler;
  private String nestedResultMapId;
  private String nestedQueryId;
  private Set<String> notNullColumns;
  private String columnPrefix;
  private List<ResultFlag> flags;
  private List<ResultMapping> composites;
  private String resultSet;
  private String foreignColumn;
  private boolean lazy;

MappedStatement

映射的语句

  private String resource;
  private Configuration configuration;
  private String id;
  private Integer fetchSize;
  private Integer timeout;
  private StatementType statementType;
  private ResultSetType resultSetType;
  //SQL源码
  private SqlSource sqlSource;
  private Cache cache;
  private ParameterMap parameterMap;
  private List<ResultMap> resultMaps;
  private boolean flushCacheRequired;
  private boolean useCache;
  private boolean resultOrdered;
  private SqlCommandType sqlCommandType;
  private KeyGenerator keyGenerator;
  private String[] keyProperties;
  private String[] keyColumns;
  private boolean hasNestedResultMaps;
  private String databaseId;
  private Log statementLog;
  private LanguageDriver lang;
  private String[] resultSets;

KeyGenerator

键值生成器,定了2个回调方法,processBefore,processAfter

目前它有三个实现类,分别如下:

Jdbc3KeyGenerator
SelectKeyGenerator
NoKeyGenerator

Jdbc3KeyGenerator 用于获取插入数据后的自增主键数值。某些数据库不支持自增主键,需要手动填写主键字段,此时需要借助 SelectKeyGenerator 获取主键值。至于 NoKeyGenerator,这是一个空实现,没什么可说的。

SelectKeyGenerator

  public static final String SELECT_KEY_SUFFIX = "!selectKey";
  private boolean executeBefore;
  private MappedStatement keyStatement;

SqlSource

SQL源码,只有BoundSql getBoundSql(Object parameterObject)方法

SqlSourceBuilder

SQL源码构建器,#占位符的解析逻辑是包含在 SqlSourceBuilder 的 parse 方法中,该方法最终会将解析后的 SQL 以及其他的一些数据封装到 StaticSqlSource 中。

DynamicSqlSource

动态SQL源码

  private Configuration configuration;
  private SqlNode rootSqlNode;

RawSqlSource

原始SQL源码,比DynamicSqlSource快,里面有一个SqlSource sqlSource

StaticSqlSource

静态SQL源码

  private String sql;
  private List<ParameterMapping> parameterMappings;
  private Configuration configuration;

MixedSqlNode

混合SQL节点,组合模式,拥有一个SqlNode的List

StaticTextSqlNode

静态文本SQL节点,里面有一个String text

TextSqlNode

文本SQL节点(CDATA|TEXT),相当于里面有$的字符串,后期对$进行处理

  private String text;
  private Pattern injectionFilter;

IfSqlNode

  private ExpressionEvaluator evaluator;
  private String test;
  private SqlNode contents;

TrimSqlNode?

  private SqlNode contents;
  private String prefix;
  private String suffix;
  private List<String> prefixesToOverride;
  private List<String> suffixesToOverride;
  private Configuration configuration;

WhereSqlNode

  private static List<String> prefixList = Arrays.asList("AND ","OR ","AND\n", "OR\n", "AND\r", "OR\r", "AND\t", "OR\t");

SqlSession相关及四大对象

SqlSessionFactory

构建SqlSession的工厂,工厂模式,默认实现是DefaultSqlSessionFactory

有openSession和getConfiguration方法,用来获得SqlSession和Configuration

通过SqlSessionFactoryBuilder来构建

DefaultSqlSessionFactory

内部有一个Configuration

SqlSession

MyBatis主要的一个接口,用来执行SQL,获取映射器,管理事务

通常情况下,我们在应用程序中使用的Mybatis的API就是这个接口定义的方法。

sqlSession.getMapper()来动态代理执行Mapper中对应的SQL语句。而当一个动态代理对象进入到了MapperMethod的execute()方法后,它经过简单地判断就进入了SqlSession的delete、update、insert、select等方法,这里是真正执行SQL语句的地方。

SqlSession的执行过程是通过Executor、StatementHandler、ParameterHandler和ResultSetHandler来完成数据库操作和结果返回的,它们简称为四大对象

DefaultSqlSession

默认SqlSession实现

  private Configuration configuration;
  private Executor executor;
  /**
   * 是否自动提交
   */
  private boolean autoCommit;
  private boolean dirty;

Executor

代表执行器,由它调度StatementHandler、ParameterHandler、ResultSetHandler等来执行对应的SQL,其中StatementHandler是最重要的。

Executor表示执行器,它是真正执行Java和数据库交互的对象,所以它十分重要,每一个SqlSession都会拥有一个Executor对象,这个对象负责增删改查的具体操作,我们可以简单的将它理解为JDBC中Statement的封装版。

BaseExecutor

是一个抽象类,采用模板方法的设计模式。它实现了Executor接口,实现了执行器的基本功能。

SimpleExecutor

最简单的执行器,根据对应的SQL直接执行即可,不会做一些额外的操作;拼接完SQL之后,直接交给 StatementHandler? 去执行。

  protected Transaction transaction;
  protected Executor wrapper;

  //延迟加载队列(线程安全)
  protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;
  //本地缓存机制(Local Cache)防止循环引用(circular references)和加速重复嵌套查询(一级缓存)
  //本地缓存
  protected PerpetualCache localCache;
  //本地输出参数缓存
  protected PerpetualCache localOutputParameterCache;
  protected Configuration configuration;

  //查询堆栈
  protected int queryStack = 0;
  private boolean closed;

BatchExecutor

批处理执行器,用于将多个SQL一次性输出到数据库,通过批量操作来优化性能。通常需要注意的是批量更新操作,由于内部有缓存的实现,使用完成后记得调用flushStatements来清除缓存。

ReuseExecutor

可重用的执行器,重用的对象是Statement,也就是说该执行器会缓存同一个sql的Statement,省去Statement的重新创建,优化性能。内部的实现是通过一个HashMap来维护Statement对象的。由于当前Map只在该session中有效,所以使用完成后记得调用flushStatements来清除Map。调用实现的四个抽象方法时会调用 prepareStatement()

CachingExecutor

启用于二级缓存时的执行器;采用静态代理;代理一个 Executor 对象。执行 update 方法前判断是否清空二级缓存;执行 query 方法前先在二级缓存中查询,命中失败再通过被代理类查询。

  private Executor delegate;
  private TransactionalCacheManager tcm = new TransactionalCacheManager();

StatementHandler

作用是使用数据库的Statement(PreparedStatement)执行操作,它是四大对象的核心,起到承上启下的作用,许多重要的插件都是通过拦截它来实现的。

StatementHandler是数据库会话器,顾名思义,数据库会话器就是专门处理数据库会话的,相当于JDBC中的Statement(PreparedStatement)。

StatementHandler接口设计采用了适配器模式,其实现类RoutingStatementHandler根据上下文来选择适配器生成相应的StatementHandler。三个适配器分别是SimpleStatementHandler、PreparedStatementHandler和CallableStatementHandler。

BaseStatementHandler

是一个抽象类,它实现了StatementHandler接口,用于简化StatementHandler接口实现的难度,采用适配器设计模式,它主要有三个实现类SimpleStatementHandler、PreparedStatementHandler和CallableStatementHandler。

  protected final Configuration configuration;
  protected final ObjectFactory objectFactory;
  protected final TypeHandlerRegistry typeHandlerRegistry;
  protected final ResultSetHandler resultSetHandler;
  protected final ParameterHandler parameterHandler;

  protected final Executor executor;
  protected final MappedStatement mappedStatement;
  protected final RowBounds rowBounds;

  protected BoundSql boundSql;

SimpleStatementHandler

最简单的StatementHandler,处理不带参数运行的SQL,对应JDBC的Statement

PreparedStatementHandler

预处理Statement的handler,处理带参数允许的SQL, 对应JDBC的PreparedStatement(预编译处理)

CallableStatementHandler

存储过程的Statement的handler,处理存储过程SQL,对应JDBC的CallableStatement(存储过程处理)

RoutingStatementHandler

RoutingStatementHandler根据上下文来选择适配器生成相应的StatementHandler。三个适配器分别是SimpleStatementHandler、PreparedStatementHandler和CallableStatementHandler。

ParameterHandler

ParameterHandler 是参数处理器,它的作用是完成对预编译的参数的设置,也就是负责为 PreparedStatement 的 SQL 语句参数动态赋值。ParameterHandler 相比于其他的组件就简单很多了,这个接口很简单只有两个方法:

getParameterObject: 用于获取参数对象。

setParameters:用于设置预编译SQL的参数??????

DefaultParameterHandler

实现了public void setParameters(PreparedStatement ps)的逻辑

ResultSetHandler

ResultSetHandler 是结果处理器,它是用来组装结果集的。ResultSetHandler 接口的定义也挺简单的:

  //处理结果集
  <E> List<E> handleResultSets(Statement stmt) throws SQLException;

  //处理OUT参数
  void handleOutputParameters(CallableStatement cs) throws SQLException;

DefaultResultSetHandler

默认的结果处理器,public List<Object> handleResultSets(Statement stmt)返回stmt的结果

sql执行的其他相关

MapperRegistry

映射器注册机

有public <T> T getMapper(Class<T> type, SqlSession sqlSession)方法

  private Configuration config;
  //将已经添加的映射都放入HashMap
  private final Map<Class<?>, MapperProxyFactory<?>> knownMappers = new HashMap<Class<?>, MapperProxyFactory<?>>();

MapperProxyFactory

映射器代理工厂,有public T newInstance(SqlSession sqlSession)方法,返回Mapper的代理类

  private final Class<T> mapperInterface;
  private Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();

MapperMethod

映射器方法,有public Object execute(SqlSession sqlSession, Object[] args)执行代理类的方法

注意:execute方法里调用sqlsession的方法

  private final SqlCommand command;
  private final MethodSignature method;

SqlCommand?

保存了一些和 SQL 相关的信息

    private final String name;
    private final SqlCommandType type;

MethodSignature?

保存了一些和目标方法相关的信息。比如目标方法的返回类型,目标方法的参数列表信息等

    private final boolean returnsMany;
    private final boolean returnsMap;
    private final boolean returnsVoid;
    private final Class<?> returnType;
    private final String mapKey;
    private final Integer resultHandlerIndex;
    private final Integer rowBoundsIndex;
    private final SortedMap<Integer, String> params;
    private final boolean hasNamedParameters;

BoundSql

绑定的SQL,是从SqlSource而来,将动态内容都处理完成得到的SQL语句字符串,其中包括?,还有绑定的参数

其中#的直接塞到sql中,$变成?,然后ParameterMapping与?一一对应

  private String sql;
  private List<ParameterMapping> parameterMappings;
  private Object parameterObject;
  private Map<String, Object> additionalParameters;
  private MetaObject metaParameters;

DynamicContext

SQL 语句构建的上下文,每个 SQL 片段解析完成后,都会将解析结果存入 DynamicContext 中。待所有的 SQL 片段解析完毕后,一条完整的 SQL 语句就会出现在 DynamicContext 对象中。

  private final ContextMap bindings;
  private final StringBuilder sqlBuilder = new StringBuilder();

ParameterMapping

参数映射,对应#

  private Configuration configuration;

  //例子:#{property,javaType=int,jdbcType=NUMERIC}

  //property
  private String property;
  //mode
  private ParameterMode mode;
  //javaType=int
  private Class<?> javaType = Object.class;
  //jdbcType=NUMERIC
  private JdbcType jdbcType;
  //numericScale
  private Integer numericScale;
  private TypeHandler<?> typeHandler;
  private String resultMapId;
  //jdbcType=NUMERIC
  private String jdbcTypeName;
  private String expression;

执行sql流程小结

一条SQL语句在Mybatis中的执行过程小结:

首先是创建Mapper的动态代理对象MapperProxy,然后将Mappe接口中的方法封装至MapperMethod对象,通过MapperMethod对象中的execute()方法来执行SQL,其本质是通过SqlSession下的方法来实现的,SQL语句的具体的执行则是通过SqlSession下的四大对象来完成。

Executor先调用StatementHandler的prepare()方法预编译SQL,然后用parameterize()方法启用ParameterHandler设置参数,完成预编译,执行查询,update()也是这样的。

如果是查询,MyBatis则会使用ResultSetHandler来封装结果并返回给调用者,从而完成查询。其执行的完整流程图如下:

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2021-08-03 11:01:36  更:2021-08-03 11:02:23 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年5日历 -2024/5/3 20:20:41-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码