@Override
  public void select(
      final String statementName, final Object parameterObject, final ResultHandler handler) {
    if (isSqlAuditorBehaviorEnabled()) {
      getSqlAuditor()
          .audit(
              statementName,
              getSqlByStatementName(statementName, parameterObject),
              parameterObject);
    }
    if (isPartitioningBehaviorEnabled()) {
      SortedMap<String, DataSource> dsMap =
          lookupDataSourcesByRouter(statementName, parameterObject);
      if (dsMap != null && !dsMap.isEmpty()) {
        SqlSessionCallback action =
            new SqlSessionCallback() {
              @Override
              public Object doInSession(SqlSession sqlSession) {
                sqlSession.select(statementName, parameterObject, handler);
                return null;
              }
            };

        if (dsMap.size() == 1) {
          executeWith(dsMap.get(dsMap.firstKey()), action);
        } else {
          executeInConcurrency(action, dsMap);
        }
      }
    }
    super.select(statementName, parameterObject, handler);
  }
 protected SortedMap<String, DataSource> lookupDataSourcesByRouter(
     final String statementName, final Object parameterObject) {
   SortedMap<String, DataSource> resultMap = new TreeMap<String, DataSource>();
   String namespace = StringUtils.substringBeforeLast(statementName, ".");
   String dsName = shardStrategy.getShardIdentitiesByNamespace(namespace, parameterObject);
   if (dsName == null) {
     throw new IllegalStateException("无法找到相应的分库资源,请检查参数列表中是否有传分库字段值, 参数:" + parameterObject);
   }
   resultMap.put(dsName, shardDataSourceService.getDataSources().get(dsName));
   return resultMap;
 }
  @Override
  public Map<?, ?> selectMap(
      final String statementName,
      final Object parameterObject,
      final String mapKey,
      final RowBounds rowBounds) {
    if (isSqlAuditorBehaviorEnabled()) {
      getSqlAuditor()
          .audit(
              statementName,
              getSqlByStatementName(statementName, parameterObject),
              parameterObject);
    }
    if (isPartitioningBehaviorEnabled()) {
      SortedMap<String, DataSource> dsMap =
          lookupDataSourcesByRouter(statementName, parameterObject);
      if (dsMap != null && !dsMap.isEmpty()) {

        SqlSessionCallback action =
            new SqlSessionCallback<Map<?, ?>>() {
              @Override
              public Map<?, ?> doInSession(SqlSession sqlSession) {
                return sqlSession.selectMap(statementName, parameterObject, mapKey, rowBounds);
              }
            };

        if (dsMap.size() == 1) {
          return (Map<?, ?>) executeWith(dsMap.get(dsMap.firstKey()), action);
        } else {
          List<Object> results = executeInConcurrency(action, dsMap);
          Map<?, ?> retVal = Maps.newHashMap();
          if (results != null && !results.isEmpty()) {
            for (int i = 0; i < results.size(); i++) {
              retVal.putAll((Map) results.get(i));
            }
          }

          return retVal;
        }
      }
    }

    return super.selectMap(statementName, parameterObject, mapKey, rowBounds);
  }
  protected List<Object> executeInConcurrency(
      SqlSessionCallback action, SortedMap<String, DataSource> dsMap) {
    List<ConcurrentShardRequest> requests = Lists.newArrayList();

    for (Map.Entry<String, DataSource> entry : dsMap.entrySet()) {
      ConcurrentShardRequest request = new ConcurrentShardRequest();
      request.setAction(action);
      request.setDataSource(entry.getValue());
      request.setExecutor(dataSourceSpecificExecutors.get(entry.getKey()));
      requests.add(request);
    }
    return getConcurrentShardRequestProcessor().process(requests);
  }
  /**
   * 更新记录
   *
   * @param statementName
   * @param parameterObject
   * @return
   */
  @Override
  public int update(final String statementName, final Object parameterObject) {
    if (isSqlAuditorBehaviorEnabled()) {
      getSqlAuditor()
          .audit(
              statementName,
              getSqlByStatementName(statementName, parameterObject),
              parameterObject);
    }
    if (isPartitioningBehaviorEnabled()) {
      SortedMap<String, DataSource> dsMap =
          lookupDataSourcesByRouter(statementName, parameterObject);
      if (dsMap != null && !dsMap.isEmpty()) {
        SqlSessionCallback action =
            new SqlSessionCallback() {
              @Override
              public Object doInSession(SqlSession sqlSession) {
                return sqlSession.update(statementName, parameterObject);
              }
            };

        if (dsMap.size() == 1) {
          return (Integer) executeWith(dsMap.get(dsMap.firstKey()), action);
        } else {
          List<Object> results = executeInConcurrency(action, dsMap);

          Integer rowAffected = 0;

          if (results != null && !results.isEmpty()) {
            for (Object item : results) {
              rowAffected += (Integer) item;
            }
          }
          return rowAffected;
        }
      }
    }
    return super.update(statementName, parameterObject);
  }