package org.apache.ibatis.session;
/**
* 这是MyBatis主要的一个类,用来执行SQL,获取映射器,管理事务,是顶层API接口
*
* 通常情况下,我们在应用程序中使用的Mybatis的API就是这个接口定义的方法。
*
*/
public interface SqlSession extends Closeable {
/**
* Retrieve a single row mapped from the statement key
* 根据指定的SqlID获取一条记录的封装对象
* @param the returned object type 封装之后的对象类型
* @param statement sqlID
* @return Mapped object 封装之后的对象
*/
<T> T selectOne(String statement);
/**
* Retrieve a single row mapped from the statement key and parameter.
* 根据指定的SqlID获取一条记录的封装对象,只不过这个方法容许我们可以给sql传递一些参数
* 一般在实际使用中,这个参数传递的是pojo,或者Map或者ImmutableMap
* @param the returned object type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @return Mapped object
*/
<T> T selectOne(String statement, Object parameter);
/**
* Retrieve a list of mapped objects from the statement key and parameter.
* 根据指定的sqlId获取多条记录
* @param the returned list element type
* @param statement Unique identifier matching the statement to use.
* @return List of mapped object
*/
<E> List<E> selectList(String statement);
/**
* Retrieve a list of mapped objects from the statement key and parameter.
* 获取多条记录,这个方法容许我们可以传递一些参数
* @param the returned list element type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @return List of mapped object
*/
<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.
* 获取多条记录,这个方法容许我们可以传递一些参数,不过这个方法容许我们进行
* 分页查询。
*
* 需要注意的是默认情况下,Mybatis为了扩展性,仅仅支持内存分页。也就是会先把
* 所有的数据查询出来以后,然后在内存中进行分页。因此在实际的情况中,需要注意
* 这一点。
*
* 一般情况下公司都会编写自己的Mybatis 物理分页插件
* @param the returned list element type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param rowBounds Bounds to limit object retrieval
* @return List of mapped object
*/
<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.
* Eg. Return a of Map[Integer,Author] for selectMap("selectAuthors","id")
* 将查询到的结果列表转换为Map类型。
* @param the returned Map keys type
* @param the returned Map values type
* @param statement Unique identifier matching the statement to use.
* @param mapKey The property to use as key for each value in the list. 这个参数会作为结果map的key
* @return Map containing key pair data.
*/
<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类型。这个方法容许我们传入需要的参数
* @param the returned Map keys type
* @param the returned Map values type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param mapKey The property to use as key for each value in the list.
* @return Map containing key pair data.
*/
<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
* @param the returned Map keys type
* @param the returned Map values type
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param mapKey The property to use as key for each value in the list.
* @param rowBounds Bounds to limit object retrieval
* @return Map containing key pair data.
*/
<K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds);
/**
* Retrieve a single row mapped from the statement key and parameter
* using a {@code ResultHandler}.
*
* @param statement Unique identifier matching the statement to use.
* @param parameter A parameter object to pass to the statement.
* @param handler ResultHandler that will handle each retrieved row
* @return Mapped object
*/
void select(String statement, Object parameter, ResultHandler handler);
/**
* Retrieve a single row mapped from the statement
* using a {@code ResultHandler}.
* 获取一条记录,并转交给ResultHandler处理。这个方法容许我们自己定义对
* 查询到的行的处理方式。不过一般用的并不是很多
* @param statement Unique identifier matching the statement to use.
* @param handler ResultHandler that will handle each retrieved row
* @return Mapped object
*/
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处理
* @param statement Unique identifier matching the statement to use.
* @param rowBounds RowBound instance to limit the query results
* @param handler ResultHandler that will handle each retrieved row
* @return Mapped object
*/
void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler);
/**
* Execute an insert statement.
* 插入记录。一般情况下这个语句在实际项目中用的并不是太多,而且更多使用带参数的insert函数
* @param statement Unique identifier matching the statement to execute.
* @return int The number of rows affected by the insert.
*/
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.
* 插入记录,容许传入参数。
* @param statement Unique identifier matching the statement to execute.
* @param parameter A parameter object to pass to the statement.
* @return int The number of rows affected by the insert. 注意返回的是受影响的行数
*/
int insert(String statement, Object parameter);
/**
* Execute an update statement. The number of rows affected will be returned.
* 更新记录。返回的是受影响的行数
* @param statement Unique identifier matching the statement to execute.
* @return int The number of rows affected by the update.
*/
int update(String statement);
/**
* Execute an update statement. The number of rows affected will be returned.
* 更新记录
* @param statement Unique identifier matching the statement to execute.
* @param parameter A parameter object to pass to the statement.
* @return int The number of rows affected by the update. 返回的是受影响的行数
*/
int update(String statement, Object parameter);
/**
* Execute a delete statement. The number of rows affected will be returned.
* 删除记录
* @param statement Unique identifier matching the statement to execute.
* @return int The number of rows affected by the delete. 返回的是受影响的行数
*/
int delete(String statement);
/**
* Execute a delete statement. The number of rows affected will be returned.
* 删除记录
* @param statement Unique identifier matching the statement to execute.
* @param parameter A parameter object to pass to the statement.
* @return int The number of rows affected by the delete. 返回的是受影响的行数
*/
int delete(String statement, Object parameter);
//以下是事务控制方法,commit,rollback
/**
* Flushes batch statements and commits database connection.
* Note that database connection will not be committed if no updates/deletes/inserts were called.
* To force the commit call {@link SqlSession#commit(boolean)}
*/
void commit();
/**
* Flushes batch statements and commits database connection.
* @param force forces connection commit
*/
void commit(boolean force);
/**
* Discards pending batch statements and rolls database connection back.
* Note that database connection will not be rolled back if no updates/deletes/inserts were called.
* To force the rollback call {@link SqlSession#rollback(boolean)}
*/
void rollback();
/**
* Discards pending batch statements and rolls database connection back.
* Note that database connection will not be rolled back if no updates/deletes/inserts were called.
* @param force forces connection rollback
*/
void rollback(boolean force);
/**
* Flushes batch statements.
* 刷新批处理语句,返回批处理结果
* @return BatchResult list of updated records
* @since 3.0.6
*/
List<BatchResult> flushStatements();
/**
* Closes the session
* 关闭Session
*/
@Override
void close();
/**
* Clears local session cache
* 清理Session缓存
*/
void clearCache();
/**
* Retrieves current configuration
* 得到配置
* @return Configuration
*/
Configuration getConfiguration();
/**
* Retrieves a mapper.
* 得到映射器
* 这个巧妙的使用了泛型,使得类型安全
* 到了MyBatis 3,还可以用注解,这样xml都不用写了
* @param the mapper type
* @param type Mapper interface class
* @return a mapper bound to this SqlSession
*/
<T> T getMapper(Class<T> type);
/**
* Retrieves inner database connection
* 得到数据库连接
* @return Connection
*/
Connection getConnection();
}
package org.apache.ibatis.executor;
public interface Executor {
//不需要ResultHandler
ResultHandler NO_RESULT_HANDLER = null;
//更新
int update(MappedStatement ms, Object parameter) throws SQLException;
//查询,带分页,带缓存,BoundSql
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
//查询,带分页
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
//刷新批处理语句
List<BatchResult> flushStatements() throws SQLException;
//提交和回滚,参数是是否要强制
void commit(boolean required) throws SQLException;
void rollback(boolean required) throws SQLException;
//创建CacheKey
CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql);
//判断是否缓存了
boolean isCached(MappedStatement ms, CacheKey key);
//清理Session缓存
void clearLocalCache();
//延迟加载
void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType);
Transaction getTransaction();
void close(boolean forceRollback);
boolean isClosed();
void setExecutorWrapper(Executor executor);
}
package org.apache.ibatis.executor.statement;
public interface StatementHandler {
//准备语句
Statement prepare(Connection connection)
throws SQLException;
//参数化
void parameterize(Statement statement)
throws SQLException;
//批处理
void batch(Statement statement)
throws SQLException;
//update
int update(Statement statement)
throws SQLException;
//select-->结果给ResultHandler
<E> List<E> query(Statement statement, ResultHandler resultHandler)
throws SQLException;
//得到绑定sql
BoundSql getBoundSql();
//得到参数处理器
ParameterHandler getParameterHandler();
}
public interface ParameterHandler {
//得到参数
Object getParameterObject();
//设置参数
void setParameters(PreparedStatement ps)
throws SQLException;
}
public interface ResultSetHandler {
//处理结果集
<E> List<E> handleResultSets(Statement stmt) throws SQLException;
//处理OUT参数
void handleOutputParameters(CallableStatement cs) throws SQLException;
}
public interface TypeHandler<T> {
//设置参数
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;
}
public final class MappedStatement {
//...
//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;
//...
public BoundSql getBoundSql(Object parameterObject) {
//其实就是调用sqlSource.getBoundSql
BoundSql boundSql = sqlSource.getBoundSql(parameterObject);
//剩下的可以暂时忽略
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
if (parameterMappings == null || parameterMappings.isEmpty()) {
boundSql = new BoundSql(configuration, boundSql.getSql(), parameterMap.getParameterMappings(), parameterObject);
}
// check for nested result maps in parameter mappings (issue #30)
for (ParameterMapping pm : boundSql.getParameterMappings()) {
String rmId = pm.getResultMapId();
if (rmId != null) {
ResultMap rm = configuration.getResultMap(rmId);
if (rm != null) {
hasNestedResultMaps |= rm.hasNestedResultMaps();
}
}
}
return boundSql;
}
}
public interface SqlSource {
BoundSql getBoundSql(Object parameterObject);
}
/**
* 绑定的SQL,是从SqlSource而来,将动态内容都处理完成得到的SQL语句字符串,其中包括?,还有绑定的参数
*
*/
public class BoundSql {
private String sql;
private List<ParameterMapping> parameterMappings;
private Object parameterObject;
private Map<String, Object> additionalParameters;
private MetaObject metaParameters;
public BoundSql(Configuration configuration, String sql, List<ParameterMapping> parameterMappings, Object parameterObject) {
this.sql = sql;
this.parameterMappings = parameterMappings;
this.parameterObject = parameterObject;
this.additionalParameters = new HashMap<String, Object>();
this.metaParameters = configuration.newMetaObject(additionalParameters);
}
public String getSql() {
return sql;
}
public List<ParameterMapping> getParameterMappings() {
return parameterMappings;
}
public Object getParameterObject() {
return parameterObject;
}
public boolean hasAdditionalParameter(String name) {
return metaParameters.hasGetter(name);
}
public void setAdditionalParameter(String name, Object value) {
metaParameters.setValue(name, value);
}
public Object getAdditionalParameter(String name) {
return metaParameters.getValue(name);
}
}
/**
* 映射器代理工厂
*/
public class MapperProxyFactory<T> {
private final Class<T> mapperInterface;
private Map<Method, MapperMethod> methodCache = new ConcurrentHashMap<Method, MapperMethod>();
public MapperProxyFactory(Class<T> mapperInterface) {
this.mapperInterface = mapperInterface;
}
public Class<T> getMapperInterface() {
return mapperInterface;
}
public Map<Method, MapperMethod> getMethodCache() {
return methodCache;
}
@SuppressWarnings("unchecked")
protected T newInstance(MapperProxy<T> mapperProxy) {
//用JDK自带的动态代理生成映射器
return (T) Proxy.newProxyInstance(mapperInterface.getClassLoader(), new Class[] { mapperInterface }, mapperProxy);
}
public T newInstance(SqlSession sqlSession) {
final MapperProxy<T> mapperProxy = new MapperProxy<T>(sqlSession, mapperInterface, methodCache);
return newInstance(mapperProxy);
}
}