建造者

  1. public class SqlSessionFactoryBuilder {
  2. // 省略
  3. public SqlSessionFactory build(Reader reader, String environment,
  4. Properties properties) {
  5. try {
  6. XMLConfigBuilder parser = new XMLConfigBuilder(reader,
  7. environment, properties);
  8. return build(parser.parse());
  9. } catch (Exception e) {
  10. throw ExceptionFactory.wrapException("Error building SqlSession.", e);
  11. } finally {
  12. ErrorContext.instance().reset();
  13. try {
  14. reader.close();
  15. } catch (IOException e) {
  16. // Intentionally ignore. Prefer previous error.
  17. }
  18. }
  19. }
  20. public SqlSessionFactory build(InputStream inputStream) {
  21. return build(inputStream, null, null);
  22. }
  23. public SqlSessionFactory build(InputStream inputStream, String environment) {
  24. return build(inputStream, environment, null);
  25. }
  26. // 省略
  27. }

建造者设计模式作用:分离对象的属性与创建过程。mybatis 有大量的可配置属性,如果都需要用户去配置,框架的使用成本太高了。SqlSessionFactoryBuilder 对外隐藏了框架解析 xml 的细节,只使用必须的参数帮用户创建对象,如果没有配置的参数直接使用了默认值,降低了框架的使用成本。

模版

BaseExecutor

  1. public abstract class BaseExecutor implements Executor {
  2. protected abstract int doUpdate(MappedStatement ms, Object parameter)
  3. throws SQLException;
  4. protected abstract List<BatchResult> doFlushStatements(boolean isRollback)
  5. throws SQLException;
  6. protected abstract <E> List<E> doQuery(MappedStatement ms, Object parameter, RowBounds rowBounds, ResultHandler resultHandler, BoundSql boundSql)
  7. throws SQLException;
  8. protected abstract <E> Cursor<E> doQueryCursor(MappedStatement ms, Object parameter, RowBounds rowBounds, BoundSql boundSql)
  9. throws SQLException;
  10. }

BaseExecutor 定义了很多方法的执行流程,具体的执行抽象出来交给子类去实现。

责任链

  1. public class InterceptorChain {
  2. private final List<Interceptor> interceptors = new ArrayList<Interceptor>();
  3. public Object pluginAll(Object target) {
  4. for (Interceptor interceptor : interceptors) {
  5. target = interceptor.plugin(target);
  6. }
  7. return target;
  8. }
  9. public void addInterceptor(Interceptor interceptor) {
  10. interceptors.add(interceptor);
  11. }
  12. public List<Interceptor> getInterceptors() {
  13. return Collections.unmodifiableList(interceptors);
  14. }
  15. }

这里定义了一个拦截器链,用于mybatis插件扩展。mybais 插件可以在 sql 执行前后拦截做一些定制化的处理;

代理

  1. class PooledConnection implements InvocationHandler {
  2. @Override
  3. public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
  4. String methodName = method.getName();
  5. if (CLOSE.hashCode() == methodName.hashCode() && CLOSE.equals(methodName)) {
  6. dataSource.pushConnection(this);
  7. return null;
  8. } else {
  9. try {
  10. if (!Object.class.equals(method.getDeclaringClass())) {
  11. // issue #579 toString() should never fail
  12. // throw an SQLException instead of a Runtime
  13. checkConnection();
  14. }
  15. return method.invoke(realConnection, args);
  16. } catch (Throwable t) {
  17. throw ExceptionUtil.unwrapThrowable(t);
  18. }
  19. }
  20. }
  21. }

装饰器

  1. public class CachingExecutor implements Executor {
  2. private final Executor delegate;
  3. private final TransactionalCacheManager tcm = new TransactionalCacheManager();
  4. public CachingExecutor(Executor delegate) {
  5. this.delegate = delegate;
  6. delegate.setExecutorWrapper(this);
  7. }
  8. }

此处装饰Executor,给 Executor 添加缓存功能。