一、源码追踪
映射器(Mapper)的动态代理
RoleMapper roleMapper = sqlSession.getMapper(RoleMapper.class);
public <T> T getMapper(Class<T> type, SqlSession sqlSession) {
MapperProxyFactory<T> mapperProxyFactory = (MapperProxyFactory)this.knownMappers.get(type);
if (mapperProxyFactory == null) {
throw new BindingException("Type " + type + " is not known to the MapperRegistry.");
} else {
try {
return mapperProxyFactory.newInstance(sqlSession);
} catch (Exception var5) {
throw new BindingException("Error getting mapper instance. Cause: " + var5, var5);
}
}
}
protected T newInstance(MapperProxy<T> mapperProxy) {
return Proxy.newProxyInstance(this.mapperInterface.getClassLoader(), new Class[]{this.mapperInterface}, mapperProxy);
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
if (Object.class.equals(method.getDeclaringClass())) {
return method.invoke(this, args);
}
if (method.isDefault()) {
return this.invokeDefaultMethod(proxy, method, args);
}
} catch (Throwable var5) {
throw ExceptionUtil.unwrapThrowable(var5);
}
MapperMethod mapperMethod = this.cachedMapperMethod(method);
return mapperMethod.execute(this.sqlSession, args);
}
Mapper映射是通过JDK动态代理来实现的
二、SqlSession流程图
SqlSession执行过程通过Executor、StatementHandler、ParameterHandler和ResultSetHandler来完成数据库操作和结果返回的
- Executor代表执行器:由它调度StatementHandler、ParameterHandler、ResultSetHandler等来执行对应的SQL
- StatementHandler的作用是使用数据库的Statement(PreparedStatement)执行操作,是四大对象的核心,起到承上启下的作用,许多重要的插件都是通过拦截它来实现的
- ParameterHandler是用来处理SQL参数的
- ResultSetHandler是进行数据集(ResultSet)的封装返回处理的。
Executor-执行器:
MyBatis根据Configuration来构建StatementHandler,然后使用prepareStatement方法,对SQL编译和参数进行初始化。
实现过程:
- 调用了StatementHandler的prepare()进行了预编译和基础的设置(比如超时、获取的最大行数的设置)
- 然后通过StatementHandler的parameterize()来设置参数
- 最后使用StatementHandler的query方法,吧ResultHandler传递进去
StatementHandler-数据库会话器
ParameterHandler-参数处理器
ResultSetHandler-结果处理器
总结
SqlSession是通过执行器Executor调度StatementHandler来运行的,而StatementHandler经过3步:
- prepared预编译SQL
- parameterize设置参数
- query/update执行SQL
parameterize是调用parameterHandler的方法设置的,而参数是根据类型转换器typeHandler处理的。
query/update方法通过ResultSetHandler进行处理结果的封装,如果是update语句,就返回整数,否则就通过typeHandler处理结果类型,然后用ObjectFactory提供的规则组装对象,返回给调用者。