文章目录
1. 查询所有方法源码分析
DAO接口的实现类调用了SqlSession.selectList()
public class AccountDaoImpl implements AccountDao {
private SqlSessionFactory factory;
public AccountDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
}
public List<Account> findAll() {
SqlSession session = factory.openSession();
List<Account> user = session.selectList("dao.AccountDao.findAll");
session.close();
return user;
}
}
看findAll()
中调用的session.selectList()
,发现SqlSession是一个借口,我们就需要找它的实现类
public interface SqlSession extends Closeable {
<E> List<E> selectList(String statement);
<E> List<E> selectList(String statement, Object parameter);
<E> List<E> selectList(String statement, Object parameter, RowBounds rowBounds);
}
这里使用的SqlSession的实现类为DefaultSqlSession,它其中的selectList()
方法的实现如下所示:
public class DefaultSqlSession implements SqlSession {
@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);
}
@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();
}
}
}
三个selectList()
依次调用下一个,最终使用的是selectList(String statement, Object parameter, RowBounds rowBounds)
。它其中又调用了executor.query()
,executor的定义为private final Executor executor;
,而Executor是一个接口:
public interface Executor {
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, CacheKey cacheKey, BoundSql boundSql) throws SQLException;
<E> List<E> query(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException;
}
因此,我们有需要找Executor的实现类。这里使用的是CachingExecutor
public class CachingExecutor implements Executor {
private final Executor delegate;
@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler) throws SQLException {
BoundSql boundSql = ms.getBoundSql(parameterObject);
CacheKey key = createCacheKey(ms, parameterObject, rowBounds, boundSql);
return query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
Cache cache = ms.getCache();
if (cache != null) {
flushCacheIfRequired(ms);
if (ms.isUseCache() && resultHandler == null) {
ensureNoOutParams(ms, boundSql);
@SuppressWarnings("unchecked")
List<E> list = (List<E>) tcm.getObject(cache, key);
if (list == null) {
list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
tcm.putObject(cache, key, list); // issue #578 and #116
}
return list;
}
}
return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
}
其中又调用了delegate.query
,delegate本身又是Executor类型的变量。因此,我们需要找到delegate对应的Executor接口的实现类,这里使用的是BaseExecutor。
public abstract class BaseExecutor implements Executor {
@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.");
}
if (queryStack == 0 && ms.isFlushCacheRequired()) {
clearLocalCache();
}
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 {
queryStack--;
}
if (queryStack == 0) {
for (DeferredLoad deferredLoad : deferredLoads) {
deferredLoad.load();
}
// issue #601
deferredLoads.clear();
if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
// issue #482
clearLocalCache();
}
}
return list;
}
}
其中又调用了queryFromDatabase()
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;
}
其中调用了doQuery()
。Executor本身是一个抽象类,故还需要继续找它的实现类SimpleExecutor中doQuery()
的实现:
public class SimpleExecutor extends BaseExecutor {
@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);
}
}
}
其中调用了handler.query()
,handler的定义为StatementHandler handler
,其中的StatementHandler 是以一个接口。这里接口的实现类使用的是RoutingStatementHandler
public class RoutingStatementHandler implements StatementHandler {
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
return delegate.query(statement, resultHandler);
}
}
而这里的delegate是StatementHandler接口的实现类PreparedStatementHandler类型的变量。
public class PreparedStatementHandler extends BaseStatementHandler {
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.handleResultSets(ps);
}
}
PreparedStatementHandler中的query()
使用的就是JDBC中的PreparedStatement的execute()
,结果的封装使用了resultSetHandler接口的唯一实现类DefaultResultSetHandler中的handleResultSets()
。
public class DefaultResultSetHandler implements ResultSetHandler {
@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++;
}
}
PreparedStatement对象的执行方法:
execute()
:它能执行CRUD中的任意一种语句,返回值是boolean类型,表示是否有结果集,有结果集是true,否则是falseexecuteUpdate()
:它只能执行CUD语句,查询语句无法执行,返回值为影响数据库记录的行数executeQuery()
:它只能执行SELECT语句,无法执行增删改,执行结果封装的结果集ResultSet对象
2. 插入、更新、删除方法源码分析
DAO接口的实现类中插入方法的实现:
public class AccountDaoImpl implements AccountDao {
private SqlSessionFactory factory;
public AccountDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
}
public void saveUser(Account account) {
SqlSession session = factory.openSession();
session.insert("dao.AccountDao.saveUser", account);
session.commit();
session.close();
}
}
调用的是SqlSession的实现类DefaultSqlSession中的insert()
public class DefaultSqlSession implements SqlSession {
@Override
public int insert(String statement) {
return insert(statement, null);
}
@Override
public int insert(String statement, Object parameter) {
return update(statement, parameter);
}
}
而insert()
调用的是update()
。
DAO接口的实现类中更新方法的实现:
public class AccountDaoImpl implements AccountDao {
private SqlSessionFactory factory;
public AccountDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
}
public void updateUser(Account account) {
SqlSession session = factory.openSession();
session.update("dao.AccountDao.updateUser", account);
session.commit();
session.close();
}
}
它调用的是SqlSession的实现类DefaultSqlSession中的update()
public class DefaultSqlSession implements SqlSession {
@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();
}
}
}
DAO接口的实现类中删除方法的实现:
public class AccountDaoImpl implements AccountDao {
private SqlSessionFactory factory;
public AccountDaoImpl(SqlSessionFactory factory) {
this.factory = factory;
}
public void deleteUser(int id) {
SqlSession session = factory.openSession();
session.update("dao.AccountDao.deleteUser", id);
session.commit();
session.close();
}
}
它调用的是SqlSession的实现类DefaultSqlSession中的update()
public class DefaultSqlSession implements SqlSession {
@Override
public int update(String statement) {
return update(statement, null);
}
@Override
public int delete(String statement) {
return update(statement, null);
}
@Override
public int delete(String statement, Object parameter) {
return update(statement, parameter);
}
}
delete()
又调用了update()
。
综上,三种方法最终调用的都是DefaultSqlSession中的update()
,因此,后面只需要分析update()
的源码实现即可。
update()
中调用了executor.update()
,这里的executor使用的是Executor接口的实现类CachingExecutor中的方法实现。
public class CachingExecutor implements Executor {
private final Executor delegate;
@Override
public int update(MappedStatement ms, Object parameterObject) throws SQLException {
flushCacheIfRequired(ms);
return delegate.update(ms, parameterObject);
}
}
方法中调用了delegate.update()
,这里调用的是Executor的实现类BaseExecutor中的update()
public abstract class BaseExecutor implements Executor {
@Override
public int update(MappedStatement ms, Object parameter) throws SQLException {
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);
}
}
update()
方法实现又调用了doUpdate()
protected abstract int doUpdate(MappedStatement ms, Object parameter)
throws SQLException;
它是一个抽象方法,找到BaseExecutor的实现类SimpleExecutor中的doUpdate()
public class SimpleExecutor extends BaseExecutor {
@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);j
}
}
}
其中调用了handler.update()
,这里的handler为StatementHandler类型,StatementHandler本身又是一个接口,需要找到它的实现类。直接实现类为BaseStatementHandler,它是一个抽象类,它的实现类PreparedStatementHandler。
public class PreparedStatementHandler extends BaseStatementHandler {
@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;
}
}
其中的update()
使用的仍然是JDBC中的PreparedStatement的execute()
。
3. 聚合函数getCount的源码分析
DAO接口的实现类中getCount()
的实现:
public class AccountDaoImpl implements AccountDao {
private SqlSessionFactory factory;
public int getCount() {
SqlSession session = factory.openSession();
int count = session.selectOne("dao.AccountDao.getCount");
session.close();
return count;
}
}
调用了SqlSession.selectOne()
。找SqlSession接口的实现类DefaultSqlSession中的selectOne()
public class DefaultSqlSession implements SqlSession {
@Override
public <T> T selectOne(String statement) {
return this.selectOne(statement, null);
}
@Override
public <T> T selectOne(String statement, Object parameter) {
// Popular vote was to return null on 0 results and throw exception on too many.
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;
}
}
}
它又调用了DefaultSqlSession中的selectList()
@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);
}
@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();
}
}
selectList()
中又调用了executor.query()
。这里同样找到Executor接口的实现类CachingExecutor中的方法实现。
public class CachingExecutor implements Executor {
@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
Cache cache = ms.getCache();
if (cache != null) {
flushCacheIfRequired(ms);
if (ms.isUseCache() && resultHandler == null) {
ensureNoOutParams(ms, boundSql);
@SuppressWarnings("unchecked")
List<E> list = (List<E>) tcm.getObject(cache, key);
if (list == null) {
list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
tcm.putObject(cache, key, list); // issue #578 and #116
}
return list;
}
}
return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
}
它又调用了delegate.query()
。delegate的类型为Executor的实现类CachingExecutor,继续看它的方法实现
public class CachingExecutor implements Executor {
@Override
public <E> List<E> query(MappedStatement ms, Object parameterObject, RowBounds rowBounds, ResultHandler resultHandler, CacheKey key, BoundSql boundSql)
throws SQLException {
Cache cache = ms.getCache();
if (cache != null) {
flushCacheIfRequired(ms);
if (ms.isUseCache() && resultHandler == null) {
ensureNoOutParams(ms, boundSql);
@SuppressWarnings("unchecked")
List<E> list = (List<E>) tcm.getObject(cache, key);
if (list == null) {
list = delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
tcm.putObject(cache, key, list); // issue #578 and #116
}
return list;
}
}
return delegate.query(ms, parameterObject, rowBounds, resultHandler, key, boundSql);
}
}
其中又调用了delegate.query
,delegate本身又是Executor类型的变量。因此,我们需要找到delegate对应的Executor接口的实现类,这里使用的是BaseExecutor。
public abstract class BaseExecutor implements Executor {
@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.");
}
if (queryStack == 0 && ms.isFlushCacheRequired()) {
clearLocalCache();
}
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 {
queryStack--;
}
if (queryStack == 0) {
for (DeferredLoad deferredLoad : deferredLoads) {
deferredLoad.load();
}
// issue #601
deferredLoads.clear();
if (configuration.getLocalCacheScope() == LocalCacheScope.STATEMENT) {
// issue #482
clearLocalCache();
}
}
return list;
}
}
其中又调用了queryFromDatabase()
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;
}
其中调用了doQuery()
。Executor本身是一个抽象类,故还需要继续找它的实现类SimpleExecutor中doQuery()
的实现:
public class SimpleExecutor extends BaseExecutor {
@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);
}
}
}
其中调用了handler.query()
,handler的定义为StatementHandler handler
,其中的StatementHandler 是以一个接口。这里接口的实现类使用的是RoutingStatementHandler
public class RoutingStatementHandler implements StatementHandler {
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
return delegate.query(statement, resultHandler);
}
}
而这里的delegate是StatementHandler接口的实现类PreparedStatementHandler类型的变量。
public class PreparedStatementHandler extends BaseStatementHandler {
@Override
public <E> List<E> query(Statement statement, ResultHandler resultHandler) throws SQLException {
PreparedStatement ps = (PreparedStatement) statement;
ps.execute();
return resultSetHandler.handleResultSets(ps);
}
}
PreparedStatementHandler中的query()
使用的就是JDBC中的PreparedStatement的execute()
,结果的封装使用了resultSetHandler接口的唯一实现类DefaultResultSetHandler中的handleResultSets()
。
public class DefaultResultSetHandler implements ResultSetHandler {
@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++;
}
}