1. 程式人生 > >[MyBatis原始碼分析系列] SqlSession, DefaultSqlSession

[MyBatis原始碼分析系列] SqlSession, DefaultSqlSession

SqlSession

簡介

使用MyBatis工作時,主要的Java介面。
通過此介面你可以執行命令,獲取對映及管理事務。

原始碼

public interface SqlSession extends Closeable {
	<T> T selectOne(String statement);
	
	<T> T selectOne(String statement, Object parameter);

	<E> List<E> selectList(String statement);

	<E> List<
E>
selectList(String statement, Object parameter); <E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds); <K, V> Map<K, V> selectMap(String statement, String mapKey); <K, V> Map<K, V> selectMap(String statement, Object parameter,
String mapKey); <K, V> Map<K, V> selectMap(String statement, Object parameter, String mapKey, RowBounds rowBounds); <T> Cursor<T> selectCursor(String statement); <T> Cursor<T> selectCursor(String statement, Object parameter); void select(String statement,
Object parameter, ResultHandler handler); void select(String statement, ResultHandler handler); void select(String statement, Object parameter, RowBounds rowBounds, ResultHandler handler); int insert(String statement); int insert(String statement, Object parameter); int update(String statement); int updte(String statement, Object parameter); int delete(String statement); int delete(String statement, Object parameter); void commit(); void commit(boolean force); void rollback(); void rollback(boolean force); List<BatchResult> flushStatements(); @Override void close(); void clearCache(); Configuration getConfiguration(); <T> T getMapper(Class<?> type); Connection getConnection(); }

DefaultSqlSession

簡介

SqlSession的預設實現

原始碼

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(Configuraton configuration, Executor executor executor){
		this(configuration, executor, false);
	}

	@Override
	public <T> T selectOne(String statement) {
		return this.<T>selectOne(statement, null);
	}

	@Override
	public <T> T selectOne(String statement, Object parameter){
		List<T> list = this.<T>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 <E> List<E> selectList(String statement){
		return this.selectList(statement, null);
	}

	@Override
	public <E> List<E> selectList(String, Object parameter){
		return this.selectList(statement, parameter, RowBounds.DEFAULT);
	}

	@Override
	public <E> list<E> selectList(String statement, Object parameter, RowBounds rowBounds){
		try{
			MappedStatement ms = configuration.getMappedStatement(statement);
			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 <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);
	}

	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;
	}

	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);
		}
	}
}