建造者
public class SqlSessionFactoryBuilder {
// 省略
public SqlSessionFactory build(Reader reader, String environment,
Properties properties) {
try {
XMLConfigBuilder parser = new XMLConfigBuilder(reader,
environment, properties);
return build(parser.parse());
} catch (Exception e) {
throw ExceptionFactory.wrapException("Error building SqlSession.", e);
} finally {
ErrorContext.instance().reset();
try {
reader.close();
} catch (IOException e) {
// Intentionally ignore. Prefer previous error.
}
}
}
public SqlSessionFactory build(InputStream inputStream) {
return build(inputStream, null, null);
}
public SqlSessionFactory build(InputStream inputStream, String environment) {
return build(inputStream, environment, null);
}
// 省略
}
建造者设计模式作用:分离对象的属性与创建过程。mybatis 有大量的可配置属性,如果都需要用户去配置,框架的使用成本太高了。SqlSessionFactoryBuilder 对外隐藏了框架解析 xml 的细节,只使用必须的参数帮用户创建对象,如果没有配置的参数直接使用了默认值,降低了框架的使用成本。
模版
BaseExecutor
public abstract class BaseExecutor implements Executor {
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;
}
BaseExecutor 定义了很多方法的执行流程,具体的执行抽象出来交给子类去实现。
责任链
public class InterceptorChain {
private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
public Object pluginAll(Object target) {
for (Interceptor interceptor : interceptors) {
target = interceptor.plugin(target);
}
return target;
}
public void addInterceptor(Interceptor interceptor) {
interceptors.add(interceptor);
}
public List<Interceptor> getInterceptors() {
return Collections.unmodifiableList(interceptors);
}
}
这里定义了一个拦截器链,用于mybatis插件扩展。mybais 插件可以在 sql 执行前后拦截做一些定制化的处理;
代理
class PooledConnection implements InvocationHandler {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
String methodName = method.getName();
if (CLOSE.hashCode() == methodName.hashCode() && CLOSE.equals(methodName)) {
dataSource.pushConnection(this);
return null;
} else {
try {
if (!Object.class.equals(method.getDeclaringClass())) {
// issue #579 toString() should never fail
// throw an SQLException instead of a Runtime
checkConnection();
}
return method.invoke(realConnection, args);
} catch (Throwable t) {
throw ExceptionUtil.unwrapThrowable(t);
}
}
}
}
装饰器
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);
}
}
此处装饰Executor,给 Executor 添加缓存功能。