Mybatis3.5.1源碼分析
- Mybatis-SqlSessionFactoryBuilder,XMLConfigBuilder,XPathParser源碼解析
- Mybatis-Configuration源碼解析
- Mybatis-事務(wù)對(duì)象源碼解析
- Mybatis-數(shù)據(jù)源源碼解析
- Mybatis緩存策略源碼解析
- Mybatis-DatabaseIdProvider源碼解析
- Mybatis-TypeHandler源碼解析
- Mybatis-Reflector源碼解析
- Mybatis-ObjectFactory,ObjectWrapperFactory源碼分析
- Mybatis-Mapper各類標(biāo)簽封裝類源碼解析
- Mybatis-XMLMapperBuilder,XMLStatmentBuilder源碼分析
- Mybatis-MapperAnnotationBuilder源碼分析
- [Mybatis-MetaObject,MetaClass源碼解析]http://www.itdecent.cn/p/f51fa552f30a)
- Mybatis-LanguageDriver源碼解析
- Mybatis-SqlSource源碼解析
- Mybatis-SqlNode源碼解析
- Mybatis-KeyGenerator源碼解析
- Mybatis-Executor源碼解析
- Mybatis-ParameterHandler源碼解析
- Mybatis-StatementHandler源碼解析
- Mybatis-DefaultResultSetHandler(一)源碼解析
- Mybatis-DefaultResultSetHandler(二)源碼解析
- Mybatis-ResultHandler,Cursor,RowBounds 源碼分析
- Mybatis-MapperProxy源碼解析
- Mybatis-SqlSession源碼解析
- Mybatis-Interceptor源碼解析
SqlSession
/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.session;
import java.io.Closeable;
import java.sql.Connection;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.executor.BatchResult;
/**
* The primary Java interface for working with MyBatis.
* Through this interface you can execute commands, get mappers and manage transactions.
* <p>
* 數(shù)據(jù)庫對(duì)話
* </p>
* <p>
* 這個(gè)Mybatis的主要Java接口,通過這個(gè)接口可以執(zhí)行命令,映射器和管理事務(wù)。
* </p>
* <p>
* Closeable:表示可以關(guān)閉的數(shù)據(jù)的源或目的地。 調(diào)用close方法來釋放對(duì)象持有的資源(如打開的文件)。
* </p>
* @author Clinton Begin
*/
public interface SqlSession extends Closeable {
/**
* Retrieve a single row mapped from the statement key. 返回單個(gè)查詢結(jié)果
* @param <T> the returned object type 結(jié)果對(duì)象類型
* @param statement 唯一標(biāo)識(shí)匹配的語句.
* @return Mapped object 映射對(duì)象
*/
<T> T selectOne(String statement);
/**
* Retrieve a single row mapped from the statement key and parameter. 返回單個(gè)查詢結(jié)果
* @param <T> the returned object type 結(jié)果對(duì)象類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @return Mapped object 映射對(duì)象
*/
<T> T selectOne(String statement, Object parameter);
/**
* Retrieve a list of mapped objects from the statement key and parameter. 返回查詢結(jié)果集合
* @param <E> the returned list element type 結(jié)果對(duì)象類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @return List of mapped object 映射對(duì)象集合
*/
<E> List<E> selectList(String statement);
/**
* Retrieve a list of mapped objects from the statement key and parameter. 返回查詢結(jié)果集合
* @param <E> the returned list element type 結(jié)果對(duì)象類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @return List of mapped object 映射對(duì)象集合
*/
<E> List<E> selectList(String statement, Object parameter);
/**
* Retrieve a list of mapped objects from the statement key and parameter,
* within the specified row bounds. 返回集合結(jié)果
* @param <E> the returned list element type 結(jié)果對(duì)象類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param rowBounds Bounds to limit object retrieval 返回結(jié)果的大小控制
* @return List of mapped object 映射對(duì)象集合
*/
<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
/**
* The selectMap is a special case in that it is designed to convert a list
* of results into a Map based on one of the properties in the resulting
* objects.
* 返回Map對(duì)象
* Eg. Return a of Map[Integer,Author] for selectMap("selectAuthors","id")
* @param <K> the returned Map keys type Map的Key類型
* @param <V> the returned Map values type Map的Value類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param mapKey The property to use as key for each value in the list. key值,字段的屬性別名
* @return Map containing key pair data. 結(jié)果對(duì)象映射
*/
<K, V> Map<K, V> selectMap(String statement, String mapKey);
/**
* The selectMap is a special case in that it is designed to convert a list
* of results into a Map based on one of the properties in the resulting
* objects. 返回Map對(duì)象
* @param <K> the returned Map keys type Map的Key類型
* @param <V> the returned Map values type Map的Value類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param mapKey The property to use as key for each value in the list. key值,字段的屬性別名
* @return Map containing key pair data. 結(jié)果對(duì)象映射
*/
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey);
/**
* The selectMap is a special case in that it is designed to convert a list
* of results into a Map based on one of the properties in the resulting
* objects. 返回Map對(duì)象
* @param <K> the returned Map keys type Map的Key類型
* @param <V> the returned Map values type Map的Value類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param mapKey The property to use as key for each value in the list. key值,字段的屬性別名
* @param rowBounds Bounds to limit object retrieval 返回結(jié)果的大小控制
* @return Map containing key pair data. 結(jié)果對(duì)象映射
*/
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
/**
* A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. 游標(biāo)查詢
* @param <T> the returned cursor element type. 結(jié)果對(duì)象類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @return Cursor of mapped objects 結(jié)果對(duì)象游標(biāo)
*/
<T> Cursor<T> selectCursor(String statement);
/**
* A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. 游標(biāo)查詢
* @param <T> the returned cursor element type. 結(jié)果對(duì)象類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement.查詢參數(shù)對(duì)象
* @return Cursor of mapped objects 結(jié)果對(duì)象游標(biāo)
*/
<T> Cursor<T> selectCursor(String statement, Object parameter);
/**
* A Cursor offers the same results as a List, except it fetches data lazily using an Iterator. 游標(biāo)查詢
* @param <T> the returned cursor element type. 結(jié)果對(duì)象類型
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param rowBounds Bounds to limit object retrieval 返回結(jié)果的大小控制
* @return Cursor of mapped objects 結(jié)果對(duì)象游標(biāo)
*/
<T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds);
/**
* Retrieve a single row mapped from the statement key and parameter
* using a {@code ResultHandler}. 查詢單條,用ResultHandler接收結(jié)果
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param handler ResultHandler that will handle each retrieved row 結(jié)果接收處理器
*/
void select(String statement, Object parameter, ResultHandler handler);
/**
* Retrieve a single row mapped from the statement
* using a {@code ResultHandler}. 查詢單條,用ResultHandler接收結(jié)果
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param handler ResultHandler that will handle each retrieved row 結(jié)果接收處理器
*/
void select(String statement, ResultHandler handler);
/**
* Retrieve a single row mapped from the statement key and parameter
* using a {@code ResultHandler} and {@code RowBounds}. 查詢單條,用ResultHandler接收結(jié)果
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param rowBounds RowBound instance to limit the query results 返回結(jié)果的大小控制
* @param handler ResultHandler that will handle each retrieved row 結(jié)果接收處理器
*/
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
/**
* Execute an insert statement. 執(zhí)行插入SQL
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @return int The number of rows affected by the insert. 更新記錄數(shù)
*/
int insert(String statement);
/**
* Execute an insert statement with the given parameter object. Any generated
* autoincrement values or selectKey entries will modify the given parameter
* object properties. Only the number of rows affected will be returned. 執(zhí)行插入SQL
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 插入?yún)?shù)對(duì)象
* @return int The number of rows affected by the insert. 更新記錄數(shù)
*/
int insert(String statement, Object parameter);
/**
* Execute an update statement. The number of rows affected will be returned. 執(zhí)行修改SQL
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @return int The number of rows affected by the update.更新記錄數(shù)
*/
int update(String statement);
/**
* Execute an update statement. The number of rows affected will be returned. 執(zhí)行修改SQL
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 修改參數(shù)對(duì)象
* @return int The number of rows affected by the update. .更新記錄數(shù)
*/
int update(String statement, Object parameter);
/**
* Execute a delete statement. The number of rows affected will be returned. 執(zhí)行刪除SQL
* @param statement Unique identifier matching the statement to execute.唯一標(biāo)識(shí)匹配的語句
* @return int The number of rows affected by the delete. 更新記錄數(shù)
*/
int delete(String statement);
/**
* Execute a delete statement. The number of rows affected will be returned. 執(zhí)行delete語句。將返回受影響的行數(shù);
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 刪除參數(shù)對(duì)象
* @return int The number of rows affected by the delete. 更新記錄數(shù)
*/
int delete(String statement, Object parameter);
/**
* Flushes batch statements and commits database connection. 事務(wù)提交
* Note that database connection will not be committed if no updates/deletes/inserts were called. 注意,數(shù)據(jù)庫連接將不會(huì)提交如果沒有更新/刪除/插入被稱為。;
* To force the commit call {@link SqlSession#commit(boolean)} 如果需要強(qiáng)制提交,可以調(diào)用 {@link SqlSession#commit(boolean)}
*/
void commit();
/**
* Flushes batch statements and commits database connection. 事務(wù)提交
* @param force forces connection commit 強(qiáng)制提交數(shù)據(jù)庫連接
*/
void commit(boolean force);
/**
* Discards pending batch statements and rolls database connection back. 事務(wù)回退
* Note that database connection will not be rolled back if no updates/deletes/inserts were called. 注意,數(shù)據(jù)庫連接將不會(huì)回退如果沒有更新/刪除/插入被調(diào)用;
* To force the rollback call {@link SqlSession#rollback(boolean)} 如果需要強(qiáng)制回退,可以調(diào)用 {@link SqlSession#commit(boolean)}
*/
void rollback();
/**
* Discards pending batch statements and rolls database connection back. 事務(wù)回退;
* Note that database connection will not be rolled back if no updates/deletes/inserts were called.注意,數(shù)據(jù)庫連接將不會(huì)回退如果沒有更新/刪除/插入被稱為。;
* @param force forces connection rollback 強(qiáng)制回退數(shù)據(jù)庫連接
*/
void rollback(boolean force);
/**
* Flushes batch statements.執(zhí)行全部等待批處理語句,并將結(jié)果封裝到BatchResult集合中
* @return BatchResult list of updated records 更新記錄的BatchResult集合
* @since 3.0.6
*/
List<BatchResult> flushStatements();
/**
* Closes the session. 關(guān)閉數(shù)據(jù)庫對(duì)話
*/
@Override
void close();
/**
* Clears local session cache. 清空數(shù)據(jù)庫對(duì)話緩存
*/
void clearCache();
/**
* 獲取Mybatis全局配置信息
* Retrieves current configuration.
* @return Configuration
*/
Configuration getConfiguration();
/**
* Retrieves a mapper. 獲取Mapper
* @param <T> the mapper type Mapper對(duì)應(yīng)的Class類型
* @param type Mapper interface class Mapper對(duì)應(yīng)的Class類型
* @return a mapper bound to this SqlSession 一個(gè)綁定到這個(gè)Sql會(huì)話的Mapper;
*/
<T> T getMapper(Class<T> type);
/**
* Retrieves inner database connection. 獲取數(shù)據(jù)庫連接
* @return Connection
*/
Connection getConnection();
}
DefaultSqlSession
/**
* Copyright 2009-2019 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.apache.ibatis.session.defaults;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.ibatis.binding.BindingException;
import org.apache.ibatis.cursor.Cursor;
import org.apache.ibatis.exceptions.ExceptionFactory;
import org.apache.ibatis.exceptions.TooManyResultsException;
import org.apache.ibatis.executor.BatchResult;
import org.apache.ibatis.executor.ErrorContext;
import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.executor.result.DefaultMapResultHandler;
import org.apache.ibatis.executor.result.DefaultResultContext;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.session.Configuration;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;
import org.apache.ibatis.session.SqlSession;
/**
* The default implementation for {@link SqlSession}. 這是一個(gè)SqlSession接口的默認(rèn)實(shí)現(xiàn)類
* Note that this class is not Thread-Safe. 注意,這個(gè)類并不是線程安全的
*
* @author Clinton Begin
*/
public class DefaultSqlSession implements SqlSession {
/**
* mybatis全局配置新
*/
private final Configuration configuration;
/**
* SQL腳本執(zhí)行器
*/
private final Executor executor;
/**
* 是否自動(dòng)提交
*/
private final boolean autoCommit;
/**
* 是否有調(diào)用更新SQL腳本標(biāo)記
*/
private boolean dirty;
/**
* 游標(biāo)集合
*/
private List<Cursor<?>> cursorList;
/**
*
* @param configuration mybatis全局配置信息
* @param executor SQL腳本執(zhí)行器
* @param autoCommit 是否自動(dòng)提交標(biāo)記
*/
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
this.configuration = configuration;
this.executor = executor;
this.dirty = false;
this.autoCommit = autoCommit;
}
/**
*
* @param configuration Mybatis全局配置信息
* @param executor SQL腳本執(zhí)行器
*/
public DefaultSqlSession(Configuration configuration, Executor executor) {
//不設(shè)置自動(dòng)提交
this(configuration, executor, false);
}
/**
* 返回單個(gè)查詢結(jié)果
* @param statement 唯一標(biāo)識(shí)匹配的語句.
* @param <T> 結(jié)果對(duì)象類型
* @return 映射對(duì)象
*/
@Override
public <T> T selectOne(String statement) {
return this.selectOne(statement, null);
}
/**
* 返回單個(gè)查詢結(jié)果
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param <T> 結(jié)果對(duì)象類型
* @return 映射對(duì)象
*/
@Override
public <T> T selectOne(String statement, Object parameter) {
// Popular vote was to return null on 0 results and throw exception on too many.
// 民眾投票 當(dāng)沒有結(jié)果對(duì)象時(shí),返回null;當(dāng)超過1條結(jié)果對(duì)象時(shí),拋出異常
List<T> list = this.selectList(statement, parameter);
//如果一個(gè)結(jié)果對(duì)象在集合中
if (list.size() == 1) {
//返回這個(gè)結(jié)果對(duì)象
return list.get(0);
//如果出現(xiàn)超過一個(gè)結(jié)果對(duì)象在集合中
} else if (list.size() > 1) {
//拋出異常
throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size());
//如果沒有結(jié)果對(duì)象在集合中
} else {
//返回null
return null;
}
}
/**
* 返回Map對(duì)象
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param mapKey The property to use as key for each value in the list. key值,字段的屬性別名
* @param <K> Map的Key類型
* @param <V> Map的Value類型
* @return 結(jié)果對(duì)象映射
*/
@Override
public <K, V> Map<K, V> selectMap(String statement, String mapKey) {
//RowBounds.DEFAULT:從0開始到Integer.MAX_VALUE
return this.selectMap(statement, null, mapKey, RowBounds.DEFAULT);
}
/**
* 返回Map對(duì)象
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param mapKey The property to use as key for each value in the list. key值,字段的屬性別名
* @param <K> Map的Key類型
* @param <V> Map的Value類型
* @return 結(jié)果對(duì)象映射
*/
@Override
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) {
//RowBounds.DEFAULT:從0開始到Integer.MAX_VALUE
return this.selectMap(statement, parameter, mapKey, RowBounds.DEFAULT);
}
/**
* 返回Map對(duì)象
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param mapKey The property to use as key for each value in the list. key值,字段的屬性別名
* @param rowBounds Bounds to limit object retrieval 返回結(jié)果的大小控制
* @param <K> Map的Key類型
* @param <V> Map的Value類型
* @return 結(jié)果對(duì)象映射
*/
@Override
public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) {
//執(zhí)行查詢SQL腳本,返回結(jié)果對(duì)象集合
final List<? extends V> list = selectList(statement, parameter, rowBounds);
//新建一個(gè)默認(rèn)Map形式的ResultHandler
final DefaultMapResultHandler<K, V> mapResultHandler = new DefaultMapResultHandler<>(mapKey,
configuration.getObjectFactory(), configuration.getObjectWrapperFactory(), configuration.getReflectorFactory());
//新建一個(gè)默認(rèn)結(jié)果上下文:這個(gè)類封裝了結(jié)果集個(gè)數(shù)和當(dāng)前結(jié)果
final DefaultResultContext<V> context = new DefaultResultContext<>();
//遍歷結(jié)果對(duì)象集合
for (V o : list) {
//將結(jié)果對(duì)象賦值到結(jié)果上下文的下一個(gè)結(jié)果對(duì)象中
context.nextResultObject(o);
//接收結(jié)果上下文,取出結(jié)果對(duì)象,添加到mapResultHandler內(nèi)部維護(hù)的Map對(duì)象中
mapResultHandler.handleResult(context);
}
//返回mapResultHandler內(nèi)部維護(hù)的Map對(duì)象
return mapResultHandler.getMappedResults();
}
/**
* 游標(biāo)查詢
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param <T> 結(jié)果對(duì)象類型
* @return 結(jié)果對(duì)象游標(biāo)
*/
@Override
public <T> Cursor<T> selectCursor(String statement) {
return selectCursor(statement, null);
}
/**
* 游標(biāo)查詢
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement.查詢參數(shù)對(duì)象
* @param <T> 結(jié)果對(duì)象類型
* @return 結(jié)果對(duì)象游標(biāo)
*/
@Override
public <T> Cursor<T> selectCursor(String statement, Object parameter) {
//RowBounds.DEFAULT:從0開始到Integer.MAX_VALUE
return selectCursor(statement, parameter, RowBounds.DEFAULT);
}
/**
* 游標(biāo)查詢
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param rowBounds Bounds to limit object retrieval 返回結(jié)果的大小控制
* @param <T> 結(jié)果對(duì)象類型
* @return 結(jié)果對(duì)象游標(biāo)
*/
@Override
public <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds) {
try {
//MappedStatement: Mapper.xml文件的select,delete,update,insert這些DML標(biāo)簽的封裝類
//獲取statement對(duì)應(yīng)的MappedStatment對(duì)象
MappedStatement ms = configuration.getMappedStatement(statement);
/**
* 如果{@code object}是數(shù)組,或者是Collection實(shí)現(xiàn)類,會(huì)將 {@code object} 包裝成StrictMap對(duì)象,
* 否則直接返回 {@code object},執(zhí)行查詢,返回結(jié)果對(duì)象游標(biāo)
*/
Cursor<T> cursor = executor.queryCursor(ms, wrapCollection(parameter), rowBounds);
//注冊(cè)游標(biāo),將cursor添加到cursorList中
registerCursor(cursor);
//返回結(jié)果對(duì)象游標(biāo)
return cursor;
} catch (Exception e) {
//如果出現(xiàn)異常,就包裝異常對(duì)象,并加以描述再拋出
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
//錯(cuò)誤上下文實(shí)例重置
ErrorContext.instance().reset();
}
}
/**
* 返回查詢結(jié)果集合
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param <E> 結(jié)果對(duì)象類型
* @return 映射對(duì)象集合
*/
@Override
public <E> List<E> selectList(String statement) {
return this.selectList(statement, null);
}
/**
* 返回查詢結(jié)果集合
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句.
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param <E> 結(jié)果對(duì)象類型
* @return 映射對(duì)象集合
*/
@Override
public <E> List<E> selectList(String statement, Object parameter) {
//RowBounds.DEFAULT:從0開始到Integer.MAX_VALUE
return this.selectList(statement, parameter, RowBounds.DEFAULT);
}
/**
* 返回集合結(jié)果
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param rowBounds Bounds to limit object retrieval 返回結(jié)果的大小控制
* @param <E> 結(jié)果對(duì)象類型
* @return 結(jié)果對(duì)象集合
*/
@Override
public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) {
try {
//MappedStatement: Mapper.xml文件的select,delete,update,insert這些DML標(biāo)簽的封裝類
//獲取statement對(duì)應(yīng)的MappedStatment對(duì)象
MappedStatement ms = configuration.getMappedStatement(statement);
/**
* 如果{@code object}是數(shù)組,或者是Collection實(shí)現(xiàn)類,會(huì)將 {@code object} 包裝成StrictMap對(duì)象,
* 否則直接返回 {@code object},執(zhí)行查詢,返回結(jié)果對(duì)象集合
*/
return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER);
} catch (Exception e) {
//如果出現(xiàn)異常,就包裝異常對(duì)象,并加以描述再拋出
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
//錯(cuò)誤上下文實(shí)例重置
ErrorContext.instance().reset();
}
}
/**
* 查詢單條,用ResultHandler接收結(jié)果
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 查詢參數(shù)對(duì)象
* @param handler ResultHandler that will handle each retrieved row 結(jié)果接收處理器
*/
@Override
public void select(String statement, Object parameter, ResultHandler handler) {
//RowBounds.DEFAULT:從0開始到Integer.MAX_VALUE
select(statement, parameter, RowBounds.DEFAULT, handler);
}
/**
* 查詢單條,用ResultHandler接收結(jié)果
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param handler ResultHandler that will handle each retrieved row 結(jié)果接收處理器
*/
@Override
public void select(String statement, ResultHandler handler) {
//RowBounds.DEFAULT:從0開始到Integer.MAX_VALUE
select(statement, null, RowBounds.DEFAULT, handler);
}
/**
* 查詢單條,用ResultHandler接收結(jié)果
* @param statement Unique identifier matching the statement to use. 唯一標(biāo)識(shí)匹配的語句
* @param parameter 參數(shù)對(duì)象
* @param rowBounds RowBound instance to limit the query results 返回結(jié)果的大小控制
* @param handler ResultHandler that will handle each retrieved row 結(jié)果接收處理器
*/
@Override
public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) {
try {
//MappedStatement: Mapper.xml文件的select,delete,update,insert這些DML標(biāo)簽的封裝類
//獲取statement對(duì)應(yīng)的MappedStatment對(duì)象
MappedStatement ms = configuration.getMappedStatement(statement);
/**
* 如果parameter是數(shù)組,或者是Collection實(shí)現(xiàn)類,會(huì)將parameter 包裝成StrictMap對(duì)象,
* 否則直接返回parameter,執(zhí)行查詢,用handler接收結(jié)果對(duì)象
*/
executor.query(ms, wrapCollection(parameter), rowBounds, handler);
} catch (Exception e) {
//如果出現(xiàn)異常,就包裝異常對(duì)象,并加以描述再拋出
throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e);
} finally {
//錯(cuò)誤上下文實(shí)例重置
ErrorContext.instance().reset();
}
}
/**
* 執(zhí)行插入SQL
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @return 更新記錄數(shù)
*/
@Override
public int insert(String statement) {
return insert(statement, null);
}
/**
* 執(zhí)行插入SQL
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 插入?yún)?shù)對(duì)象
* @return 更新記錄數(shù)
*/
@Override
public int insert(String statement, Object parameter) {
return update(statement, parameter);
}
/**
* 執(zhí)行修改SQL
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @return 更新記錄數(shù)
*/
@Override
public int update(String statement) {
return update(statement, null);
}
/**
* 執(zhí)行修改SQL
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 修改參數(shù)對(duì)象
* @return 更新記錄數(shù)
*/
@Override
public int update(String statement, Object parameter) {
try {
//將是否有調(diào)用更新SQL標(biāo)記設(shè)置為true,表示有有調(diào)用更新SQL
dirty = true;
//MappedStatement: Mapper.xml文件的select,delete,update,insert這些DML標(biāo)簽的封裝類
//獲取statement對(duì)應(yīng)的MappedStatment對(duì)象
MappedStatement ms = configuration.getMappedStatement(statement);
/**
* wrapCollection:如果parameter是數(shù)組,或者是Collection實(shí)現(xiàn)類,會(huì)將parameter 包裝成StrictMap對(duì)象,
* 否則直接返回parameter
*/
//執(zhí)行更新SQL腳本
return executor.update(ms, wrapCollection(parameter));
} catch (Exception e) {
//如果出現(xiàn)異常,就包裝異常對(duì)象,并加以描述再拋出
throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e);
} finally {
//錯(cuò)誤上下文實(shí)例重置
ErrorContext.instance().reset();
}
}
/**
* 執(zhí)行刪除SQL
* @param statement Unique identifier matching the statement to execute.唯一標(biāo)識(shí)匹配的語句
* @return 更新記錄數(shù)
*/
@Override
public int delete(String statement) {
return update(statement, null);
}
/**
* 執(zhí)行刪除SQL
* @param statement Unique identifier matching the statement to execute. 唯一標(biāo)識(shí)匹配的語句
* @param parameter A parameter object to pass to the statement. 刪除參數(shù)對(duì)象
* @return 更新記錄數(shù)
*/
@Override
public int delete(String statement, Object parameter) {
return update(statement, parameter);
}
/**
* 事務(wù)提交
* <p>
* 注意,數(shù)據(jù)庫連接將不會(huì)提交如果沒有更新/刪除/插入被稱為。
* 如果需要強(qiáng)制提交,可以調(diào)用 {@link SqlSession#commit(boolean)}
* </p>
*/
@Override
public void commit() {
commit(false);
}
/**
* 事務(wù)提交
* @param force forces connection commit 強(qiáng)制提交數(shù)據(jù)庫連接
*/
@Override
public void commit(boolean force) {
try {
/**
* isCommitOrRollbackRequired:只要force為true,一定返回ture;如果force
* 為false,如果沒有設(shè)置自動(dòng)提交但有執(zhí)行更新的SQL腳本;否則返回false
*/
//通知執(zhí)行器提交事務(wù)
executor.commit(isCommitOrRollbackRequired(force));
//事務(wù)結(jié)束,標(biāo)記還原
dirty = false;
} catch (Exception e) {
//如果出現(xiàn)異常,就包裝異常對(duì)象,并加以描述再拋出
throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + e, e);
} finally {
//錯(cuò)誤上下文實(shí)例重置
ErrorContext.instance().reset();
}
}
/**
* 事務(wù)回退
* <p>
* 注意,數(shù)據(jù)庫連接將不會(huì)回退如果沒有更新/刪除/插入被調(diào)用;
* 如果需要強(qiáng)制回退,可以調(diào)用 {@link SqlSession#commit(boolean)}
* </p>
*/
@Override
public void rollback() {
rollback(false);
}
/**
* 事務(wù)回退
* @param force forces connection rollback 強(qiáng)制回退數(shù)據(jù)庫連接
*/
@Override
public void rollback(boolean force) {
try {
/**
* isCommitOrRollbackRequired:只要force為true,一定返回ture;如果force
* 為false,如果沒有設(shè)置自動(dòng)提交但有執(zhí)行更新的SQL腳本;否則返回false
*/
//通知執(zhí)行器回退事務(wù)
executor.rollback(isCommitOrRollbackRequired(force));
//事務(wù)結(jié)束,標(biāo)記還原
dirty = false;
} catch (Exception e) {
//如果出現(xiàn)異常,就包裝異常對(duì)象,并加以描述再拋出
throw ExceptionFactory.wrapException("Error rolling back transaction. Cause: " + e, e);
} finally {
//錯(cuò)誤上下文實(shí)例重置
ErrorContext.instance().reset();
}
}
/**
* 執(zhí)行全部等待批處理語句,并將結(jié)果封裝到BatchResult集合中
* @return 更新記錄的BatchResult集合
*/
@Override
public List<BatchResult> flushStatements() {
try {
//通知執(zhí)行器執(zhí)行全部等待批處理語句,并將結(jié)果封裝到BatchResult集合中
return executor.flushStatements();
} catch (Exception e) {
//如果出現(xiàn)異常,就包裝異常對(duì)象,并加以描述再拋出
throw ExceptionFactory.wrapException("Error flushing statements. Cause: " + e, e);
} finally {
//錯(cuò)誤上下文實(shí)例重置
ErrorContext.instance().reset();
}
}
@Override
public void close() {
try {
/**
* isCommitOrRollbackRequired:只要force為true,一定返回ture;如果force
* 為false,如果沒有設(shè)置自動(dòng)提交但有執(zhí)行更新的SQL腳本;否則返回false
*/
//關(guān)閉執(zhí)行器,回退事務(wù),關(guān)閉事務(wù)
executor.close(isCommitOrRollbackRequired(false));
//關(guān)閉游標(biāo)集合中的所有游標(biāo)對(duì)象,清空游標(biāo)集合
closeCursors();
//標(biāo)記還原
dirty = false;
} finally {
//錯(cuò)誤上下文實(shí)例重置
ErrorContext.instance().reset();
}
}
/**
* 關(guān)閉游標(biāo)集合中的所有游標(biāo)對(duì)象,清空游標(biāo)集合
*/
private void closeCursors() {
//如果游標(biāo)集合不為null且游標(biāo)集合不是空集合
if (cursorList != null && cursorList.size() != 0) {
//遍歷游標(biāo)集合
for (Cursor<?> cursor : cursorList) {
try {
//關(guān)閉游標(biāo)
cursor.close();
} catch (IOException e) {
//如果出現(xiàn)異常,就包裝異常對(duì)象,并加以描述再拋出
throw ExceptionFactory.wrapException("Error closing cursor. Cause: " + e, e);
}
}
//清空游標(biāo)集合中的所有游標(biāo)
cursorList.clear();
}
}
/**
* 獲取Mybatis全局配置信息
* @return Mybatis全局配置信息對(duì)象
*/
@Override
public Configuration getConfiguration() {
return configuration;
}
/**
* 獲取Mapper
* @param type Mapper interface class Mapper對(duì)應(yīng)的Class類型
* @param <T> Mapper對(duì)應(yīng)的Class類型
* @return 一個(gè)綁定到這個(gè)Sql會(huì)話的Mapper;
*/
@Override
public <T> T getMapper(Class<T> type) {
return configuration.getMapper(type, this);
}
/**
* 獲取數(shù)據(jù)庫連接
* @return 數(shù)據(jù)庫連接對(duì)象
*/
@Override
public Connection getConnection() {
try {
//從執(zhí)行器中獲取事務(wù)對(duì)象,再從事務(wù)對(duì)象中獲取數(shù)據(jù)庫連接并返回
return executor.getTransaction().getConnection();
} catch (SQLException e) {
////如果出現(xiàn)異常,就包裝異常對(duì)象,并加以描述再拋出
throw ExceptionFactory.wrapException("Error getting a new connection. Cause: " + e, e);
}
}
/**
* 清空數(shù)據(jù)庫對(duì)話緩存
*/
@Override
public void clearCache() {
//清空?qǐng)?zhí)行器本地緩存(一級(jí)緩存)
executor.clearLocalCache();
}
/**
* 注冊(cè)游標(biāo),將 {@code cursor} 添加到cursorList中
* @param cursor 結(jié)果對(duì)象游標(biāo)
* @param <T> 結(jié)果對(duì)象類型
*/
private <T> void registerCursor(Cursor<T> cursor) {
//如果游標(biāo)集合為null
if (cursorList == null) {
//實(shí)例化cursorList為ArrayList
cursorList = new ArrayList<>();
}
//添加cursor到游標(biāo)對(duì)象集合中
cursorList.add(cursor);
}
/**
* 是否必須提交或者回滾
* @param force 是否強(qiáng)制提交或者強(qiáng)制關(guān)閉
* @return 只要force為true,一定返回ture;如果 {@code force} 為false,如果沒有設(shè)置自動(dòng)提交但有執(zhí)行更新的SQL腳本;否則返回false
*/
private boolean isCommitOrRollbackRequired(boolean force) {
//只要force為true,一定返回ture
//如果force為false,如果沒有設(shè)置自動(dòng)提交但有執(zhí)行更新的SQL腳本,返回true;否則返回false
return (!autoCommit && dirty) || force;
}
/**
* 如果{@code object}是數(shù)組,或者是Collection實(shí)現(xiàn)類,會(huì)將 {@code object} 包裝成StrictMap對(duì)象,否則直接返回 {@code object}
* @param object 參數(shù)對(duì)象
* @return 如果object是數(shù)組,或者是Collection的實(shí)現(xiàn)類,就直接返回StrictMap對(duì)象;否則直接返回 {@code object}
*/
private Object wrapCollection(final Object object) {
//如果Object是Collection的實(shí)現(xiàn)類
if (object instanceof Collection) {
//StrictMap:HashMap的子類,對(duì)獲取集合沒有元素時(shí)會(huì)拋出異常。
//新建一個(gè)Map
StrictMap<Object> map = new StrictMap<>();
//將object添加到map,key為collection
map.put("collection", object);
//如果object還是List的實(shí)現(xiàn)類
if (object instanceof List) {
//將object再次添加到map,key為list
map.put("list", object);
}
return map;
//如果object不為null,且 object是數(shù)組
} else if (object != null && object.getClass().isArray()) {
//StrictMap:HashMap的子類,對(duì)獲取集合沒有元素時(shí)會(huì)拋出異常。
//新建一個(gè)Map
StrictMap<Object> map = new StrictMap<>();
//將object再次添加到map,key為array
map.put("array", object);
return map;
}
//如果object不是數(shù)組,又不是Collection的實(shí)現(xiàn)類,就直接返回object
return object;
}
/**
* HashMap的子類,對(duì)獲取集合沒有元素時(shí)會(huì)拋出異常。
*/
public static class StrictMap<V> extends HashMap<String, V> {
private static final long serialVersionUID = -5741767162221585340L;
@Override
public V get(Object key) {
//如果沒有key對(duì)應(yīng)的value時(shí)
if (!super.containsKey(key)) {
throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
}
return super.get(key);
}
}
}