下面我们分析一个最常用的mapper接口,向数据库插入单个实体对象的源码实现逻辑。
省略配置文件…因为重点在于插入源码,先回顾下我们应用app服务端开发熟悉的配置mybatis过程。
//加载MapperConfig.xml的配置文件
final String resource = "org/apache/ibatis/builder/MapperConfig.xml";
//根据配置文件获取字符流
final Reader reader = Resources.getResourceAsReader(resource);
//根据字符流构建SqlSessionFactory
SqlSessionFactory sqlMapper = new SqlSessionFactoryBuilder().build(reader);
//获取全局核心配置类
Configuration configuration = new Configuration(sqlMapper.getConfiguration().getEnvironment());
//为全局配置添加需要的Mapper接口
configuration.addMapper(AuthorMapperWithAnnotation.class);
//创建SQL会话工厂
SqlSessionFactory sqlMapperWithAnnotation = new DefaultSqlSessionFactory(configuration);
//获取SQL会话
SqlSession sqlSession = sqlMapperWithAnnotation.openSession();
//从会话中获取绑定好的mapper接口信息
AuthorMapperWithAnnotation mapper = sqlSession.getMapper(AuthorMapperWithAnnotation.class);
//执行mapper接口的实现方法
//执行插入会话
Author expected = new Author(500, "wolf_love666:\"test\"", "******", "[email protected]", "Something...", null);
mapper.insertAuthorWithPlaceholder(expected);
//期待返回正确的数据
assertEquals(500,expected.getId());
如果你细心的话,就会发现与上面的查询我们这里只更改了mapper接口的方法,因为本节主要是讲该插入的源码。
/**
* @author liuxiaocheng
* @create 2020/3/28 9:43 上午
*/
public interface AuthorMapperWithAnnotation {
// TODO: 2020/3/28 by wolf_love666 for study source code
@InsertProvider(type =AuthorProvider.class,method = "insertAuthorWithPlaceholder")
void insertAuthorWithPlaceholder(Author author);
class AuthorProvider{
// 插入带有占位符预编译的会话SQL
public String insertAuthorWithPlaceholder(Author author){
return new SQL(){{
INSERT_INTO("Author").VALUES("id,username,password,email,bio","#{id},#{username},#{password},#{email},#{bio}");
}}.toString();
}
}
}
通常意义上我们的服务端开发已经结束了,接下来只需要去数据库看下数据是否正确就OK了,而今天我们讲的内容是需要看下mybatis框架是如何执行插入的。
MapperProxy(根据动态代理执行目标mapper接口)
MapperMethod(根据@Insert找到对应的Update方法、根据方法签名确定返回参数)
ParamNameResolver(根据args入参解析属性入参,获取对应的动态值)
/**
* Mapper接口代理--真正的mapper执行类
*/
public class MapperProxy<T> implements InvocationHandler, Serializable {
...省略本次无关内容...
//mapper接口的执行
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
//object类直接执行
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
//缓存的执行器执行
} else {
return cachedInvoker(proxy, method, args).invoke(proxy, method, args, sqlSession);
}
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
//缓存的执行器
private MapperMethodInvoker cachedInvoker(Object proxy, Method method, Object[] args) throws Throwable {
try {
return methodCache.computeIfAbsent(method, m -> {
if (m.isDefault()) {
try {
//jdk8和jdk9的默认方法执行
if (privateLookupInMethod == null) {
return new DefaultMethodInvoker(getMethodHandleJava8(method));
} else {
return new DefaultMethodInvoker(getMethodHandleJava9(method));
}
} catch (IllegalAccessException | InstantiationException | InvocationTargetException
| NoSuchMethodException e) {
throw new RuntimeException(e);
}
} else {
//返回声明的方法执行器
return new PlainMethodInvoker(new MapperMethod(mapperInterface, method, sqlSession.getConfiguration()));
}
});
} catch (RuntimeException re) {
Throwable cause = re.getCause();
throw cause == null ? re : cause;
}
}
//Java9获取方法处理器
private MethodHandle getMethodHandleJava9(Method method)
throws NoSuchMethodException, IllegalAccessException, InvocationTargetException {
final Class<?> declaringClass = method.getDeclaringClass();
return ((Lookup) privateLookupInMethod.invoke(null, declaringClass, MethodHandles.lookup())).findSpecial(
declaringClass, method.getName(), MethodType.methodType(method.getReturnType(), method.getParameterTypes()),
declaringClass);
}
//Java8获取方法处理器
private MethodHandle getMethodHandleJava8(Method method)
throws IllegalAccessException, InstantiationException, InvocationTargetException {
final Class<?> declaringClass = method.getDeclaringClass();
return lookupConstructor.newInstance(declaringClass, ALLOWED_MODES).unreflectSpecial(method, declaringClass);
}
//Mapper方法执行器接口
interface MapperMethodInvoker {
Object invoke(Object proxy, Method method, Object[] args, SqlSession sqlSession) throws Throwable;
}
...省略本次无关内容...
}
/**
* Mapper的方法 add by wolf_love666
*/
public class MapperMethod {
//命令
private final SqlCommand command;
//方法签名
private final MethodSignature method;
//映射的接口和方法和全局配置
public MapperMethod(Class<?> mapperInterface, Method method, Configuration config) {
this.command = new SqlCommand(config, mapperInterface, method);
this.method = new MethodSignature(config, mapperInterface, method);
}
//执行sqlSession和参数
public Object execute(SqlSession sqlSession, Object[] args) {
Object result;
switch (command.getType()) {
...省略本次无关内容...
//插入
case INSERT: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.insert(command.getName(), param));
break;
}
//更新
case UPDATE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.update(command.getName(), param));
break;
}
//删除
case DELETE: {
Object param = method.convertArgsToSqlCommandParam(args);
result = rowCountResult(sqlSession.delete(command.getName(), param));
break;
}
...省略本次无关内容...
default:
throw new BindingException("Unknown execution method for: " + command.getName());
}
if (result == null && method.getReturnType().isPrimitive() && !method.returnsVoid()) {
throw new BindingException("Mapper method '" + command.getName()
+ " attempted to return null from a method with a primitive return type (" + method.getReturnType() + ").");
}
return result;
}
//行数结果
private Object rowCountResult(int rowCount) {
final Object result;
//无返回值
if (method.returnsVoid()) {
result = null;
//int返回类型
} else if (Integer.class.equals(method.getReturnType()) || Integer.TYPE.equals(method.getReturnType())) {
result = rowCount;
//long返回类型
} else if (Long.class.equals(method.getReturnType()) || Long.TYPE.equals(method.getReturnType())) {
result = (long)rowCount;
//boolean返回类型
} else if (Boolean.class.equals(method.getReturnType()) || Boolean.TYPE.equals(method.getReturnType())) {
result = rowCount > 0;
} else {
//其他不支持
throw new BindingException("Mapper method '" + command.getName() + "' has an unsupported return type: " + method.getReturnType());
}
return result;
}
}
/**
* 参数名字解析器 add by wolf_love666
*/
public class ParamNameResolver {
public static final String GENERIC_NAME_PREFIX = "param";
...省略本次无关内容...
/**
*
返回一个没有名称的非特殊参数。 使用命名规则来命名多个参数。 除了默认名称外,此方法还添加了通用名称(param1,param2,* ...)。
*/
public Object getNamedParams(Object[] args) {
//获取对象
final int paramCount = names.size();
if (args == null || paramCount == 0) {
return null;
} else if (!hasParamAnnotation && paramCount == 1) {
return args[names.firstKey()];
} else {
final Map<String, Object> param = new ParamMap<>();
int i = 0;
for (Map.Entry<Integer, String> entry : names.entrySet()) {
param.put(entry.getValue(), args[entry.getKey()]);
//添加通用的参数名字
final String genericParamName = GENERIC_NAME_PREFIX + (i + 1);
// 确保带有@Param注解参数的不被重写
if (!names.containsValue(genericParamName)) {
param.put(genericParamName, args[entry.getKey()]);
}
i++;
}
return param;
}
}
}
public class DefaultSqlSession implements SqlSession {
//全局配置
private final Configuration configuration;
//执行器
private final Executor executor;
//是否自动提交
private final boolean autoCommit;
//是否脏数据
private boolean dirty;
//游标结果集
private List<Cursor<?>> cursorList;
//构造函数
public DefaultSqlSession(Configuration configuration, Executor executor, boolean autoCommit) {
this.configuration = configuration;
this.executor = executor;
this.dirty = false;
this.autoCommit = autoCommit;
}
//构造函数
public DefaultSqlSession(Configuration configuration, Executor executor) {
this(configuration, executor, false);
}
...省略本次无关内容(上一节的查询方法函数)...
//插入会话
@Override
public int insert(String statement) {
return insert(statement, null);
}
//插入会话
@Override
public int insert(String statement, Object parameter) {
return update(statement, parameter);
}
//更新会话
@Override
public int update(String statement) {
return update(statement, null);
}
//更新会话
@Override
public int update(String statement, Object parameter) {
try {
dirty = true;
MappedStatement ms = configuration.getMappedStatement(statement);
return executor.update(ms, wrapCollection(parameter));
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error updating database. Cause: " + e, e);
} finally {
ErrorContext.instance().reset();
}
}
//删除会话
@Override
public int delete(String statement) {
return update(statement, null);
}
//删除会话
@Override
public int delete(String statement, Object parameter) {
return update(statement, parameter);
}
...省略本次无关内容(提交刷新回滚)...
//封装集合
private Object wrapCollection(final Object object) {
if (object instanceof Collection) {
StrictMap<Object> map = new StrictMap<>();
map.put("collection", object);
if (object instanceof List) {
map.put("list", object);
}
return map;
} else if (object != null && object.getClass().isArray()) {
StrictMap<Object> map = new StrictMap<>();
map.put("array", object);
return map;
}
return object;
}
//严格map
public static class StrictMap<V> extends HashMap<String, V> {
private static final long serialVersionUID = -5741767162221585340L;
@Override
public V get(Object key) {
if (!super.containsKey(key)) {
throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + this.keySet());
}
return super.get(key);
}
}
}
/**
*全局配置类 add by wolf_love666
*/
public class Configuration {
...省略本次无关内容...
//获取映射的会话根据会话ID
public MappedStatement getMappedStatement(String id) {
return this.getMappedStatement(id, true);
}
//获取映射的会话根据会话ID
public MappedStatement getMappedStatement(String id, boolean validateIncompleteStatements) {
//是否需要验证不匹配的会话
if (validateIncompleteStatements) {
//构建所有会话验证
buildAllStatements();
}
//获取映射的会话根据会话ID
return mappedStatements.get(id);
}
/*
* 解析缓存中所有未处理的语句节点。建议一旦添加了所有映射器,便调用此方法,因为它提供了快速失败语句验证
*/
protected void buildAllStatements() {
parsePendingResultMaps();
if (!incompleteCacheRefs.isEmpty()) {
synchronized (incompleteCacheRefs) {
incompleteCacheRefs.removeIf(x -> x.resolveCacheRef() != null);
}
}
if (!incompleteStatements.isEmpty()) {
synchronized (incompleteStatements) {
incompleteStatements.removeIf(x -> {
x.parseStatementNode();
return true;
});
}
}
if (!incompleteMethods.isEmpty()) {
synchronized (incompleteMethods) {
incompleteMethods.removeIf(x -> {
x.resolve();
return true;
});
}
}
}
//解析等待的结果map集
private void parsePendingResultMaps() {
if (incompleteResultMaps.isEmpty()) {
return;
}
synchronized (incompleteResultMaps) {
boolean resolved;
IncompleteElementException ex = null;
do {
resolved = false;
Iterator<ResultMapResolver> iterator = incompleteResultMaps.iterator();
while (iterator.hasNext()) {
try {
iterator.next().resolve();
iterator.remove();
resolved = true;
} catch (IncompleteElementException e) {
ex = e;
}
}
} while (resolved);
if (!incompleteResultMaps.isEmpty() && ex != null) {
// At least one result map is unresolvable.
throw ex;
}
}
}
...省略本次无关内容...
}
//严格的map内部实现类
protected static class StrictMap<V> extends HashMap<String, V> {
...省略本次无关内容...
//获取全局配置的属性对应的值
@Override
public V get(Object key) {
V value = super.get(key);
if (value == null) {
throw new IllegalArgumentException(name + " does not contain value for " + key);
}
if (value instanceof Ambiguity) {
throw new IllegalArgumentException(((Ambiguity) value).getSubject() + " is ambiguous in " + name
+ " (try using the full name including the namespace, or rename one of the entries)");
}
return value;
}
//内部语义不明的类
protected static class Ambiguity {
final private String subject;
public Ambiguity(String subject) {
this.subject = subject;
}
public String getSubject() {
return subject;
}
}
private String getShortName(String key) {
final String[] keyParts = key.split("\\.");
return keyParts[keyParts.length - 1];
}}
public class CachingExecutor implements Executor {
//代表执行器
private final Executor delegate;
//事务缓存管理
private final TransactionalCacheManager tcm = new TransactionalCacheManager();
//初始化构造器,执行器就是本身。
public CachingExecutor(Executor delegate) {
this.delegate = delegate;
delegate.setExecutorWrapper(this);
}
//获取执行器的事务
@Override
public Transaction getTransaction() {
return delegate.getTransaction();
}
//关闭前强制是否回滚或者提交,最后执行器关闭
@Override
public void close(boolean forceRollback) {
try {
//issues #499, #524 and #573
if (forceRollback) {
tcm.rollback();
} else {
tcm.commit();
}
} finally {
delegate.close(forceRollback);
}
}
//是否执行器被关闭
@Override
public boolean isClosed() {
return delegate.isClosed();
}
//如果有必要刷新缓存,执行器更新会话操作
@Override
public int update(MappedStatement ms, Object parameterObject) throws SQLException {
flushCacheIfRequired(ms);
return delegate.update(ms, parameterObject);
}
...省略本次无关内容(刷新,提交回滚等操作)...
//确保没有外来参数的缓存 否则不支持,比如字段有自己添加的
private void ensureNoOutParams(MappedStatement ms, BoundSql boundSql) {
if (ms.getStatementType() == StatementType.CALLABLE) {
for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
if (parameterMapping.getMode() != ParameterMode.IN) {
throw new ExecutorException("Caching stored procedures with OUT params is not supported. Please configure useCache=false in " + ms.getId() + " statement.");
}
}
}
}
//创建缓存key
@Override
public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {
return delegate.createCacheKey(ms, parameterObject, rowBounds, boundSql);
}
//是否缓存
@Override
public boolean isCached(MappedStatement ms, CacheKey key) {
return delegate.isCached(ms, key);
}
//延迟加载
@Override
public void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType) {
delegate.deferLoad(ms, resultObject, property, key, targetType);
}
//清除本地缓存
@Override
public void clearLocalCache() {
delegate.clearLocalCache();
}
//如果有必要 刷新缓存 事务缓存管理清空缓存
private void flushCacheIfRequired(MappedStatement ms) {
Cache cache = ms.getCache();
if (cache != null && ms.isFlushCacheRequired()) {
tcm.clear(cache);
}
}
//设置执行器包装器,这个方法应该从来不会被调用
@Override
public void setExecutorWrapper(Executor executor) {
throw new UnsupportedOperationException("This method should not be called");
}
}
public final class MappedStatement {
//资源
private String resource;
//全局配置
private Configuration configuration;
//id
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;
//sql命令类型
private SqlCommandType sqlCommandType;
//是否生成主键
private KeyGenerator keyGenerator;
//key属性集合
private String[] keyProperties;
//key列集合
private String[] keyColumns;
//是否有嵌套结果集合
private boolean hasNestedResultMaps;
//数据库ID
private String databaseId;
//会话日志
private Log statementLog;
//语言驱动
private LanguageDriver lang;
//结果集
private String[] resultSets;
//映射会话
MappedStatement() {
// constructor disabled
}
//内部构建类
public static class Builder {
//映射会话
private MappedStatement mappedStatement = new MappedStatement();
//构建器
public Builder(Configuration configuration, String id, SqlSource sqlSource, SqlCommandType sqlCommandType) {
mappedStatement.configuration = configuration;
mappedStatement.id = id;
mappedStatement.sqlSource = sqlSource;
mappedStatement.statementType = StatementType.PREPARED;
mappedStatement.resultSetType = ResultSetType.DEFAULT;
mappedStatement.parameterMap = new ParameterMap.Builder(configuration, "defaultParameterMap", null, new ArrayList<>()).build();
mappedStatement.resultMaps = new ArrayList<>();
mappedStatement.sqlCommandType = sqlCommandType;
//Jdbc3KeyGenerator是生成key的主要实现
mappedStatement.keyGenerator = configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType) ? Jdbc3KeyGenerator.INSTANCE : NoKeyGenerator.INSTANCE;
String logId = id;
if (configuration.getLogPrefix() != null) {
logId = configuration.getLogPrefix() + id;
}
mappedStatement.statementLog = LogFactory.getLog(logId);
//获取默认的脚本语言实例
mappedStatement.lang = configuration.getDefaultScriptingLanguageInstance();
}
//映射资源
public Builder resource(String resource) {
mappedStatement.resource = resource;
return this;
}
//映射ID
public String id() {
return mappedStatement.id;
}
//参数映射
public Builder parameterMap(ParameterMap parameterMap) {
mappedStatement.parameterMap = parameterMap;
return this;
}
//结果集
public Builder resultMaps(List<ResultMap> resultMaps) {
mappedStatement.resultMaps = resultMaps;
for (ResultMap resultMap : resultMaps) {
mappedStatement.hasNestedResultMaps = mappedStatement.hasNestedResultMaps || resultMap.hasNestedResultMaps();
}
return this;
}
//拉取数量
public Builder fetchSize(Integer fetchSize) {
mappedStatement.fetchSize = fetchSize;
return this;
}
//超时时间
public Builder timeout(Integer timeout) {
mappedStatement.timeout = timeout;
return this;
}
//会话类型
public Builder statementType(StatementType statementType) {
mappedStatement.statementType = statementType;
return this;
}
//结果集类型
public Builder resultSetType(ResultSetType resultSetType) {
mappedStatement.resultSetType = resultSetType == null ? ResultSetType.DEFAULT : resultSetType;
return this;
}
//缓存
public Builder cache(Cache cache) {
mappedStatement.cache = cache;
return this;
}
//是否有必要刷新缓存
public Builder flushCacheRequired(boolean flushCacheRequired) {
mappedStatement.flushCacheRequired = flushCacheRequired;
return this;
}
//是否使用缓存
public Builder useCache(boolean useCache) {
mappedStatement.useCache = useCache;
return this;
}
//是否结果有序
public Builder resultOrdered(boolean resultOrdered) {
mappedStatement.resultOrdered = resultOrdered;
return this;
}
//是否生成主键
public Builder keyGenerator(KeyGenerator keyGenerator) {
mappedStatement.keyGenerator = keyGenerator;
return this;
}
//key属性
public Builder keyProperty(String keyProperty) {
mappedStatement.keyProperties = delimitedStringToArray(keyProperty);
return this;
}
//key列
public Builder keyColumn(String keyColumn) {
mappedStatement.keyColumns = delimitedStringToArray(keyColumn);
return this;
}
//数据库ID
public Builder databaseId(String databaseId) {
mappedStatement.databaseId = databaseId;
return this;
}
//语言驱动
public Builder lang(LanguageDriver driver) {
mappedStatement.lang = driver;
return this;
}
//结果集
public Builder resultSets(String resultSet) {
mappedStatement.resultSets = delimitedStringToArray(resultSet);
return this;
}
/**
* 不再建议使用
* @deprecated Use {@link #resultSets}
*/
@Deprecated
public Builder resulSets(String resultSet) {
mappedStatement.resultSets = delimitedStringToArray(resultSet);
return this;
}
//构建返回会话
public MappedStatement build() {
assert mappedStatement.configuration != null;
assert mappedStatement.id != null;
assert mappedStatement.sqlSource != null;
assert mappedStatement.lang != null;
mappedStatement.resultMaps = Collections.unmodifiableList(mappedStatement.resultMaps);
return mappedStatement;
}
}
//属性的get方法,没有set防止外部破坏内部构建
public KeyGenerator getKeyGenerator() {
return keyGenerator;
}
public SqlCommandType getSqlCommandType() {
return sqlCommandType;
}
public String getResource() {
return resource;
}
public Configuration getConfiguration() {
return configuration;
}
public String getId() {
return id;
}
public boolean hasNestedResultMaps() {
return hasNestedResultMaps;
}
public Integer getFetchSize() {
return fetchSize;
}
public Integer getTimeout() {
return timeout;
}
public StatementType getStatementType() {
return statementType;
}
public ResultSetType getResultSetType() {
return resultSetType;
}
public SqlSource getSqlSource() {
return sqlSource;
}
public ParameterMap getParameterMap() {
return parameterMap;
}
public List<ResultMap> getResultMaps() {
return resultMaps;
}
public Cache getCache() {
return cache;
}
public boolean isFlushCacheRequired() {
return flushCacheRequired;
}
public boolean isUseCache() {
return useCache;
}
public boolean isResultOrdered() {
return resultOrdered;
}
public String getDatabaseId() {
return databaseId;
}
public String[] getKeyProperties() {
return keyProperties;
}
public String[] getKeyColumns() {
return keyColumns;
}
public Log getStatementLog() {
return statementLog;
}
public LanguageDriver getLang() {
return lang;
}
public String[] getResultSets() {
return resultSets;
}
/**
* 不建议使用
* @deprecated Use {@link #getResultSets()}
*/
@Deprecated
public String[] getResulSets() {
return resultSets;
}
public BoundSql getBoundSql(Object parameterObject) {
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;
}
//根据逗号分割返回数组
private static String[] delimitedStringToArray(String in) {
if (in == null || in.trim().length() == 0) {
return null;
} else {
return in.split(",");
}
}
}
/**
* 在已经执行一些动态内容之后,从{@link SqlSource} 获取实际的SQL。
* SQL可能有占位符,并且参数映射有序 对于每个参数另外的信息(至少是从输入的对象读取值)
* 可能也有另外的参数通过动态语言创建 比如循环或者绑定
*/
public class BoundSql {
//sql
private final String sql;
//参数映射
private final List<ParameterMapping> parameterMappings;
//参数对象
private final Object parameterObject;
//附加参数
private final Map<String, Object> additionalParameters;
//元参数
private final MetaObject metaParameters;
//绑定SQL构造器
public BoundSql(Configuration configuration, String sql, List<ParameterMapping> parameterMappings, Object parameterObject) {
this.sql = sql;
this.parameterMappings = parameterMappings;
this.parameterObject = parameterObject;
this.additionalParameters = new HashMap<>();
this.metaParameters = configuration.newMetaObject(additionalParameters);
}
//获取SQL
public String getSql() {
return sql;
}
//获取参数映射
public List<ParameterMapping> getParameterMappings() {
return parameterMappings;
}
//获取参数对象
public Object getParameterObject() {
return parameterObject;
}
//是否有附加参数
public boolean hasAdditionalParameter(String name) {
String paramName = new PropertyTokenizer(name).getName();
return additionalParameters.containsKey(paramName);
}
//设置附加参数--存放元参数信息
public void setAdditionalParameter(String name, Object value) {
metaParameters.setValue(name, value);
}
//获取附加参数
public Object getAdditionalParameter(String name) {
return metaParameters.getValue(name);
}
}
public abstract class BaseExecutor implements Executor {
//日志
private static final Log log = LogFactory.getLog(BaseExecutor.class);
//事务
protected Transaction transaction;
//执行器包装器
protected Executor wrapper;
//并发队列,延迟加载
protected ConcurrentLinkedQueue<DeferredLoad> deferredLoads;
//永久的本地缓存
protected PerpetualCache localCache;
//永久的本地外放参数缓存
protected PerpetualCache localOutputParameterCache;
//配置对象--全局很重要
protected Configuration configuration;
//查询栈
protected int queryStack;
//是否关闭
private boolean closed;
//根据configuration和事务来初始化构造器
protected BaseExecutor(Configuration configuration, Transaction transaction) {
this.transaction = transaction;
this.deferredLoads = new ConcurrentLinkedQueue<>();
this.localCache = new PerpetualCache("LocalCache");
this.localOutputParameterCache = new PerpetualCache("LocalOutputParameterCache");
this.closed = false;
this.configuration = configuration;
this.wrapper = this;
}
//获取事务,如果关闭了则直接抛出异常 执行器已经被关闭
@Override
public Transaction getTransaction() {
if (closed) {
throw new ExecutorException("Executor was closed.");
}
return transaction;
}
//关闭 是否回滚
@Override
public void close(boolean forceRollback) {
try {
try {
rollback(forceRollback);
} finally {
if (transaction != null) {
transaction.close();
}
}
} catch (SQLException e) {
// Ignore. There's nothing that can be done at this point.
log.warn("Unexpected exception on closing transaction. Cause: " + e);
} finally {
transaction = null;
deferredLoads = null;
localCache = null;
localOutputParameterCache = null;
closed = true;
}
}
//是否被关闭
@Override
public boolean isClosed() {
return closed;
}
//更新会话操作
@Override
public int update(MappedStatement ms, Object parameter) throws SQLException {
//错误上下文实例获取会话ID
ErrorContext.instance().resource(ms.getResource()).activity("executing an update").object(ms.getId());
//如果关闭抛出异常
if (closed) {
throw new ExecutorException("Executor was closed.");
}
//清除本地缓存
clearLocalCache();
//更新会话操作
return doUpdate(ms, parameter);
}
//刷新会话操作 不回滚
@Override
public List<BatchResult> flushStatements() throws SQLException {
return flushStatements(false);
}
//刷新会话操作
public List<BatchResult> flushStatements(boolean isRollBack) throws SQLException {
if (closed) {
throw new ExecutorException("Executor was closed.");
}
//操作刷新会话
return doFlushStatements(isRollBack);
}
//查询会话
@Override
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
BoundSql boundSql = ms.getBoundSql(parameter);
CacheKey key = createCacheKey(ms, parameter, rowBounds, boundSql);
return query(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
//带缓存查询会话
@SuppressWarnings("unchecked")
@Override
public <E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
//错误上下文增加活动记录
ErrorContext.instance().resource(ms.getResource()).activity("executing a query").object(ms.getId());
//是否关闭检查
if (closed) {
throw new ExecutorException("Executor was closed.");
}
//查询栈=0并且要求被刷新缓存的会话操作
if (queryStack == 0 && ms.isFlushCacheRequired()) {
//清除本地缓存
clearLocalCache();
}
//查询栈+1
List<E> list;
try {
queryStack++;
//判断结果处理器是否为空,如果为空从本地缓存获取否则赋值空
list = resultHandler == null ? (List<E>) localCache.getObject(key) : null;
if (list != null) {
//有结果处理器则直接处理缓存外来的参数
handleLocallyCachedOutputParameters(ms, key, parameter, boundSql);
} else {
//没有结果处理器则直接从数据库查
list = queryFromDatabase(ms, parameter, rowBounds, resultHandler, key, boundSql);
}
} finally {
//查询栈-1维护初始0
queryStack--;
}
//如果查询栈=0则延迟加载队列 进行延迟循环加载
if (queryStack == 0) {
for (DeferredLoad deferredLoad : deferredLoads) {
deferredLoad.load();
}
//延迟队列清空
// issue #601
deferredLoads.clear();
//如果配置的本地缓存范围是会话层
if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
//清除本地缓存
// issue #482
clearLocalCache();
}
}
return list;
}
//查询游标集
@Override
public <E> Cursor<E> queryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds) throws SQLException {
BoundSql boundSql = ms.getBoundSql(parameter);
return doQueryCursor(ms, parameter, rowBounds, boundSql);
}
//延迟加载
@Override
public void deferLoad(MappedStatement ms, MetaObject resultObject, String property, CacheKey key, Class<?> targetType) {
if (closed) {
throw new ExecutorException("Executor was closed.");
}
DeferredLoad deferredLoad = new DeferredLoad(resultObject, property, key, localCache, configuration, targetType);
if (deferredLoad.canLoad()) {
deferredLoad.load();
} else {
deferredLoads.add(new DeferredLoad(resultObject, property, key, localCache, configuration, targetType));
}
}
//创建缓存key
@Override
public CacheKey createCacheKey(MappedStatement ms, Object parameterObject, RowBounds rowBounds, BoundSql boundSql) {
if (closed) {
throw new ExecutorException("Executor was closed.");
}
CacheKey cacheKey = new CacheKey();
cacheKey.update(ms.getId());
cacheKey.update(rowBounds.getOffset());
cacheKey.update(rowBounds.getLimit());
cacheKey.update(boundSql.getSql());
List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
//之前我们看到的类型处理器注册 在type包下的 可以通过会话的配置获取
TypeHandlerRegistry typeHandlerRegistry = ms.getConfiguration().getTypeHandlerRegistry();
// mimic DefaultParameterHandler logic
for (ParameterMapping parameterMapping : parameterMappings) {
if (parameterMapping.getMode() != ParameterMode.OUT) {
Object value;
//参数映射获取属性
String propertyName = parameterMapping.getProperty();
if (boundSql.hasAdditionalParameter(propertyName)) {
value = boundSql.getAdditionalParameter(propertyName);
} else if (parameterObject == null) {
value = null;
} else if (typeHandlerRegistry.hasTypeHandler(parameterObject.getClass())) {
value = parameterObject;
} else {
MetaObject metaObject = configuration.newMetaObject(parameterObject);
value = metaObject.getValue(propertyName);
}
cacheKey.update(value);
}
}
//如果configuration获取环境不为空,则缓存更新环境ID
if (configuration.getEnvironment() != null) {
// issue #176
cacheKey.update(configuration.getEnvironment().getId());
}
return cacheKey;
}
//是否被缓存会话
@Override
public boolean isCached(MappedStatement ms, CacheKey key) {
return localCache.getObject(key) != null;
}
//提交如果有必要的话,清除本地缓存,刷新会话,事务提交
@Override
public void commit(boolean required) throws SQLException {
if (closed) {
throw new ExecutorException("Cannot commit, transaction is already closed");
}
clearLocalCache();
flushStatements();
if (required) {
transaction.commit();
}
}
//回滚,如果有必要回滚事务
@Override
public void rollback(boolean required) throws SQLException {
if (!closed) {
try {
clearLocalCache();
flushStatements(true);
} finally {
if (required) {
transaction.rollback();
}
}
}
}
//清除本地缓存
@Override
public void clearLocalCache() {
if (!closed) {
localCache.clear();
localOutputParameterCache.clear();
}
}
//约定子类实现的操作更新接口
protected abstract int doUpdate(MappedStatement ms, Object parameter)
throws SQLException;
//约定子类操作的刷新会话接口
protected abstract List<BatchResult> doFlushStatements(boolean isRollback)
throws SQLException;
//约定子类操作的查询接口
protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
throws SQLException;
//约定子类操作的查询结果集接口
protected abstract <E> Cursor<E> doQueryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds, BoundSql boundSql)
throws SQLException;
//关闭会话
protected void closeStatement(Statement statement) {
if (statement != null) {
try {
statement.close();
} catch (SQLException e) {
// ignore
}
}
}
/**
* 如果数据库操作访问异常,这个方法被调用报事务异常超时
*/
protected void applyTransactionTimeout(Statement statement) throws SQLException {
StatementUtil.applyTransactionTimeout(statement, statement.getQueryTimeout(), transaction.getTimeout());
}
//处理本地缓存输出参数
private void handleLocallyCachedOutputParameters(MappedStatement ms, CacheKey key, Object parameter, BoundSql boundSql) {
if (ms.getStatementType() == StatementType.CALLABLE) {
final Object cachedParameter = localOutputParameterCache.getObject(key);
if (cachedParameter != null && parameter != null) {
final MetaObject metaCachedParameter = configuration.newMetaObject(cachedParameter);
final MetaObject metaParameter = configuration.newMetaObject(parameter);
for (ParameterMapping parameterMapping : boundSql.getParameterMappings()) {
if (parameterMapping.getMode() != ParameterMode.IN) {
final String parameterName = parameterMapping.getProperty();
final Object cachedValue = metaCachedParameter.getValue(parameterName);
metaParameter.setValue(parameterName, cachedValue);
}
}
}
}
}
//从数据库查询
private <E> List<E> queryFromDatabase(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql) throws SQLException {
List<E> list;
//本地缓存存储
localCache.putObject(key, EXECUTION_PLACEHOLDER);
try {
//执行查询
list = doQuery(ms, parameter, rowBounds, resultHandler, boundSql);
} finally {
//本地缓存移除
localCache.removeObject(key);
}
//本地缓存存储新的
localCache.putObject(key, list);
//如果会话类型是回调,则本地外放参数缓存存放
if (ms.getStatementType() == StatementType.CALLABLE) {
localOutputParameterCache.putObject(key, parameter);
}
return list;
}
//获取事务链接
protected Connection getConnection(Log statementLog) throws SQLException {
Connection connection = transaction.getConnection();
if (statementLog.isDebugEnabled()) {
return ConnectionLogger.newInstance(connection, statementLog, queryStack);
} else {
return connection;
}
}
//设置执行器包装器
@Override
public void setExecutorWrapper(Executor wrapper) {
this.wrapper = wrapper;
}
//延迟加载类
private static class DeferredLoad {
//元对象
private final MetaObject resultObject;
//属性
private final String property;
//目标类型
private final Class<?> targetType;
//缓存key
private final CacheKey key;
//本地缓存
private final PerpetualCache localCache;
//对象工厂
private final ObjectFactory objectFactory;
//结果提取器
private final ResultExtractor resultExtractor;
// issue #781
//延迟加载构造器
public DeferredLoad(MetaObject resultObject,
String property,
CacheKey key,
PerpetualCache localCache,
Configuration configuration,
Class<?> targetType) {
this.resultObject = resultObject;
this.property = property;
this.key = key;
this.localCache = localCache;
this.objectFactory = configuration.getObjectFactory();
this.resultExtractor = new ResultExtractor(configuration, objectFactory);
this.targetType = targetType;
}
//是否可以被加载
public boolean canLoad() {
return localCache.getObject(key) != null && localCache.getObject(key) != EXECUTION_PLACEHOLDER;
}
//加载
public void load() {
@SuppressWarnings("unchecked")
// we suppose we get back a List
List<Object> list = (List<Object>) localCache.getObject(key);
Object value = resultExtractor.extractObjectFromList(list, targetType);
resultObject.setValue(property, value);
}
}
}
public class SimpleExecutor extends BaseExecutor {
//构造执行器
public SimpleExecutor(Configuration configuration, Transaction transaction) {
super(configuration, transaction);
}
//执行会话操作
@Override
public int doUpdate(MappedStatement ms, Object parameter) throws SQLException {
Statement stmt = null;
try {
//会话获取全局配置
Configuration configuration = ms.getConfiguration();
//配置创建会话处理器
StatementHandler handler = configuration.newStatementHandler(this, ms, parameter, RowBounds.DEFAULT, null, null);
//预会话
stmt = prepareStatement(handler, ms.getStatementLog());
//处理会话
return handler.update(stmt);
} finally {
//关闭会话
closeStatement(stmt);
}
}
//执行查询
@Override
public <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) throws SQLException {
Statement stmt = null;
try {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, resultHandler, boundSql);
stmt = prepareStatement(handler, ms.getStatementLog());
return handler.query(stmt, resultHandler);
} finally {
closeStatement(stmt);
}
}
//执行查询游标集
@Override
protected <E> Cursor<E> doQueryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds, BoundSql boundSql) throws SQLException {
Configuration configuration = ms.getConfiguration();
StatementHandler handler = configuration.newStatementHandler(wrapper, ms, parameter, rowBounds, null, boundSql);
Statement stmt = prepareStatement(handler, ms.getStatementLog());
Cursor<E> cursor = handler.queryCursor(stmt);
stmt.closeOnCompletion();
return cursor;
}
//刷新会话
@Override
public List<BatchResult> doFlushStatements(boolean isRollback) {
return Collections.emptyList();
}
//预准备会话
private Statement prepareStatement(StatementHandler handler, Log statementLog) throws SQLException {
Statement stmt;
Connection connection = getConnection(statementLog);
stmt = handler.prepare(connection, transaction.getTimeout());
handler.parameterize(stmt);
return stmt;
}
}
public class RoutingStatementHandler implements StatementHandler {
//会话处理器
private final StatementHandler delegate;
public RoutingStatementHandler(Executor executor, MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
switch (ms.getStatementType()) {
//会话操作
case STATEMENT:
delegate = new SimpleStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
//预会话操作
case PREPARED:
delegate = new PreparedStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
case CALLABLE:
//回调会话操作
delegate = new CallableStatementHandler(executor, ms, parameter, rowBounds, resultHandler, boundSql);
break;
default:
throw new ExecutorException("Unknown statement type: " + ms.getStatementType());
}
}
//准备
@Override
public Statement prepare(Connection connection, Integer transactionTimeout) throws SQLException {
return delegate.prepare(connection, transactionTimeout);
}
//参数化
@Override
public void parameterize(Statement statement) throws SQLException {
delegate.parameterize(statement);
}
//执行
@Override
public void batch(Statement statement) throws SQLException {
delegate.batch(statement);
}
//更新
@Override
public int update(Statement statement) throws SQLException {
return delegate.update(statement);
}
//查询
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
return delegate.query(statement, resultHandler);
}
//查询游标
@Override
public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
return delegate.queryCursor(statement);
}
//执行sql
@Override
public BoundSql getBoundSql() {
return delegate.getBoundSql();
}
//获取参数处理器
@Override
public ParameterHandler getParameterHandler() {
return delegate.getParameterHandler();
}
}
public class PreparedStatementHandler extends BaseStatementHandler {
//构造函数
public PreparedStatementHandler(Executor executor, MappedStatement mappedStatement, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql) {
super(executor, mappedStatement, parameter, rowBounds, resultHandler, boundSql);
}
//更新
@Override
public int update(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
int rows = ps.getUpdateCount();
Object parameterObject = boundSql.getParameterObject();
KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
keyGenerator.processAfter(executor, mappedStatement, ps, parameterObject);
return rows;
}
//批量执行
@Override
public void batch(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.addBatch();
}
//查询
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.handleResultSets(ps);
}
//查询游标集
@Override
public <E> Cursor<E> queryCursor(Statement statement) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.handleCursorResultSets(ps);
}
//实例话会话
@Override
protected Statement instantiateStatement(Connection connection) throws SQLException {
String sql = boundSql.getSql();
if (mappedStatement.getKeyGenerator() instanceof Jdbc3KeyGenerator) {
String[] keyColumnNames = mappedStatement.getKeyColumns();
if (keyColumnNames == null) {
return connection.prepareStatement(sql, PreparedStatement.RETURN_GENERATED_KEYS);
} else {
return connection.prepareStatement(sql, keyColumnNames);
}
} else if (mappedStatement.getResultSetType() == ResultSetType.DEFAULT) {
return connection.prepareStatement(sql);
} else {
return connection.prepareStatement(sql, mappedStatement.getResultSetType().getValue(), ResultSet.CONCUR_READ_ONLY);
}
}
//参数化会话
@Override
public void parameterize(Statement statement) throws SQLException {
parameterHandler.setParameters((PreparedStatement) statement);
}
}
public class DefaultResultSetHandler implements ResultSetHandler {
//延迟对象
private static final Object DEFERRED = new Object();
//执行器
private final Executor executor;
//全局配置
private final Configuration configuration;
//映射会话
private final MappedStatement mappedStatement;
//行数据
private final RowBounds rowBounds;
//参数处理器
private final ParameterHandler parameterHandler;
//结果处理器
private final ResultHandler<?> resultHandler;
//执行SQL
private final BoundSql boundSql;
//类型处理器注册器
private final TypeHandlerRegistry typeHandlerRegistry;
//对象工厂
private final ObjectFactory objectFactory;
//反射工厂
private final ReflectorFactory reflectorFactory;
//嵌套结果映射
// nested resultmaps
private final Map<CacheKey, Object> nestedResultObjects = new HashMap<>();
//原型对象
private final Map<String, Object> ancestorObjects = new HashMap<>();
//先前行值
private Object previousRowValue;
//多个结果集
// multiple resultsets
private final Map<String, ResultMapping> nextResultMaps = new HashMap<>();
//等待的关系
private final Map<CacheKey, List<PendingRelation>> pendingRelations = new HashMap<>();
//自动映射的缓存
// Cached Automappings
private final Map<String, List<UnMappedColumnAutoMapping>> autoMappingsCache = new HashMap<>();
//暂时标记 使用构造器映射(使用属性减少内存使用)
// temporary marking flag that indicate using constructor mapping (use field to reduce memory usage)
private boolean useConstructorMappings;
//等待关系
private static class PendingRelation {
public MetaObject metaObject;
public ResultMapping propertyMapping;
}
//未映射的列自动映射 内部类
private static class UnMappedColumnAutoMapping {
private final String column;
private final String property;
private final TypeHandler<?> typeHandler;
private final boolean primitive;
public UnMappedColumnAutoMapping(String column, String property, TypeHandler<?> typeHandler, boolean primitive) {
this.column = column;
this.property = property;
this.typeHandler = typeHandler;
this.primitive = primitive;
}
}
//有参构造函数
public DefaultResultSetHandler(Executor executor, MappedStatement mappedStatement, ParameterHandler parameterHandler, ResultHandler<?> resultHandler, BoundSql boundSql,
RowBounds rowBounds) {
this.executor = executor;
this.configuration = mappedStatement.getConfiguration();
this.mappedStatement = mappedStatement;
this.rowBounds = rowBounds;
this.parameterHandler = parameterHandler;
this.boundSql = boundSql;
this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
this.objectFactory = configuration.getObjectFactory();
this.reflectorFactory = configuration.getReflectorFactory();
this.resultHandler = resultHandler;
}
//处理输出参数
// HANDLE OUTPUT PARAMETER
//
@Override
public void handleOutputParameters(CallableStatement cs) throws SQLException {
final Object parameterObject = parameterHandler.getParameterObject();
final MetaObject metaParam = configuration.newMetaObject(parameterObject);
final List<ParameterMapping> parameterMappings = boundSql.getParameterMappings();
for (int i = 0; i < parameterMappings.size(); i++) {
final ParameterMapping parameterMapping = parameterMappings.get(i);
if (parameterMapping.getMode() == ParameterMode.OUT || parameterMapping.getMode() == ParameterMode.INOUT) {
if (ResultSet.class.equals(parameterMapping.getJavaType())) {
handleRefCursorOutputParameter((ResultSet) cs.getObject(i + 1), parameterMapping, metaParam);
} else {
final TypeHandler<?> typeHandler = parameterMapping.getTypeHandler();
metaParam.setValue(parameterMapping.getProperty(), typeHandler.getResult(cs, i + 1));
}
}
}
}
//处理游标输出参数
private void handleRefCursorOutputParameter(ResultSet rs, ParameterMapping parameterMapping, MetaObject metaParam) throws SQLException {
if (rs == null) {
return;
}
try {
final String resultMapId = parameterMapping.getResultMapId();
final ResultMap resultMap = configuration.getResultMap(resultMapId);
final ResultSetWrapper rsw = new ResultSetWrapper(rs, configuration);
if (this.resultHandler == null) {
final DefaultResultHandler resultHandler = new DefaultResultHandler(objectFactory);
handleRowValues(rsw, resultMap, resultHandler, new RowBounds(), null);
metaParam.setValue(parameterMapping.getProperty(), resultHandler.getResultList());
} else {
handleRowValues(rsw, resultMap, resultHandler, new RowBounds(), null);
}
} finally {
// issue #228 (close resultsets)
closeResultSet(rs);
}
}
//处理结果集
// HANDLE RESULT SETS
//
@Override
public List<Object> handleResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling results").object(mappedStatement.getId());
final List<Object> multipleResults = new ArrayList<>();
int resultSetCount = 0;
ResultSetWrapper rsw = getFirstResultSet(stmt);
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
int resultMapCount = resultMaps.size();
validateResultMapsCount(rsw, resultMapCount);
while (rsw != null && resultMapCount > resultSetCount) {
ResultMap resultMap = resultMaps.get(resultSetCount);
handleResultSet(rsw, resultMap, multipleResults, null);
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
String[] resultSets = mappedStatement.getResultSets();
if (resultSets != null) {
while (rsw != null && resultSetCount < resultSets.length) {
ResultMapping parentMapping = nextResultMaps.get(resultSets[resultSetCount]);
if (parentMapping != null) {
String nestedResultMapId = parentMapping.getNestedResultMapId();
ResultMap resultMap = configuration.getResultMap(nestedResultMapId);
handleResultSet(rsw, resultMap, null, parentMapping);
}
rsw = getNextResultSet(stmt);
cleanUpAfterHandlingResultSet();
resultSetCount++;
}
}
return collapseSingleResultList(multipleResults);
}
//处理游标结果集
@Override
public <E> Cursor<E> handleCursorResultSets(Statement stmt) throws SQLException {
ErrorContext.instance().activity("handling cursor results").object(mappedStatement.getId());
ResultSetWrapper rsw = getFirstResultSet(stmt);
List<ResultMap> resultMaps = mappedStatement.getResultMaps();
int resultMapCount = resultMaps.size();
validateResultMapsCount(rsw, resultMapCount);
if (resultMapCount != 1) {
throw new ExecutorException("Cursor results cannot be mapped to multiple resultMaps");
}
ResultMap resultMap = resultMaps.get(0);
return new DefaultCursor<>(this, resultMap, rsw, rowBounds);
}
//获取首个结果集
private ResultSetWrapper getFirstResultSet(Statement stmt) throws SQLException {
ResultSet rs = stmt.getResultSet();
while (rs == null) {
// move forward to get the first resultset in case the driver
// doesn't return the resultset as the first result (HSQLDB 2.1)
if (stmt.getMoreResults()) {
rs = stmt.getResultSet();
} else {
if (stmt.getUpdateCount() == -1) {
// no more results. Must be no resultset
break;
}
}
}
return rs != null ? new ResultSetWrapper(rs, configuration) : null;
}
//获取下一个结果集
private ResultSetWrapper getNextResultSet(Statement stmt) {
// Making this method tolerant of bad JDBC drivers
try {
if (stmt.getConnection().getMetaData().supportsMultipleResultSets()) {
// Crazy Standard JDBC way of determining if there are more results
if (!(!stmt.getMoreResults() && stmt.getUpdateCount() == -1)) {
ResultSet rs = stmt.getResultSet();
if (rs == null) {
return getNextResultSet(stmt);
} else {
return new ResultSetWrapper(rs, configuration);
}
}
}
} catch (Exception e) {
// Intentionally ignored.
}
return null;
}
//关闭结果集
private void closeResultSet(ResultSet rs) {
try {
if (rs != null) {
rs.close();
}
} catch (SQLException e) {
// ignore
}
}
//嵌套结果对象清空
private void cleanUpAfterHandlingResultSet() {
nestedResultObjects.clear();
}
//校验结果映射数量
private void validateResultMapsCount(ResultSetWrapper rsw, int resultMapCount) {
if (rsw != null && resultMapCount < 1) {
throw new ExecutorException("A query was run and no Result Maps were found for the Mapped Statement '" + mappedStatement.getId()
+ "'. It's likely that neither a Result Type nor a Result Map was specified.");
}
}
//处理结果集
private void handleResultSet(ResultSetWrapper rsw, ResultMap resultMap, List<Object> multipleResults, ResultMapping parentMapping) throws SQLException {
try {
if (parentMapping != null) {
handleRowValues(rsw, resultMap, null, RowBounds.DEFAULT, parentMapping);
} else {
if (resultHandler == null) {
DefaultResultHandler defaultResultHandler = new DefaultResultHandler(objectFactory);
handleRowValues(rsw, resultMap, defaultResultHandler, rowBounds, null);
multipleResults.add(defaultResultHandler.getResultList());
} else {
handleRowValues(rsw, resultMap, resultHandler, rowBounds, null);
}
}
} finally {
// issue #228 (close resultsets)
closeResultSet(rsw.getResultSet());
}
}
//
//处理单个结果集
@SuppressWarnings("unchecked")
private List<Object> collapseSingleResultList(List<Object> multipleResults) {
return multipleResults.size() == 1 ? (List<Object>) multipleResults.get(0) : multipleResults;
}
// 简单的结果集 处理行数据
// HANDLE ROWS FOR SIMPLE RESULTMAP
//
public void handleRowValues(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
if (resultMap.hasNestedResultMaps()) {
ensureNoRowBounds();
checkResultHandler();
handleRowValuesForNestedResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
} else {
handleRowValuesForSimpleResultMap(rsw, resultMap, resultHandler, rowBounds, parentMapping);
}
}
//确保没行数据
private void ensureNoRowBounds() {
if (configuration.isSafeRowBoundsEnabled() && rowBounds != null && (rowBounds.getLimit() < RowBounds.NO_ROW_LIMIT || rowBounds.getOffset() > RowBounds.NO_ROW_OFFSET)) {
throw new ExecutorException("Mapped Statements with nested result mappings cannot be safely constrained by RowBounds. "
+ "Use safeRowBoundsEnabled=false setting to bypass this check.");
}
}
//检查结果处理器
protected void checkResultHandler() {
if (resultHandler != null && configuration.isSafeResultHandlerEnabled() && !mappedStatement.isResultOrdered()) {
throw new ExecutorException("Mapped Statements with nested result mappings cannot be safely used with a custom ResultHandler. "
+ "Use safeResultHandlerEnabled=false setting to bypass this check "
+ "or ensure your statement returns ordered data and set resultOrdered=true on it.");
}
}
//处理简单结果集的行数据值
private void handleRowValuesForSimpleResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping)
throws SQLException {
DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
ResultSet resultSet = rsw.getResultSet();
skipRows(resultSet, rowBounds);
while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
Object rowValue = getRowValue(rsw, discriminatedResultMap, null);
storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
}
//存储对象
private void storeObject(ResultHandler<?> resultHandler, DefaultResultContext<Object> resultContext, Object rowValue, ResultMapping parentMapping, ResultSet rs) throws SQLException {
if (parentMapping != null) {
linkToParents(rs, parentMapping, rowValue);
} else {
callResultHandler(resultHandler, resultContext, rowValue);
}
}
//调用结果处理器
@SuppressWarnings("unchecked" /* because ResultHandler> is always ResultHandler)
private void callResultHandler(ResultHandler<?> resultHandler, DefaultResultContext<Object> resultContext, Object rowValue) {
resultContext.nextResultObject(rowValue);
((ResultHandler<Object>) resultHandler).handleResult(resultContext);
}
//应该执行更多行
private boolean shouldProcessMoreRows(ResultContext<?> context, RowBounds rowBounds) {
return !context.isStopped() && context.getResultCount() < rowBounds.getLimit();
}
//跳过行数据
private void skipRows(ResultSet rs, RowBounds rowBounds) throws SQLException {
if (rs.getType() != ResultSet.TYPE_FORWARD_ONLY) {
if (rowBounds.getOffset() != RowBounds.NO_ROW_OFFSET) {
rs.absolute(rowBounds.getOffset());
}
} else {
for (int i = 0; i < rowBounds.getOffset(); i++) {
if (!rs.next()) {
break;
}
}
}
}
// 获取简单结果集的行数据值
// GET VALUE FROM ROW FOR SIMPLE RESULT MAP
//
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, String columnPrefix) throws SQLException {
final ResultLoaderMap lazyLoader = new ResultLoaderMap();
Object rowValue = createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
final MetaObject metaObject = configuration.newMetaObject(rowValue);
boolean foundValues = this.useConstructorMappings;
if (shouldApplyAutomaticMappings(resultMap, false)) {
foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
}
foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;
foundValues = lazyLoader.size() > 0 || foundValues;
rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
}
return rowValue;
}
//应该自动映射
private boolean shouldApplyAutomaticMappings(ResultMap resultMap, boolean isNested) {
if (resultMap.getAutoMapping() != null) {
return resultMap.getAutoMapping();
} else {
if (isNested) {
return AutoMappingBehavior.FULL == configuration.getAutoMappingBehavior();
} else {
return AutoMappingBehavior.NONE != configuration.getAutoMappingBehavior();
}
}
}
// 属性映射
// PROPERTY MAPPINGS
//
private boolean applyPropertyMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, ResultLoaderMap lazyLoader, String columnPrefix)
throws SQLException {
final List<String> mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix);
boolean foundValues = false;
final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings();
for (ResultMapping propertyMapping : propertyMappings) {
String column = prependPrefix(propertyMapping.getColumn(), columnPrefix);
if (propertyMapping.getNestedResultMapId() != null) {
// the user added a column attribute to a nested result map, ignore it
column = null;
}
if (propertyMapping.isCompositeResult()
|| (column != null && mappedColumnNames.contains(column.toUpperCase(Locale.ENGLISH)))
|| propertyMapping.getResultSet() != null) {
Object value = getPropertyMappingValue(rsw.getResultSet(), metaObject, propertyMapping, lazyLoader, columnPrefix);
// issue #541 make property optional
final String property = propertyMapping.getProperty();
if (property == null) {
continue;
} else if (value == DEFERRED) {
foundValues = true;
continue;
}
if (value != null) {
foundValues = true;
}
if (value != null || (configuration.isCallSettersOnNulls() && !metaObject.getSetterType(property).isPrimitive())) {
// gcode issue #377, call setter on nulls (value is not 'found')
metaObject.setValue(property, value);
}
}
}
return foundValues;
}
// 获取属性映射的值
private Object getPropertyMappingValue(ResultSet rs, MetaObject metaResultObject, ResultMapping propertyMapping, ResultLoaderMap lazyLoader, String columnPrefix)
throws SQLException {
if (propertyMapping.getNestedQueryId() != null) {
return getNestedQueryMappingValue(rs, metaResultObject, propertyMapping, lazyLoader, columnPrefix);
} else if (propertyMapping.getResultSet() != null) {
addPendingChildRelation(rs, metaResultObject, propertyMapping); // TODO is that OK?
return DEFERRED;
} else {
final TypeHandler<?> typeHandler = propertyMapping.getTypeHandler();
final String column = prependPrefix(propertyMapping.getColumn(), columnPrefix);
return typeHandler.getResult(rs, column);
}
}
// 创建自动映射
private List<UnMappedColumnAutoMapping> createAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
final String mapKey = resultMap.getId() + ":" + columnPrefix;
List<UnMappedColumnAutoMapping> autoMapping = autoMappingsCache.get(mapKey);
if (autoMapping == null) {
autoMapping = new ArrayList<>();
final List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
for (String columnName : unmappedColumnNames) {
String propertyName = columnName;
if (columnPrefix != null && !columnPrefix.isEmpty()) {
// When columnPrefix is specified,
// ignore columns without the prefix.
if (columnName.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
propertyName = columnName.substring(columnPrefix.length());
} else {
continue;
}
}
final String property = metaObject.findProperty(propertyName, configuration.isMapUnderscoreToCamelCase());
if (property != null && metaObject.hasSetter(property)) {
if (resultMap.getMappedProperties().contains(property)) {
continue;
}
final Class<?> propertyType = metaObject.getSetterType(property);
if (typeHandlerRegistry.hasTypeHandler(propertyType, rsw.getJdbcType(columnName))) {
final TypeHandler<?> typeHandler = rsw.getTypeHandler(propertyType, columnName);
autoMapping.add(new UnMappedColumnAutoMapping(columnName, property, typeHandler, propertyType.isPrimitive()));
} else {
configuration.getAutoMappingUnknownColumnBehavior()
.doAction(mappedStatement, columnName, property, propertyType);
}
} else {
configuration.getAutoMappingUnknownColumnBehavior()
.doAction(mappedStatement, columnName, (property != null) ? property : propertyName, null);
}
}
autoMappingsCache.put(mapKey, autoMapping);
}
return autoMapping;
}
//是否应用自动映射
private boolean applyAutomaticMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String columnPrefix) throws SQLException {
List<UnMappedColumnAutoMapping> autoMapping = createAutomaticMappings(rsw, resultMap, metaObject, columnPrefix);
boolean foundValues = false;
if (!autoMapping.isEmpty()) {
for (UnMappedColumnAutoMapping mapping : autoMapping) {
final Object value = mapping.typeHandler.getResult(rsw.getResultSet(), mapping.column);
if (value != null) {
foundValues = true;
}
if (value != null || (configuration.isCallSettersOnNulls() && !mapping.primitive)) {
// gcode issue #377, call setter on nulls (value is not 'found')
metaObject.setValue(mapping.property, value);
}
}
}
return foundValues;
}
//多个结果集
// MULTIPLE RESULT SETS
private void linkToParents(ResultSet rs, ResultMapping parentMapping, Object rowValue) throws SQLException {
CacheKey parentKey = createKeyForMultipleResults(rs, parentMapping, parentMapping.getColumn(), parentMapping.getForeignColumn());
List<PendingRelation> parents = pendingRelations.get(parentKey);
if (parents != null) {
for (PendingRelation parent : parents) {
if (parent != null && rowValue != null) {
linkObjects(parent.metaObject, parent.propertyMapping, rowValue);
}
}
}
}
//添加等待子关系
private void addPendingChildRelation(ResultSet rs, MetaObject metaResultObject, ResultMapping parentMapping) throws SQLException {
CacheKey cacheKey = createKeyForMultipleResults(rs, parentMapping, parentMapping.getColumn(), parentMapping.getColumn());
PendingRelation deferLoad = new PendingRelation();
deferLoad.metaObject = metaResultObject;
deferLoad.propertyMapping = parentMapping;
List<PendingRelation> relations = pendingRelations.computeIfAbsent(cacheKey, k -> new ArrayList<>());
// issue #255
relations.add(deferLoad);
ResultMapping previous = nextResultMaps.get(parentMapping.getResultSet());
if (previous == null) {
nextResultMaps.put(parentMapping.getResultSet(), parentMapping);
} else {
if (!previous.equals(parentMapping)) {
throw new ExecutorException("Two different properties are mapped to the same resultSet");
}
}
}
//创建多个结果集的key
private CacheKey createKeyForMultipleResults(ResultSet rs, ResultMapping resultMapping, String names, String columns) throws SQLException {
CacheKey cacheKey = new CacheKey();
cacheKey.update(resultMapping);
if (columns != null && names != null) {
String[] columnsArray = columns.split(",");
String[] namesArray = names.split(",");
for (int i = 0; i < columnsArray.length; i++) {
Object value = rs.getString(columnsArray[i]);
if (value != null) {
cacheKey.update(namesArray[i]);
cacheKey.update(value);
}
}
}
return cacheKey;
}
// 创建结果集
// INSTANTIATION & CONSTRUCTOR MAPPING
//
private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, ResultLoaderMap lazyLoader, String columnPrefix) throws SQLException {
this.useConstructorMappings = false; // reset previous mapping result
final List<Class<?>> constructorArgTypes = new ArrayList<>();
final List<Object> constructorArgs = new ArrayList<>();
Object resultObject = createResultObject(rsw, resultMap, constructorArgTypes, constructorArgs, columnPrefix);
if (resultObject != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
final List<ResultMapping> propertyMappings = resultMap.getPropertyResultMappings();
for (ResultMapping propertyMapping : propertyMappings) {
// issue gcode #109 && issue #149
if (propertyMapping.getNestedQueryId() != null && propertyMapping.isLazy()) {
resultObject = configuration.getProxyFactory().createProxy(resultObject, lazyLoader, configuration, objectFactory, constructorArgTypes, constructorArgs);
break;
}
}
}
this.useConstructorMappings = resultObject != null && !constructorArgTypes.isEmpty(); // set current mapping result
return resultObject;
}
//创建结果对象
private Object createResultObject(ResultSetWrapper rsw, ResultMap resultMap, List<Class<?>> constructorArgTypes, List<Object> constructorArgs, String columnPrefix)
throws SQLException {
final Class<?> resultType = resultMap.getType();
final MetaClass metaType = MetaClass.forClass(resultType, reflectorFactory);
final List<ResultMapping> constructorMappings = resultMap.getConstructorResultMappings();
if (hasTypeHandlerForResultObject(rsw, resultType)) {
return createPrimitiveResultObject(rsw, resultMap, columnPrefix);
} else if (!constructorMappings.isEmpty()) {
return createParameterizedResultObject(rsw, resultType, constructorMappings, constructorArgTypes, constructorArgs, columnPrefix);
} else if (resultType.isInterface() || metaType.hasDefaultConstructor()) {
return objectFactory.create(resultType);
} else if (shouldApplyAutomaticMappings(resultMap, false)) {
return createByConstructorSignature(rsw, resultType, constructorArgTypes, constructorArgs);
}
throw new ExecutorException("Do not know how to create an instance of " + resultType);
}
//创建参数化的结果对象
Object createParameterizedResultObject(ResultSetWrapper rsw, Class<?> resultType, List<ResultMapping> constructorMappings,
List<Class<?>> constructorArgTypes, List<Object> constructorArgs, String columnPrefix) {
boolean foundValues = false;
for (ResultMapping constructorMapping : constructorMappings) {
final Class<?> parameterType = constructorMapping.getJavaType();
final String column = constructorMapping.getColumn();
final Object value;
try {
if (constructorMapping.getNestedQueryId() != null) {
value = getNestedQueryConstructorValue(rsw.getResultSet(), constructorMapping, columnPrefix);
} else if (constructorMapping.getNestedResultMapId() != null) {
final ResultMap resultMap = configuration.getResultMap(constructorMapping.getNestedResultMapId());
value = getRowValue(rsw, resultMap, getColumnPrefix(columnPrefix, constructorMapping));
} else {
final TypeHandler<?> typeHandler = constructorMapping.getTypeHandler();
value = typeHandler.getResult(rsw.getResultSet(), prependPrefix(column, columnPrefix));
}
} catch (ResultMapException | SQLException e) {
throw new ExecutorException("Could not process result for mapping: " + constructorMapping, e);
}
constructorArgTypes.add(parameterType);
constructorArgs.add(value);
foundValues = value != null || foundValues;
}
return foundValues ? objectFactory.create(resultType, constructorArgTypes, constructorArgs) : null;
}
//创建根据构造特征的对象
private Object createByConstructorSignature(ResultSetWrapper rsw, Class<?> resultType, List<Class<?>> constructorArgTypes, List<Object> constructorArgs) throws SQLException {
final Constructor<?>[] constructors = resultType.getDeclaredConstructors();
final Constructor<?> defaultConstructor = findDefaultConstructor(constructors);
if (defaultConstructor != null) {
return createUsingConstructor(rsw, resultType, constructorArgTypes, constructorArgs, defaultConstructor);
} else {
for (Constructor<?> constructor : constructors) {
if (allowedConstructorUsingTypeHandlers(constructor, rsw.getJdbcTypes())) {
return createUsingConstructor(rsw, resultType, constructorArgTypes, constructorArgs, constructor);
}
}
}
throw new ExecutorException("No constructor found in " + resultType.getName() + " matching " + rsw.getClassNames());
}
//使用构造器创建对象
private Object createUsingConstructor(ResultSetWrapper rsw, Class<?> resultType, List<Class<?>> constructorArgTypes, List<Object> constructorArgs, Constructor<?> constructor) throws SQLException {
boolean foundValues = false;
for (int i = 0; i < constructor.getParameterTypes().length; i++) {
Class<?> parameterType = constructor.getParameterTypes()[i];
String columnName = rsw.getColumnNames().get(i);
TypeHandler<?> typeHandler = rsw.getTypeHandler(parameterType, columnName);
Object value = typeHandler.getResult(rsw.getResultSet(), columnName);
constructorArgTypes.add(parameterType);
constructorArgs.add(value);
foundValues = value != null || foundValues;
}
return foundValues ? objectFactory.create(resultType, constructorArgTypes, constructorArgs) : null;
}
//找到默认的构造器
private Constructor<?> findDefaultConstructor(final Constructor<?>[] constructors) {
if (constructors.length == 1) {
return constructors[0];
}
for (final Constructor<?> constructor : constructors) {
if (constructor.isAnnotationPresent(AutomapConstructor.class)) {
return constructor;
}
}
return null;
}
//允许使用类型处理器的构造器
private boolean allowedConstructorUsingTypeHandlers(final Constructor<?> constructor, final List<JdbcType> jdbcTypes) {
final Class<?>[] parameterTypes = constructor.getParameterTypes();
if (parameterTypes.length != jdbcTypes.size()) {
return false;
}
for (int i = 0; i < parameterTypes.length; i++) {
if (!typeHandlerRegistry.hasTypeHandler(parameterTypes[i], jdbcTypes.get(i))) {
return false;
}
}
return true;
}
//创建主要的结果对象
private Object createPrimitiveResultObject(ResultSetWrapper rsw, ResultMap resultMap, String columnPrefix) throws SQLException {
final Class<?> resultType = resultMap.getType();
final String columnName;
if (!resultMap.getResultMappings().isEmpty()) {
final List<ResultMapping> resultMappingList = resultMap.getResultMappings();
final ResultMapping mapping = resultMappingList.get(0);
columnName = prependPrefix(mapping.getColumn(), columnPrefix);
} else {
columnName = rsw.getColumnNames().get(0);
}
final TypeHandler<?> typeHandler = rsw.getTypeHandler(resultType, columnName);
return typeHandler.getResult(rsw.getResultSet(), columnName);
}
// 嵌套查询
// NESTED QUERY
//
private Object getNestedQueryConstructorValue(ResultSet rs, ResultMapping constructorMapping, String columnPrefix) throws SQLException {
final String nestedQueryId = constructorMapping.getNestedQueryId();
final MappedStatement nestedQuery = configuration.getMappedStatement(nestedQueryId);
final Class<?> nestedQueryParameterType = nestedQuery.getParameterMap().getType();
final Object nestedQueryParameterObject = prepareParameterForNestedQuery(rs, constructorMapping, nestedQueryParameterType, columnPrefix);
Object value = null;
if (nestedQueryParameterObject != null) {
final BoundSql nestedBoundSql = nestedQuery.getBoundSql(nestedQueryParameterObject);
final CacheKey key = executor.createCacheKey(nestedQuery, nestedQueryParameterObject, RowBounds.DEFAULT, nestedBoundSql);
final Class<?> targetType = constructorMapping.getJavaType();
final ResultLoader resultLoader = new ResultLoader(configuration, executor, nestedQuery, nestedQueryParameterObject, targetType, key, nestedBoundSql);
value = resultLoader.loadResult();
}
return value;
}
// 获取嵌套查询映射值
private Object getNestedQueryMappingValue(ResultSet rs, MetaObject metaResultObject, ResultMapping propertyMapping, ResultLoaderMap lazyLoader, String columnPrefix)
throws SQLException {
final String nestedQueryId = propertyMapping.getNestedQueryId();
final String property = propertyMapping.getProperty();
final MappedStatement nestedQuery = configuration.getMappedStatement(nestedQueryId);
final Class<?> nestedQueryParameterType = nestedQuery.getParameterMap().getType();
final Object nestedQueryParameterObject = prepareParameterForNestedQuery(rs, propertyMapping, nestedQueryParameterType, columnPrefix);
Object value = null;
if (nestedQueryParameterObject != null) {
final BoundSql nestedBoundSql = nestedQuery.getBoundSql(nestedQueryParameterObject);
final CacheKey key = executor.createCacheKey(nestedQuery, nestedQueryParameterObject, RowBounds.DEFAULT, nestedBoundSql);
final Class<?> targetType = propertyMapping.getJavaType();
if (executor.isCached(nestedQuery, key)) {
executor.deferLoad(nestedQuery, metaResultObject, property, key, targetType);
value = DEFERRED;
} else {
final ResultLoader resultLoader = new ResultLoader(configuration, executor, nestedQuery, nestedQueryParameterObject, targetType, key, nestedBoundSql);
if (propertyMapping.isLazy()) {
lazyLoader.addLoader(property, metaResultObject, resultLoader);
value = DEFERRED;
} else {
value = resultLoader.loadResult();
}
}
}
return value;
}
//准备参数 为嵌套查询
private Object prepareParameterForNestedQuery(ResultSet rs, ResultMapping resultMapping, Class<?> parameterType, String columnPrefix) throws SQLException {
if (resultMapping.isCompositeResult()) {
return prepareCompositeKeyParameter(rs, resultMapping, parameterType, columnPrefix);
} else {
return prepareSimpleKeyParameter(rs, resultMapping, parameterType, columnPrefix);
}
}
//准备单个key参数
private Object prepareSimpleKeyParameter(ResultSet rs, ResultMapping resultMapping, Class<?> parameterType, String columnPrefix) throws SQLException {
final TypeHandler<?> typeHandler;
if (typeHandlerRegistry.hasTypeHandler(parameterType)) {
typeHandler = typeHandlerRegistry.getTypeHandler(parameterType);
} else {
typeHandler = typeHandlerRegistry.getUnknownTypeHandler();
}
return typeHandler.getResult(rs, prependPrefix(resultMapping.getColumn(), columnPrefix));
}
//准备混合key参数
private Object prepareCompositeKeyParameter(ResultSet rs, ResultMapping resultMapping, Class<?> parameterType, String columnPrefix) throws SQLException {
final Object parameterObject = instantiateParameterObject(parameterType);
final MetaObject metaObject = configuration.newMetaObject(parameterObject);
boolean foundValues = false;
for (ResultMapping innerResultMapping : resultMapping.getComposites()) {
final Class<?> propType = metaObject.getSetterType(innerResultMapping.getProperty());
final TypeHandler<?> typeHandler = typeHandlerRegistry.getTypeHandler(propType);
final Object propValue = typeHandler.getResult(rs, prependPrefix(innerResultMapping.getColumn(), columnPrefix));
// issue #353 & #560 do not execute nested query if key is null
if (propValue != null) {
metaObject.setValue(innerResultMapping.getProperty(), propValue);
foundValues = true;
}
}
return foundValues ? parameterObject : null;
}
//实例话参数对象
private Object instantiateParameterObject(Class<?> parameterType) {
if (parameterType == null) {
return new HashMap<>();
} else if (ParamMap.class.equals(parameterType)) {
return new HashMap<>(); // issue #649
} else {
return objectFactory.create(parameterType);
}
}
//解决区别结果集
// DISCRIMINATOR
//
public ResultMap resolveDiscriminatedResultMap(ResultSet rs, ResultMap resultMap, String columnPrefix) throws SQLException {
Set<String> pastDiscriminators = new HashSet<>();
Discriminator discriminator = resultMap.getDiscriminator();
while (discriminator != null) {
final Object value = getDiscriminatorValue(rs, discriminator, columnPrefix);
final String discriminatedMapId = discriminator.getMapIdFor(String.valueOf(value));
if (configuration.hasResultMap(discriminatedMapId)) {
resultMap = configuration.getResultMap(discriminatedMapId);
Discriminator lastDiscriminator = discriminator;
discriminator = resultMap.getDiscriminator();
if (discriminator == lastDiscriminator || !pastDiscriminators.add(discriminatedMapId)) {
break;
}
} else {
break;
}
}
return resultMap;
}
//获取区别值
private Object getDiscriminatorValue(ResultSet rs, Discriminator discriminator, String columnPrefix) throws SQLException {
final ResultMapping resultMapping = discriminator.getResultMapping();
final TypeHandler<?> typeHandler = resultMapping.getTypeHandler();
return typeHandler.getResult(rs, prependPrefix(resultMapping.getColumn(), columnPrefix));
}
//封装前缀
private String prependPrefix(String columnName, String prefix) {
if (columnName == null || columnName.length() == 0 || prefix == null || prefix.length() == 0) {
return columnName;
}
return prefix + columnName;
}
// 处理嵌套结果映射
// HANDLE NESTED RESULT MAPS
//
private void handleRowValuesForNestedResultMap(ResultSetWrapper rsw, ResultMap resultMap, ResultHandler<?> resultHandler, RowBounds rowBounds, ResultMapping parentMapping) throws SQLException {
final DefaultResultContext<Object> resultContext = new DefaultResultContext<>();
ResultSet resultSet = rsw.getResultSet();
skipRows(resultSet, rowBounds);
Object rowValue = previousRowValue;
while (shouldProcessMoreRows(resultContext, rowBounds) && !resultSet.isClosed() && resultSet.next()) {
final ResultMap discriminatedResultMap = resolveDiscriminatedResultMap(resultSet, resultMap, null);
final CacheKey rowKey = createRowKey(discriminatedResultMap, rsw, null);
Object partialObject = nestedResultObjects.get(rowKey);
// issue #577 && #542
if (mappedStatement.isResultOrdered()) {
if (partialObject == null && rowValue != null) {
nestedResultObjects.clear();
storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, null, partialObject);
} else {
rowValue = getRowValue(rsw, discriminatedResultMap, rowKey, null, partialObject);
if (partialObject == null) {
storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
}
}
}
if (rowValue != null && mappedStatement.isResultOrdered() && shouldProcessMoreRows(resultContext, rowBounds)) {
storeObject(resultHandler, resultContext, rowValue, parentMapping, resultSet);
previousRowValue = null;
} else if (rowValue != null) {
previousRowValue = rowValue;
}
}
// 从嵌套结果映射中获取值
// GET VALUE FROM ROW FOR NESTED RESULT MAP
//
private Object getRowValue(ResultSetWrapper rsw, ResultMap resultMap, CacheKey combinedKey, String columnPrefix, Object partialObject) throws SQLException {
final String resultMapId = resultMap.getId();
Object rowValue = partialObject;
if (rowValue != null) {
final MetaObject metaObject = configuration.newMetaObject(rowValue);
putAncestor(rowValue, resultMapId);
applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, false);
ancestorObjects.remove(resultMapId);
} else {
final ResultLoaderMap lazyLoader = new ResultLoaderMap();
rowValue = createResultObject(rsw, resultMap, lazyLoader, columnPrefix);
if (rowValue != null && !hasTypeHandlerForResultObject(rsw, resultMap.getType())) {
final MetaObject metaObject = configuration.newMetaObject(rowValue);
boolean foundValues = this.useConstructorMappings;
if (shouldApplyAutomaticMappings(resultMap, true)) {
foundValues = applyAutomaticMappings(rsw, resultMap, metaObject, columnPrefix) || foundValues;
}
foundValues = applyPropertyMappings(rsw, resultMap, metaObject, lazyLoader, columnPrefix) || foundValues;
putAncestor(rowValue, resultMapId);
foundValues = applyNestedResultMappings(rsw, resultMap, metaObject, columnPrefix, combinedKey, true) || foundValues;
ancestorObjects.remove(resultMapId);
foundValues = lazyLoader.size() > 0 || foundValues;
rowValue = foundValues || configuration.isReturnInstanceForEmptyRow() ? rowValue : null;
}
if (combinedKey != CacheKey.NULL_CACHE_KEY) {
nestedResultObjects.put(combinedKey, rowValue);
}
}
return rowValue;
}
private void putAncestor(Object resultObject, String resultMapId) {
ancestorObjects.put(resultMapId, resultObject);
}
// 嵌套结果集
// NESTED RESULT MAP (JOIN MAPPING)
//
private boolean applyNestedResultMappings(ResultSetWrapper rsw, ResultMap resultMap, MetaObject metaObject, String parentPrefix, CacheKey parentRowKey, boolean newObject) {
boolean foundValues = false;
for (ResultMapping resultMapping : resultMap.getPropertyResultMappings()) {
final String nestedResultMapId = resultMapping.getNestedResultMapId();
if (nestedResultMapId != null && resultMapping.getResultSet() == null) {
try {
final String columnPrefix = getColumnPrefix(parentPrefix, resultMapping);
final ResultMap nestedResultMap = getNestedResultMap(rsw.getResultSet(), nestedResultMapId, columnPrefix);
if (resultMapping.getColumnPrefix() == null) {
// try to fill circular reference only when columnPrefix
// is not specified for the nested result map (issue #215)
Object ancestorObject = ancestorObjects.get(nestedResultMapId);
if (ancestorObject != null) {
if (newObject) {
linkObjects(metaObject, resultMapping, ancestorObject); // issue #385
}
continue;
}
}
final CacheKey rowKey = createRowKey(nestedResultMap, rsw, columnPrefix);
final CacheKey combinedKey = combineKeys(rowKey, parentRowKey);
Object rowValue = nestedResultObjects.get(combinedKey);
boolean knownValue = rowValue != null;
instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject); // mandatory
if (anyNotNullColumnHasValue(resultMapping, columnPrefix, rsw)) {
rowValue = getRowValue(rsw, nestedResultMap, combinedKey, columnPrefix, rowValue);
if (rowValue != null && !knownValue) {
linkObjects(metaObject, resultMapping, rowValue);
foundValues = true;
}
}
} catch (SQLException e) {
throw new ExecutorException("Error getting nested result map values for '" + resultMapping.getProperty() + "'. Cause: " + e, e);
}
}
}
return foundValues;
}
//获取列前缀
private String getColumnPrefix(String parentPrefix, ResultMapping resultMapping) {
final StringBuilder columnPrefixBuilder = new StringBuilder();
if (parentPrefix != null) {
columnPrefixBuilder.append(parentPrefix);
}
if (resultMapping.getColumnPrefix() != null) {
columnPrefixBuilder.append(resultMapping.getColumnPrefix());
}
return columnPrefixBuilder.length() == 0 ? null : columnPrefixBuilder.toString().toUpperCase(Locale.ENGLISH);
}
//应用非空字段是否有值
private boolean anyNotNullColumnHasValue(ResultMapping resultMapping, String columnPrefix, ResultSetWrapper rsw) throws SQLException {
Set<String> notNullColumns = resultMapping.getNotNullColumns();
if (notNullColumns != null && !notNullColumns.isEmpty()) {
ResultSet rs = rsw.getResultSet();
for (String column : notNullColumns) {
rs.getObject(prependPrefix(column, columnPrefix));
if (!rs.wasNull()) {
return true;
}
}
return false;
} else if (columnPrefix != null) {
for (String columnName : rsw.getColumnNames()) {
if (columnName.toUpperCase().startsWith(columnPrefix.toUpperCase())) {
return true;
}
}
return false;
}
return true;
}
//获取嵌套结果映射
private ResultMap getNestedResultMap(ResultSet rs, String nestedResultMapId, String columnPrefix) throws SQLException {
ResultMap nestedResultMap = configuration.getResultMap(nestedResultMapId);
return resolveDiscriminatedResultMap(rs, nestedResultMap, columnPrefix);
}
// 唯一的结果key
// UNIQUE RESULT KEY
//
private CacheKey createRowKey(ResultMap resultMap, ResultSetWrapper rsw, String columnPrefix) throws SQLException {
final CacheKey cacheKey = new CacheKey();
cacheKey.update(resultMap.getId());
List<ResultMapping> resultMappings = getResultMappingsForRowKey(resultMap);
if (resultMappings.isEmpty()) {
if (Map.class.isAssignableFrom(resultMap.getType())) {
createRowKeyForMap(rsw, cacheKey);
} else {
createRowKeyForUnmappedProperties(resultMap, rsw, cacheKey, columnPrefix);
}
} else {
createRowKeyForMappedProperties(resultMap, rsw, cacheKey, resultMappings, columnPrefix);
}
if (cacheKey.getUpdateCount() < 2) {
return CacheKey.NULL_CACHE_KEY;
}
return cacheKey;
}
//合起来key
private CacheKey combineKeys(CacheKey rowKey, CacheKey parentRowKey) {
if (rowKey.getUpdateCount() > 1 && parentRowKey.getUpdateCount() > 1) {
CacheKey combinedKey;
try {
combinedKey = rowKey.clone();
} catch (CloneNotSupportedException e) {
throw new ExecutorException("Error cloning cache key. Cause: " + e, e);
}
combinedKey.update(parentRowKey);
return combinedKey;
}
return CacheKey.NULL_CACHE_KEY;
}
//获取行key的结果映射
private List<ResultMapping> getResultMappingsForRowKey(ResultMap resultMap) {
List<ResultMapping> resultMappings = resultMap.getIdResultMappings();
if (resultMappings.isEmpty()) {
resultMappings = resultMap.getPropertyResultMappings();
}
return resultMappings;
}
//创建行key对于映射的属性
private void createRowKeyForMappedProperties(ResultMap resultMap, ResultSetWrapper rsw, CacheKey cacheKey, List<ResultMapping> resultMappings, String columnPrefix) throws SQLException {
for (ResultMapping resultMapping : resultMappings) {
if (resultMapping.getNestedResultMapId() != null && resultMapping.getResultSet() == null) {
// Issue #392
final ResultMap nestedResultMap = configuration.getResultMap(resultMapping.getNestedResultMapId());
createRowKeyForMappedProperties(nestedResultMap, rsw, cacheKey, nestedResultMap.getConstructorResultMappings(),
prependPrefix(resultMapping.getColumnPrefix(), columnPrefix));
} else if (resultMapping.getNestedQueryId() == null) {
final String column = prependPrefix(resultMapping.getColumn(), columnPrefix);
final TypeHandler<?> th = resultMapping.getTypeHandler();
List<String> mappedColumnNames = rsw.getMappedColumnNames(resultMap, columnPrefix);
// Issue #114
if (column != null && mappedColumnNames.contains(column.toUpperCase(Locale.ENGLISH))) {
final Object value = th.getResult(rsw.getResultSet(), column);
if (value != null || configuration.isReturnInstanceForEmptyRow()) {
cacheKey.update(column);
cacheKey.update(value);
}
}
}
}
}
//创建行key对应未映射的属性
private void createRowKeyForUnmappedProperties(ResultMap resultMap, ResultSetWrapper rsw, CacheKey cacheKey, String columnPrefix) throws SQLException {
final MetaClass metaType = MetaClass.forClass(resultMap.getType(), reflectorFactory);
List<String> unmappedColumnNames = rsw.getUnmappedColumnNames(resultMap, columnPrefix);
for (String column : unmappedColumnNames) {
String property = column;
if (columnPrefix != null && !columnPrefix.isEmpty()) {
// When columnPrefix is specified, ignore columns without the prefix.
if (column.toUpperCase(Locale.ENGLISH).startsWith(columnPrefix)) {
property = column.substring(columnPrefix.length());
} else {
continue;
}
}
if (metaType.findProperty(property, configuration.isMapUnderscoreToCamelCase()) != null) {
String value = rsw.getResultSet().getString(column);
if (value != null) {
cacheKey.update(column);
cacheKey.update(value);
}
}
}
}
//创建行key
private void createRowKeyForMap(ResultSetWrapper rsw, CacheKey cacheKey) throws SQLException {
List<String> columnNames = rsw.getColumnNames();
for (String columnName : columnNames) {
final String value = rsw.getResultSet().getString(columnName);
if (value != null) {
cacheKey.update(columnName);
cacheKey.update(value);
}
}
}
//链接对象
private void linkObjects(MetaObject metaObject, ResultMapping resultMapping, Object rowValue) {
final Object collectionProperty = instantiateCollectionPropertyIfAppropriate(resultMapping, metaObject);
if (collectionProperty != null) {
final MetaObject targetMetaObject = configuration.newMetaObject(collectionProperty);
targetMetaObject.add(rowValue);
} else {
metaObject.setValue(resultMapping.getProperty(), rowValue);
}
}
//实例话集合属性如果合适的
private Object instantiateCollectionPropertyIfAppropriate(ResultMapping resultMapping, MetaObject metaObject) {
final String propertyName = resultMapping.getProperty();
Object propertyValue = metaObject.getValue(propertyName);
if (propertyValue == null) {
Class<?> type = resultMapping.getJavaType();
if (type == null) {
type = metaObject.getSetterType(propertyName);
}
try {
if (objectFactory.isCollection(type)) {
propertyValue = objectFactory.create(type);
metaObject.setValue(propertyName, propertyValue);
return propertyValue;
}
} catch (Exception e) {
throw new ExecutorException("Error instantiating collection property for result '" + resultMapping.getProperty() + "'. Cause: " + e, e);
}
} else if (objectFactory.isCollection(propertyValue.getClass())) {
return propertyValue;
}
return null;
}
//结果对象的类型处理器是否存在
private boolean hasTypeHandlerForResultObject(ResultSetWrapper rsw, Class<?> resultType) {
if (rsw.getColumnNames().size() == 1) {
return typeHandlerRegistry.hasTypeHandler(resultType, rsw.getJdbcType(rsw.getColumnNames().get(0)));
}
return typeHandlerRegistry.hasTypeHandler(resultType);
}
}
/**
* jdbc链接主键生成
* @author Clinton Begin
* @author Kazuki Shimizu
*/
public class Jdbc3KeyGenerator implements KeyGenerator {
//参数名字
private static final String SECOND_GENERIC_PARAM_NAME = ParamNameResolver.GENERIC_NAME_PREFIX + "2";
/**
* 3.4.3版本以后 一个共享的实例
* A shared instance.
*
* @since 3.4.3
*/
public static final Jdbc3KeyGenerator INSTANCE = new Jdbc3KeyGenerator();
//生成太多key的错误提示
private static final String MSG_TOO_MANY_KEYS = "Too many keys are generated. There are only %d target objects. "
+ "You either specified a wrong 'keyProperty' or encountered a driver bug like #1523.";
//在执行器前执行,什么也不做
@Override
public void processBefore(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
// do nothing
}
//在执行器后执行,执行会话
@Override
public void processAfter(Executor executor, MappedStatement ms, Statement stmt, Object parameter) {
processBatch(ms, stmt, parameter);
}
//执行
public void processBatch(MappedStatement ms, Statement stmt, Object parameter) {
//映射会话获取key属性
final String[] keyProperties = ms.getKeyProperties();
if (keyProperties == null || keyProperties.length == 0) {
return;
}
//会话获取主键
try (ResultSet rs = stmt.getGeneratedKeys()) {
//结果集获取元数据
final ResultSetMetaData rsmd = rs.getMetaData();
//获取全局配置
final Configuration configuration = ms.getConfiguration();
if (rsmd.getColumnCount() < keyProperties.length) {
// Error?
} else {
//分配key主键
assignKeys(configuration, rs, rsmd, keyProperties, parameter);
}
} catch (Exception e) {
throw new ExecutorException("Error getting generated key or setting result to parameter object. Cause: " + e, e);
}
}
//分配key主键
@SuppressWarnings("unchecked")
private void assignKeys(Configuration configuration, ResultSet rs, ResultSetMetaData rsmd, String[] keyProperties,
Object parameter) throws SQLException {
//使用@Param多个参数或者单个参数
if (parameter instanceof ParamMap || parameter instanceof StrictMap) {
// Multi-param or single param with @Param
assignKeysToParamMap(configuration, rs, rsmd, keyProperties, (Map<String, ?>) parameter);
} else if (parameter instanceof ArrayList && !((ArrayList<?>) parameter).isEmpty()
&& ((ArrayList<?>) parameter).get(0) instanceof ParamMap) {
//批量操作 @Param多个参数或者单个参数
// Multi-param or single param with @Param in batch operation
assignKeysToParamMapList(configuration, rs, rsmd, keyProperties, ((ArrayList<ParamMap<?>>) parameter));
} else {
//没有@Param的单个参数
// Single param without @Param
assignKeysToParam(configuration, rs, rsmd, keyProperties, parameter);
}
}
//分配主键给参数
private void assignKeysToParam(Configuration configuration, ResultSet rs, ResultSetMetaData rsmd,
String[] keyProperties, Object parameter) throws SQLException {
//集合化参数
Collection<?> params = collectionize(parameter);
if (params.isEmpty()) {
return;
}
//分配集合
List<KeyAssigner> assignerList = new ArrayList<>();
for (int i = 0; i < keyProperties.length; i++) {
//添加分配的主键集合
assignerList.add(new KeyAssigner(configuration, rsmd, i + 1, null, keyProperties[i]));
}
//遍历
Iterator<?> iterator = params.iterator();
while (rs.next()) {
if (!iterator.hasNext()) {
throw new ExecutorException(String.format(MSG_TOO_MANY_KEYS, params.size()));
}
//给每个会话绑定
Object param = iterator.next();
assignerList.forEach(x -> x.assign(rs, param));
}
}
//分配主键给参数map集合
private void assignKeysToParamMapList(Configuration configuration, ResultSet rs, ResultSetMetaData rsmd,
String[] keyProperties, ArrayList<ParamMap<?>> paramMapList) throws SQLException {
Iterator<ParamMap<?>> iterator = paramMapList.iterator();
List<KeyAssigner> assignerList = new ArrayList<>();
long counter = 0;
//遍历结果信息
while (rs.next()) {
if (!iterator.hasNext()) {
throw new ExecutorException(String.format(MSG_TOO_MANY_KEYS, counter));
}
//如果分配集合为空,则给每个对象属性赋值
ParamMap<?> paramMap = iterator.next();
if (assignerList.isEmpty()) {
for (int i = 0; i < keyProperties.length; i++) {
assignerList
.add(getAssignerForParamMap(configuration, rsmd, i + 1, paramMap, keyProperties[i], keyProperties, false)
.getValue());
}
}
assignerList.forEach(x -> x.assign(rs, paramMap));
counter++;
}
}
//分配主键给参数Map
private void assignKeysToParamMap(Configuration configuration, ResultSet rs, ResultSetMetaData rsmd,
String[] keyProperties, Map<String, ?> paramMap) throws SQLException {
if (paramMap.isEmpty()) {
return;
}
//遍历map的key属性
Map<String, Entry<Iterator<?>, List<KeyAssigner>>> assignerMap = new HashMap<>();
for (int i = 0; i < keyProperties.length; i++) {
Entry<String, KeyAssigner> entry = getAssignerForParamMap(configuration, rsmd, i + 1, paramMap, keyProperties[i],
keyProperties, true);
Entry<Iterator<?>, List<KeyAssigner>> iteratorPair = assignerMap.computeIfAbsent(entry.getKey(),
k -> entry(collectionize(paramMap.get(k)).iterator(), new ArrayList<>()));
iteratorPair.getValue().add(entry.getValue());
}
//遍历返回结果赋值
long counter = 0;
while (rs.next()) {
for (Entry<Iterator<?>, List<KeyAssigner>> pair : assignerMap.values()) {
if (!pair.getKey().hasNext()) {
throw new ExecutorException(String.format(MSG_TOO_MANY_KEYS, counter));
}
Object param = pair.getKey().next();
pair.getValue().forEach(x -> x.assign(rs, param));
}
counter++;
}
}
//从参数Map获取分配
private Entry<String, KeyAssigner> getAssignerForParamMap(Configuration config, ResultSetMetaData rsmd,
int columnPosition, Map<String, ?> paramMap, String keyProperty, String[] keyProperties, boolean omitParamName) {
Set<String> keySet = paramMap.keySet();
//如果唯一的参数这种方式使用{@code @Param("param2")},一定是被param2.x这样引用
// A caveat : if the only parameter has {@code @Param("param2")} on it,
// it must be referenced with param name e.g. 'param2.x'.
//主键集合不包括参数名字
boolean singleParam = !keySet.contains(SECOND_GENERIC_PARAM_NAME);
//属性获取第一个点
int firstDot = keyProperty.indexOf('.');
//如果是没有
if (firstDot == -1) {
//如果是单个参数,直接分配
if (singleParam) {
return getAssignerForSingleParam(config, rsmd, columnPosition, paramMap, keyProperty, omitParamName);
}
throw new ExecutorException("Could not determine which parameter to assign generated keys to. "
+ "Note that when there are multiple parameters, 'keyProperty' must include the parameter name (e.g. 'param.id'). "
+ "Specified key properties are " + ArrayUtil.toString(keyProperties) + " and available parameters are "
+ keySet);
}
//从0到第一个点截断,取后面的参数名字
String paramName = keyProperty.substring(0, firstDot);
//判断key集合是否包含参数名字
if (keySet.contains(paramName)) {
String argParamName = omitParamName ? null : paramName;
String argKeyProperty = keyProperty.substring(firstDot + 1);
return entry(paramName, new KeyAssigner(config, rsmd, columnPosition, argParamName, argKeyProperty));
} else if (singleParam) {
//单个参数的分配
return getAssignerForSingleParam(config, rsmd, columnPosition, paramMap, keyProperty, omitParamName);
} else {
throw new ExecutorException("Could not find parameter '" + paramName + "'. "
+ "Note that when there are multiple parameters, 'keyProperty' must include the parameter name (e.g. 'param.id'). "
+ "Specified key properties are " + ArrayUtil.toString(keyProperties) + " and available parameters are "
+ keySet);
}
}
//从单个参数获取分配
private Entry<String, KeyAssigner> getAssignerForSingleParam(Configuration config, ResultSetMetaData rsmd,
int columnPosition, Map<String, ?> paramMap, String keyProperty, boolean omitParamName) {
// Assume 'keyProperty' to be a property of the single param.
//假设这个属性的参数有'keyProperty'
String singleParamName = nameOfSingleParam(paramMap);
String argParamName = omitParamName ? null : singleParamName;
//封装该实体类
return entry(singleParamName, new KeyAssigner(config, rsmd, columnPosition, argParamName, keyProperty));
}
//单个参数的名字
private static String nameOfSingleParam(Map<String, ?> paramMap) {
// There is virtually one parameter, so any key works.
return paramMap.keySet().iterator().next();
}
//集合化参数
private static Collection<?> collectionize(Object param) {
if (param instanceof Collection) {
return (Collection<?>) param;
} else if (param instanceof Object[]) {
return Arrays.asList((Object[]) param);
} else {
return Arrays.asList(param);
}
}
//在Java9中取代了Map.entry(key, value)的方式
private static <K, V> Entry<K, V> entry(K key, V value) {
// Replace this with Map.entry(key, value) in Java 9.
return new AbstractMap.SimpleImmutableEntry<>(key, value);
}
//主键分配类
private class KeyAssigner {
//全局配置
private final Configuration configuration;
//结果元数据集
private final ResultSetMetaData rsmd;
//类型处理注册器
private final TypeHandlerRegistry typeHandlerRegistry;
//列位置
private final int columnPosition;
//参数名字
private final String paramName;
//属性名字
private final String propertyName;
//类型处理器
private TypeHandler<?> typeHandler;
//构造函数
protected KeyAssigner(Configuration configuration, ResultSetMetaData rsmd, int columnPosition, String paramName,
String propertyName) {
super();
this.configuration = configuration;
this.rsmd = rsmd;
this.typeHandlerRegistry = configuration.getTypeHandlerRegistry();
this.columnPosition = columnPosition;
this.paramName = paramName;
this.propertyName = propertyName;
}
//分配结果集和参数
protected void assign(ResultSet rs, Object param) {
if (paramName != null) {
// If paramName is set, param is ParamMap
param = ((ParamMap<?>) param).get(paramName);
}
//获取元对象
MetaObject metaParam = configuration.newMetaObject(param);
try {
//如果类型处理器为空
if (typeHandler == null) {
//元参数判断是否有set方法
if (metaParam.hasSetter(propertyName)) {
//元参数获取set类型
Class<?> propertyType = metaParam.getSetterType(propertyName);
//类型处理器注册器获取对应的类型处理器
typeHandler = typeHandlerRegistry.getTypeHandler(propertyType,
JdbcType.forCode(rsmd.getColumnType(columnPosition)));
} else {
throw new ExecutorException("No setter found for the keyProperty '" + propertyName + "' in '"
+ metaParam.getOriginalObject().getClass().getName() + "'.");
}
}
if (typeHandler == null) {
// Error?
} else {
//类型处理器处理结果返回值赋值给属性
Object value = typeHandler.getResult(rs, columnPosition);
metaParam.setValue(propertyName, value);
}
} catch (SQLException e) {
throw new ExecutorException("Error getting generated key or setting result to parameter object. Cause: " + e,
e);
}
}
}
}