mybatis3.5.1,接收参数

这里是parameterType接受的各种参数类型处理,在DefaultSqlSession中,此时走的是openSession后面的流程

 /**
     * ~~把参数包装成Collection~~ 
     *
     * @param object
     * @return
     */
    private Object wrapCollection(final Object object) {
     
        if (object instanceof Collection) {
     
            //参数若是Collection型,做collection标记
            StrictMap<Object> map = new StrictMap<>();
            map.put("collection", object);
            if (object instanceof List) {
     
                //参数若是List型,做list标记
                map.put("list", object);
            }
            return map;
        } else if (object != null && object.getClass().isArray()) {
     
            //参数若是数组型,,做array标记
            StrictMap<Object> map = new StrictMap<>();
            map.put("array", object);
            return map;
        }
        //参数若不是集合型,直接返回原来值
        return object;
    }

下面是整个代码

/**
 * Copyright ${license.git.copyrightYears} the original author or authors.
 * 

* Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at *

* http://www.apache.org/licenses/LICENSE-2.0 *

* Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.ibatis.session.defaults; import org.apache.ibatis.binding.BindingException; import org.apache.ibatis.cursor.Cursor; import org.apache.ibatis.exceptions.ExceptionFactory; import org.apache.ibatis.exceptions.TooManyResultsException; import org.apache.ibatis.executor.BatchResult; import org.apache.ibatis.executor.ErrorContext; import org.apache.ibatis.executor.Executor; import org.apache.ibatis.executor.result.DefaultMapResultHandler; import org.apache.ibatis.executor.result.DefaultResultContext; import org.apache.ibatis.mapping.MappedStatement; import org.apache.ibatis.session.Configuration; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; import org.apache.ibatis.session.SqlSession; import java.io.IOException; import java.sql.Connection; import java.sql.SQLException; import java.util.*; /** * 默认SqlSession实现 * 非线程安全 * The default implementation for {@link SqlSession}. * Note that this class is not Thread-Safe. * * @author Clinton Begin */ 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 <T> T selectOne(String statement) { return this.selectOne(statement, null); } /** * 核心selectOne * * @param statement * @param * @return */ @Override public <T> T selectOne(String statement, Object parameter) { // Popular vote was to return null on 0 results and throw exception on too many. //转而去调用selectList,很简单的,如果得到0条则返回null,得到1条则返回1条,得到多条报TooManyResultsException错 //特别需要注意的是当没有查询到结果的时候就会返回null。因此一般建议在mapper中编写resultType的时候使用包装类型 //而不是基本类型,比如推荐使用Integer而不是int。这样就可以避免NPE(NullPointerException) List<T> list = this.selectList(statement, parameter); if (list.size() == 1) { return list.get(0); } else if (list.size() > 1) { throw new TooManyResultsException("Expected one result (or null) to be returned by selectOne(), but found: " + list.size()); } else { return null; } } @Override public <K, V> Map<K, V> selectMap(String statement, String mapKey) { return this.selectMap(statement, null, mapKey, RowBounds.DEFAULT); } @Override public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey) { return this.selectMap(statement, parameter, mapKey, RowBounds.DEFAULT); } /** * //核心selectMap * * @param statement Unique identifier matching the statement to use. * @param parameter A parameter object to pass to the statement. * @param mapKey The property to use as key for each value in the list. * @param rowBounds Bounds to limit object retrieval * @param * @param * @return */ @Override public <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds) { //调用selectList final List<? extends V> list = selectList(statement, parameter, rowBounds); final DefaultMapResultHandler<K, V> mapResultHandler = new DefaultMapResultHandler<>(mapKey, configuration.getObjectFactory(), configuration.getObjectWrapperFactory(), configuration.getReflectorFactory()); final DefaultResultContext<V> context = new DefaultResultContext<>(); for (V o : list) { //循环用DefaultMapResultHandler处理每条记录 context.nextResultObject(o); mapResultHandler.handleResult(context); } //注意这个DefaultMapResultHandler里面存了所有已处理的记录(内部实现可能就是一个Map),最后再返回一个Map return mapResultHandler.getMappedResults(); } @Override public <T> Cursor<T> selectCursor(String statement) { return selectCursor(statement, null); } @Override public <T> Cursor<T> selectCursor(String statement, Object parameter) { return selectCursor(statement, parameter, RowBounds.DEFAULT); } @Override public <T> Cursor<T> selectCursor(String statement, Object parameter, RowBounds rowBounds) { try { MappedStatement ms = configuration.getMappedStatement(statement); Cursor<T> cursor = executor.queryCursor(ms, wrapCollection(parameter), rowBounds); registerCursor(cursor); return cursor; } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } @Override public <E> List<E> selectList(String statement) { return this.selectList(statement, null); } @Override public <E> List<E> selectList(String statement, Object parameter) { return this.selectList(statement, parameter, RowBounds.DEFAULT); } /** * 核心selectList * * @param statement Unique identifier matching the statement to use. * @param parameter A parameter object to pass to the statement. * @param rowBounds Bounds to limit object retrieval * @param * @return */ @Override public <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds) { try { //根据statement id找到对应的MappedStatement MappedStatement ms = configuration.getMappedStatement(statement); //转而用执行器来查询结果,注意这里传入的ResultHandler是null return executor.query(ms, wrapCollection(parameter), rowBounds, Executor.NO_RESULT_HANDLER); } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } @Override public void select(String statement, Object parameter, ResultHandler handler) { select(statement, parameter, RowBounds.DEFAULT, handler); } @Override public void select(String statement, ResultHandler handler) { select(statement, null, RowBounds.DEFAULT, handler); } /** * 核心select,带有ResultHandler,和selectList代码差不多的,区别就一个ResultHandler * * @param statement Unique identifier matching the statement to use. * @param parameter * @param rowBounds RowBound instance to limit the query results * @param handler ResultHandler that will handle each retrieved row */ @Override public void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler) { try { MappedStatement ms = configuration.getMappedStatement(statement); executor.query(ms, wrapCollection(parameter), rowBounds, handler); } catch (Exception e) { throw ExceptionFactory.wrapException("Error querying database. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } @Override public int insert(String statement) { return insert(statement, null); } @Override public int insert(String statement, Object parameter) { //insert也是调用update return update(statement, parameter); } @Override public int update(String statement) { return update(statement, null); } /** * 核心update * * @param statement Unique identifier matching the statement to execute. * @param parameter A parameter object to pass to the statement. * @return */ @Override public int update(String statement, Object parameter) { try { //每次要更新之前,dirty标志设为true dirty = true; MappedStatement ms = configuration.getMappedStatement(statement); //转而用执行器来update结果 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) { //delete也是调用update return update(statement, null); } @Override public int delete(String statement, Object parameter) { return update(statement, parameter); } @Override public void commit() { commit(false); } /** * 核心commit * * @param force forces connection commit */ @Override public void commit(boolean force) { try { //转而用执行器来commit executor.commit(isCommitOrRollbackRequired(force)); //每次commit之后,dirty标志设为false dirty = false; } catch (Exception e) { throw ExceptionFactory.wrapException("Error committing transaction. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } @Override public void rollback() { rollback(false); } /** * 核心rollback * * @param force forces connection rollback */ @Override public void rollback(boolean force) { try { //转而用执行器来rollback executor.rollback(isCommitOrRollbackRequired(force)); //每次rollback之后,dirty标志设为false dirty = false; } catch (Exception e) { throw ExceptionFactory.wrapException("Error rolling back transaction. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } /** * 核心flushStatements * * @return */ @Override public List<BatchResult> flushStatements() { try { //转而用执行器来flushStatements return executor.flushStatements(); } catch (Exception e) { throw ExceptionFactory.wrapException("Error flushing statements. Cause: " + e, e); } finally { ErrorContext.instance().reset(); } } /** * 核心close */ @Override public void close() { try { //转而用执行器来close executor.close(isCommitOrRollbackRequired(false)); closeCursors(); //每次close之后,dirty标志设为false dirty = false; } finally { ErrorContext.instance().reset(); } } private void closeCursors() { if (cursorList != null && cursorList.size() != 0) { for (Cursor<?> cursor : cursorList) { try { cursor.close(); } catch (IOException e) { throw ExceptionFactory.wrapException("Error closing cursor. Cause: " + e, e); } } cursorList.clear(); } } @Override public Configuration getConfiguration() { return configuration; } @Override public <T> T getMapper(Class<T> type) { //最后会去调用MapperRegistry.getMapper return configuration.getMapper(type, this); } @Override public Connection getConnection() { try { return executor.getTransaction().getConnection(); } catch (SQLException e) { throw ExceptionFactory.wrapException("Error getting a new connection. Cause: " + e, e); } } /** * 清理缓存 */ @Override public void clearCache() { executor.clearLocalCache(); } private <T> void registerCursor(Cursor<T> cursor) { if (cursorList == null) { cursorList = new ArrayList<>(); } cursorList.add(cursor); } /** * 检查是否需要强制commit或rollback * * @param force * @return */ private boolean isCommitOrRollbackRequired(boolean force) { return (!autoCommit && dirty) || force; } /** * 把参数包装成Collection * * @param object * @return */ private Object wrapCollection(final Object object) { if (object instanceof Collection) { //参数若是Collection型,做collection标记 StrictMap<Object> map = new StrictMap<>(); map.put("collection", object); if (object instanceof List) { //参数若是List型,做list标记 map.put("list", object); } return map; } else if (object != null && object.getClass().isArray()) { //参数若是数组型,,做array标记 StrictMap<Object> map = new StrictMap<>(); map.put("array", object); return map; } //参数若不是集合型,直接返回原来值 return object; } /** * 严格的Map,如果找不到对应的key,直接抛BindingException例外,而不是返回null * * @param */ 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); } } }

看一下,StrictMap

  /**
     * 严格的Map,如果找不到对应的key,直接抛BindingException例外,而不是返回null
     *
     * @param 
     */
    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);
        }

    }

你可能感兴趣的:(mybatis3.5.1,接收参数)