org.apache.ibatis.executor.keygen.SelectKeyGenerator Java Examples

The following examples show how to use org.apache.ibatis.executor.keygen.SelectKeyGenerator. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: SimpleStatementHandler.java    From mybatis with Apache License 2.0 6 votes vote down vote up
@Override
public int update(Statement statement) throws SQLException {
  String sql = boundSql.getSql();
  Object parameterObject = boundSql.getParameterObject();
  KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
  int rows;
  if (keyGenerator instanceof Jdbc3KeyGenerator) {
    statement.execute(sql, Statement.RETURN_GENERATED_KEYS);
    rows = statement.getUpdateCount();
    keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
  } else if (keyGenerator instanceof SelectKeyGenerator) {
    statement.execute(sql);
    rows = statement.getUpdateCount();
    keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
  } else {
    //如果没有keyGenerator,直接调用Statement.execute和Statement.getUpdateCount
    statement.execute(sql);
    rows = statement.getUpdateCount();
  }
  return rows;
}
 
Example #2
Source File: RwRouteHandler.java    From azeroth with Apache License 2.0 6 votes vote down vote up
@Override
public Object onInterceptor(Invocation invocation) throws Throwable {

    Object[] objects = invocation.getArgs();
    MappedStatement ms = (MappedStatement) objects[0];
    //已指定强制使用
    if (DataSourceContextHolder.get().isForceUseMaster()) {
        logger.debug("Method[{}] force use Master..", ms.getId());
        return null;
    }

    //读方法
    if (ms.getSqlCommandType().equals(SqlCommandType.SELECT)) {
        //!selectKey 为自增id查询主键(SELECT LAST_INSERT_ID() )方法,使用主库
        if (!ms.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)) {
            DataSourceContextHolder.get().useSlave(true);
            logger.debug("Method[{} use Slave Strategy..", ms.getId());
        }
    } else {
        logger.debug("Method[{}] use Master Strategy..", ms.getId());
        DataSourceContextHolder.get().useSlave(false);
    }

    return null;
}
 
Example #3
Source File: RwRouteHandler.java    From jeesuite-libs with Apache License 2.0 6 votes vote down vote up
@Override
public Object onInterceptor(Invocation invocation) throws Throwable {
	
	Object[] objects = invocation.getArgs();
	MappedStatement ms = (MappedStatement) objects[0];
	//已指定强制使用
	if(MybatisRuntimeContext.isForceUseMaster()){
		logger.debug("Method[{}] force use Master..",ms.getId());
		return null;
	}
	
	//读方法
	if(ms.getSqlCommandType().equals(SqlCommandType.SELECT)){
		//!selectKey 为自增id查询主键(SELECT LAST_INSERT_ID() )方法,使用主库
		if(!ms.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)){				
			MybatisRuntimeContext.useSlave(true);
			logger.debug("Method[{} use Slave Strategy..",ms.getId());
		}
	}else{
		logger.debug("Method[{}] use Master Strategy..",ms.getId());
		MybatisRuntimeContext.useSlave(false);
	}
	
	return null;
}
 
Example #4
Source File: SimpleStatementHandler.java    From mybaties with Apache License 2.0 6 votes vote down vote up
@Override
public int update(Statement statement) throws SQLException {
  String sql = boundSql.getSql();
  Object parameterObject = boundSql.getParameterObject();
  KeyGenerator keyGenerator = mappedStatement.getKeyGenerator();
  int rows;
  if (keyGenerator instanceof Jdbc3KeyGenerator) {
    statement.execute(sql, Statement.RETURN_GENERATED_KEYS);
    rows = statement.getUpdateCount();
    keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
  } else if (keyGenerator instanceof SelectKeyGenerator) {
    statement.execute(sql);
    rows = statement.getUpdateCount();
    keyGenerator.processAfter(executor, mappedStatement, statement, parameterObject);
  } else {
    //如果没有keyGenerator,直接调用Statement.execute和Statement.getUpdateCount
    statement.execute(sql);
    rows = statement.getUpdateCount();
  }
  return rows;
}
 
Example #5
Source File: ExecutorTestHelper.java    From mybatis with Apache License 2.0 5 votes vote down vote up
public static MappedStatement prepareInsertAuthorMappedStatementWithBeforeAutoKey(final Configuration config) {
  final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
  final ResultMap rm = new ResultMap.Builder(config, "keyResultMap", Integer.class, new ArrayList<ResultMapping>())
      .build();

  MappedStatement kms = new MappedStatement.Builder(config, "insertAuthor!selectKey", new StaticSqlSource(config,"SELECT 123456 as id FROM SYSIBM.SYSDUMMY1"), SqlCommandType.SELECT)
      .keyProperty("id")
      .resultMaps(new ArrayList<ResultMap>() {
        {
          add(rm);
        }
      })
      .build();
  config.addMappedStatement(kms);
  MappedStatement ms = new MappedStatement.Builder(config, "insertAuthor", new DynamicSqlSource(config, new TextSqlNode("INSERT INTO author (id,username,password,email,bio,favourite_section) values(#{id},#{username},#{password},#{email},#{bio:VARCHAR},#{favouriteSection})")), SqlCommandType.INSERT)
      .parameterMap(
          new ParameterMap.Builder(config, "defaultParameterMap", Author.class, new ArrayList<ParameterMapping>() {
            {
              add(new ParameterMapping.Builder(config, "id", registry.getTypeHandler(Integer.class)).build());
              add(new ParameterMapping.Builder(config, "username", registry.getTypeHandler(String.class)).build());
              add(new ParameterMapping.Builder(config, "password", registry.getTypeHandler(String.class)).build());
              add(new ParameterMapping.Builder(config, "email", registry.getTypeHandler(String.class)).build());
              add(new ParameterMapping.Builder(config, "bio", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).build());
              add(new ParameterMapping.Builder(config, "favouriteSection", registry.getTypeHandler(Section.class)).jdbcType(JdbcType.VARCHAR).build());
            }
          }).build())
      .cache(authorCache)
      .keyGenerator(new SelectKeyGenerator(kms, true))
      .keyProperty("id")
      .build();
  return ms;
}
 
Example #6
Source File: XMLStatementBuilder.java    From mybatis with Apache License 2.0 5 votes vote down vote up
private void parseSelectKeyNode(String id, XNode nodeToHandle, Class<?> parameterTypeClass, LanguageDriver langDriver, String databaseId) {
  String resultType = nodeToHandle.getStringAttribute("resultType");
  Class<?> resultTypeClass = resolveClass(resultType);
  StatementType statementType = StatementType.valueOf(nodeToHandle.getStringAttribute("statementType", StatementType.PREPARED.toString()));
  String keyProperty = nodeToHandle.getStringAttribute("keyProperty");
  String keyColumn = nodeToHandle.getStringAttribute("keyColumn");
  boolean executeBefore = "BEFORE".equals(nodeToHandle.getStringAttribute("order", "AFTER"));

  //defaults
  boolean useCache = false;
  boolean resultOrdered = false;
  KeyGenerator keyGenerator = new NoKeyGenerator();
  Integer fetchSize = null;
  Integer timeout = null;
  boolean flushCache = false;
  String parameterMap = null;
  String resultMap = null;
  ResultSetType resultSetTypeEnum = null;

  SqlSource sqlSource = langDriver.createSqlSource(configuration, nodeToHandle, parameterTypeClass);
  SqlCommandType sqlCommandType = SqlCommandType.SELECT;

  builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
      fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
      resultSetTypeEnum, flushCache, useCache, resultOrdered,
      keyGenerator, keyProperty, keyColumn, databaseId, langDriver, null);

  id = builderAssistant.applyCurrentNamespace(id, false);

  MappedStatement keyStatement = configuration.getMappedStatement(id, false);
  configuration.addKeyGenerator(id, new SelectKeyGenerator(keyStatement, executeBefore));
}
 
Example #7
Source File: XMLStatementBuilder.java    From mybatis with Apache License 2.0 5 votes vote down vote up
private void parseSelectKeyNodes(String parentId, List<XNode> list, Class<?> parameterTypeClass, LanguageDriver langDriver, String skRequiredDatabaseId) {
  for (XNode nodeToHandle : list) {
    String id = parentId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
    String databaseId = nodeToHandle.getStringAttribute("databaseId");
    if (databaseIdMatchesCurrent(id, databaseId, skRequiredDatabaseId)) {
      parseSelectKeyNode(id, nodeToHandle, parameterTypeClass, langDriver, databaseId);
    }
  }
}
 
Example #8
Source File: MapperAnnotationBuilder.java    From mybatis with Apache License 2.0 5 votes vote down vote up
private KeyGenerator handleSelectKeyAnnotation(SelectKey selectKeyAnnotation, String baseStatementId, Class<?> parameterTypeClass, LanguageDriver languageDriver) {
  String id = baseStatementId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
  Class<?> resultTypeClass = selectKeyAnnotation.resultType();
  StatementType statementType = selectKeyAnnotation.statementType();
  String keyProperty = selectKeyAnnotation.keyProperty();
  String keyColumn = selectKeyAnnotation.keyColumn();
  boolean executeBefore = selectKeyAnnotation.before();

  // defaults
  boolean useCache = false;
  KeyGenerator keyGenerator = new NoKeyGenerator();
  Integer fetchSize = null;
  Integer timeout = null;
  boolean flushCache = false;
  String parameterMap = null;
  String resultMap = null;
  ResultSetType resultSetTypeEnum = null;

  SqlSource sqlSource = buildSqlSourceFromStrings(selectKeyAnnotation.statement(), parameterTypeClass, languageDriver);
  SqlCommandType sqlCommandType = SqlCommandType.SELECT;

  assistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum,
      flushCache, useCache, false,
      keyGenerator, keyProperty, keyColumn, null, languageDriver, null);

  id = assistant.applyCurrentNamespace(id, false);

  MappedStatement keyStatement = configuration.getMappedStatement(id, false);
  SelectKeyGenerator answer = new SelectKeyGenerator(keyStatement, executeBefore);
  configuration.addKeyGenerator(id, answer);
  return answer;
}
 
Example #9
Source File: DynamicDataSourcePlugin.java    From EasyReport with Apache License 2.0 5 votes vote down vote up
private DynamicDataSourceType getDynamicDataSourceType(final MappedStatement mappedStatement) {
    final DynamicDataSourceType dynamicDataSourceType = cacheMap.get(mappedStatement.getId());
    if (dynamicDataSourceType != null) {
        return dynamicDataSourceType;
    }
    //如是不是select语句则使用主库
    if (!SqlCommandType.SELECT.equals(mappedStatement.getSqlCommandType())) {
        return DynamicDataSourceType.WRITE;
    }
    //selectKey为自增id查询主键(SELECT LAST_INSERT_ID())方法,使用主库
    if (mappedStatement.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)) {
        return DynamicDataSourceType.WRITE;
    }
    return DynamicDataSourceType.READ;
}
 
Example #10
Source File: ExecutorTestHelper.java    From mybaties with Apache License 2.0 5 votes vote down vote up
public static MappedStatement prepareInsertAuthorMappedStatementWithBeforeAutoKey(final Configuration config) {
  final TypeHandlerRegistry registry = config.getTypeHandlerRegistry();
  final ResultMap rm = new ResultMap.Builder(config, "keyResultMap", Integer.class, new ArrayList<ResultMapping>())
      .build();

  MappedStatement kms = new MappedStatement.Builder(config, "insertAuthor!selectKey", new StaticSqlSource(config,"SELECT 123456 as id FROM SYSIBM.SYSDUMMY1"), SqlCommandType.SELECT)
      .keyProperty("id")
      .resultMaps(new ArrayList<ResultMap>() {
        {
          add(rm);
        }
      })
      .build();
  config.addMappedStatement(kms);
  MappedStatement ms = new MappedStatement.Builder(config, "insertAuthor", new DynamicSqlSource(config, new TextSqlNode("INSERT INTO author (id,username,password,email,bio,favourite_section) values(#{id},#{username},#{password},#{email},#{bio:VARCHAR},#{favouriteSection})")), SqlCommandType.INSERT)
      .parameterMap(
          new ParameterMap.Builder(config, "defaultParameterMap", Author.class, new ArrayList<ParameterMapping>() {
            {
              add(new ParameterMapping.Builder(config, "id", registry.getTypeHandler(Integer.class)).build());
              add(new ParameterMapping.Builder(config, "username", registry.getTypeHandler(String.class)).build());
              add(new ParameterMapping.Builder(config, "password", registry.getTypeHandler(String.class)).build());
              add(new ParameterMapping.Builder(config, "email", registry.getTypeHandler(String.class)).build());
              add(new ParameterMapping.Builder(config, "bio", registry.getTypeHandler(String.class)).jdbcType(JdbcType.VARCHAR).build());
              add(new ParameterMapping.Builder(config, "favouriteSection", registry.getTypeHandler(Section.class)).jdbcType(JdbcType.VARCHAR).build());
            }
          }).build())
      .cache(authorCache)
      .keyGenerator(new SelectKeyGenerator(kms, true))
      .keyProperty("id")
      .build();
  return ms;
}
 
Example #11
Source File: XMLStatementBuilder.java    From mybaties with Apache License 2.0 5 votes vote down vote up
private void parseSelectKeyNode(String id, XNode nodeToHandle, Class<?> parameterTypeClass, LanguageDriver langDriver, String databaseId) {
  String resultType = nodeToHandle.getStringAttribute("resultType");
  Class<?> resultTypeClass = resolveClass(resultType);
  StatementType statementType = StatementType.valueOf(nodeToHandle.getStringAttribute("statementType", StatementType.PREPARED.toString()));
  String keyProperty = nodeToHandle.getStringAttribute("keyProperty");
  String keyColumn = nodeToHandle.getStringAttribute("keyColumn");
  boolean executeBefore = "BEFORE".equals(nodeToHandle.getStringAttribute("order", "AFTER"));

  //defaults
  boolean useCache = false;
  boolean resultOrdered = false;
  KeyGenerator keyGenerator = new NoKeyGenerator();
  Integer fetchSize = null;
  Integer timeout = null;
  boolean flushCache = false;
  String parameterMap = null;
  String resultMap = null;
  ResultSetType resultSetTypeEnum = null;

  SqlSource sqlSource = langDriver.createSqlSource(configuration, nodeToHandle, parameterTypeClass);
  SqlCommandType sqlCommandType = SqlCommandType.SELECT;

  builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
      fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
      resultSetTypeEnum, flushCache, useCache, resultOrdered,
      keyGenerator, keyProperty, keyColumn, databaseId, langDriver, null);

  id = builderAssistant.applyCurrentNamespace(id, false);

  MappedStatement keyStatement = configuration.getMappedStatement(id, false);
  configuration.addKeyGenerator(id, new SelectKeyGenerator(keyStatement, executeBefore));
}
 
Example #12
Source File: XMLStatementBuilder.java    From mybaties with Apache License 2.0 5 votes vote down vote up
private void parseSelectKeyNodes(String parentId, List<XNode> list, Class<?> parameterTypeClass, LanguageDriver langDriver, String skRequiredDatabaseId) {
  for (XNode nodeToHandle : list) {
    String id = parentId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
    String databaseId = nodeToHandle.getStringAttribute("databaseId");
    if (databaseIdMatchesCurrent(id, databaseId, skRequiredDatabaseId)) {
      parseSelectKeyNode(id, nodeToHandle, parameterTypeClass, langDriver, databaseId);
    }
  }
}
 
Example #13
Source File: MapperAnnotationBuilder.java    From mybaties with Apache License 2.0 5 votes vote down vote up
private KeyGenerator handleSelectKeyAnnotation(SelectKey selectKeyAnnotation, String baseStatementId, Class<?> parameterTypeClass, LanguageDriver languageDriver) {
  String id = baseStatementId + SelectKeyGenerator.SELECT_KEY_SUFFIX;
  Class<?> resultTypeClass = selectKeyAnnotation.resultType();
  StatementType statementType = selectKeyAnnotation.statementType();
  String keyProperty = selectKeyAnnotation.keyProperty();
  String keyColumn = selectKeyAnnotation.keyColumn();
  boolean executeBefore = selectKeyAnnotation.before();

  // defaults
  boolean useCache = false;
  KeyGenerator keyGenerator = new NoKeyGenerator();
  Integer fetchSize = null;
  Integer timeout = null;
  boolean flushCache = false;
  String parameterMap = null;
  String resultMap = null;
  ResultSetType resultSetTypeEnum = null;

  SqlSource sqlSource = buildSqlSourceFromStrings(selectKeyAnnotation.statement(), parameterTypeClass, languageDriver);
  SqlCommandType sqlCommandType = SqlCommandType.SELECT;

  assistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType, fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass, resultSetTypeEnum,
      flushCache, useCache, false,
      keyGenerator, keyProperty, keyColumn, null, languageDriver, null);

  id = assistant.applyCurrentNamespace(id, false);

  MappedStatement keyStatement = configuration.getMappedStatement(id, false);
  SelectKeyGenerator answer = new SelectKeyGenerator(keyStatement, executeBefore);
  configuration.addKeyGenerator(id, answer);
  return answer;
}
 
Example #14
Source File: DynamicDataSourcePlugin.java    From dk-foundation with GNU Lesser General Public License v2.1 5 votes vote down vote up
@Override
public Object intercept(Invocation invocation) throws Throwable {
    boolean synchronizationActive = TransactionSynchronizationManager.isSynchronizationActive();
    if(!synchronizationActive) {
        Object[] objects = invocation.getArgs();
        MappedStatement ms = (MappedStatement) objects[0];
        String dataSourceKey="";
        if((dataSourceKey = CACHE_MAP.get(ms.getId())) == null) {
            if(ms.getSqlCommandType().equals(SqlCommandType.SELECT)) {
                //!selectKey 为自增id查询主键(SELECT LAST_INSERT_ID() )方法,使用主库
                if(ms.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)) {
                    dataSourceKey = DynamicDataSourceKey.MASTER;
                } else {
                    BoundSql boundSql = ms.getSqlSource().getBoundSql(objects[1]);
                    String sql = boundSql.getSql().replaceAll("[\\t\\n\\r]", " ");
                    if(PATTERN.matcher(sql).matches()) {
                        dataSourceKey = DynamicDataSourceKey.MASTER;
                    } else {
                        dataSourceKey = DynamicDataSourceKey.READ_RANDOM_PROXY;
                    }
                }
            }else{
                dataSourceKey = DynamicDataSourceKey.MASTER;
            }
            logger.warn("Method [{}] use [{}] Strategy, SqlCommandType [{}].", ms.getId(), dataSourceKey, ms.getSqlCommandType().name());
            CACHE_MAP.put(ms.getId(), dataSourceKey);
        }
        DynamicDataSourceKey.setDataSource(dataSourceKey,false);
    }

    return invocation.proceed();
}
 
Example #15
Source File: XMLStatementBuilder.java    From mybatis with Apache License 2.0 4 votes vote down vote up
public void parseStatementNode() {
   String id = context.getStringAttribute("id");
   String databaseId = context.getStringAttribute("databaseId");

   //如果databaseId不匹配,退出
   if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
     return;
   }

   //暗示驱动程序每次批量返回的结果行数
   Integer fetchSize = context.getIntAttribute("fetchSize");
   //超时时间
   Integer timeout = context.getIntAttribute("timeout");
   //引用外部 parameterMap,已废弃
   String parameterMap = context.getStringAttribute("parameterMap");
   //参数类型
   String parameterType = context.getStringAttribute("parameterType");
   Class<?> parameterTypeClass = resolveClass(parameterType);
   //引用外部的 resultMap(高级功能)
   String resultMap = context.getStringAttribute("resultMap");
   //结果类型
   String resultType = context.getStringAttribute("resultType");
   //脚本语言,mybatis3.2的新功能
   String lang = context.getStringAttribute("lang");
   //得到语言驱动
   LanguageDriver langDriver = getLanguageDriver(lang);

   Class<?> resultTypeClass = resolveClass(resultType);
   //结果集类型,FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE 中的一种
   String resultSetType = context.getStringAttribute("resultSetType");
   //语句类型, STATEMENT|PREPARED|CALLABLE 的一种
   StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
   ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);

   //获取命令类型(select|insert|update|delete)
   String nodeName = context.getNode().getNodeName();
   SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
   boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
   boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
   //是否要缓存select结果
   boolean useCache = context.getBooleanAttribute("useCache", isSelect);
   //仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。
   //这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。 
   boolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);

   // Include Fragments before parsing
   //解析之前先解析<include>SQL片段
   XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
   includeParser.applyIncludes(context.getNode());

   // Parse selectKey after includes and remove them.
   //解析之前先解析<selectKey>
   processSelectKeyNodes(id, parameterTypeClass, langDriver);
   
   // Parse the SQL (pre: <selectKey> and <include> were parsed and removed)
   //解析成SqlSource,一般是DynamicSqlSource
   SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
   String resultSets = context.getStringAttribute("resultSets");
   //(仅对 insert 有用) 标记一个属性, MyBatis 会通过 getGeneratedKeys 或者通过 insert 语句的 selectKey 子元素设置它的值
   String keyProperty = context.getStringAttribute("keyProperty");
   //(仅对 insert 有用) 标记一个属性, MyBatis 会通过 getGeneratedKeys 或者通过 insert 语句的 selectKey 子元素设置它的值
   String keyColumn = context.getStringAttribute("keyColumn");
   KeyGenerator keyGenerator;
   String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
   keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
   if (configuration.hasKeyGenerator(keyStatementId)) {
     keyGenerator = configuration.getKeyGenerator(keyStatementId);
   } else {
     keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
         configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))
         ? new Jdbc3KeyGenerator() : new NoKeyGenerator();
   }

//又去调助手类
   builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
       fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
       resultSetTypeEnum, flushCache, useCache, resultOrdered, 
       keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
 }
 
Example #16
Source File: XMLStatementBuilder.java    From mybaties with Apache License 2.0 4 votes vote down vote up
public void parseStatementNode() {
   String id = context.getStringAttribute("id");
   String databaseId = context.getStringAttribute("databaseId");

   //如果databaseId不匹配,退出
   if (!databaseIdMatchesCurrent(id, databaseId, this.requiredDatabaseId)) {
     return;
   }

   //暗示驱动程序每次批量返回的结果行数
   Integer fetchSize = context.getIntAttribute("fetchSize");
   //超时时间
   Integer timeout = context.getIntAttribute("timeout");
   //引用外部 parameterMap,已废弃
   String parameterMap = context.getStringAttribute("parameterMap");
   //参数类型
   String parameterType = context.getStringAttribute("parameterType");
   Class<?> parameterTypeClass = resolveClass(parameterType);
   //引用外部的 resultMap(高级功能)
   String resultMap = context.getStringAttribute("resultMap");
   //结果类型
   String resultType = context.getStringAttribute("resultType");
   //脚本语言,mybatis3.2的新功能
   String lang = context.getStringAttribute("lang");
   //得到语言驱动
   LanguageDriver langDriver = getLanguageDriver(lang);

   Class<?> resultTypeClass = resolveClass(resultType);
   //结果集类型,FORWARD_ONLY|SCROLL_SENSITIVE|SCROLL_INSENSITIVE 中的一种
   String resultSetType = context.getStringAttribute("resultSetType");
   //语句类型, STATEMENT|PREPARED|CALLABLE 的一种
   StatementType statementType = StatementType.valueOf(context.getStringAttribute("statementType", StatementType.PREPARED.toString()));
   ResultSetType resultSetTypeEnum = resolveResultSetType(resultSetType);

   //获取命令类型(select|insert|update|delete)
   String nodeName = context.getNode().getNodeName();
   SqlCommandType sqlCommandType = SqlCommandType.valueOf(nodeName.toUpperCase(Locale.ENGLISH));
   boolean isSelect = sqlCommandType == SqlCommandType.SELECT;
   boolean flushCache = context.getBooleanAttribute("flushCache", !isSelect);
   //是否要缓存select结果
   boolean useCache = context.getBooleanAttribute("useCache", isSelect);
   //仅针对嵌套结果 select 语句适用:如果为 true,就是假设包含了嵌套结果集或是分组了,这样的话当返回一个主结果行的时候,就不会发生有对前面结果集的引用的情况。
   //这就使得在获取嵌套的结果集的时候不至于导致内存不够用。默认值:false。 
   boolean resultOrdered = context.getBooleanAttribute("resultOrdered", false);

   // Include Fragments before parsing
   //解析之前先解析<include>SQL片段
   XMLIncludeTransformer includeParser = new XMLIncludeTransformer(configuration, builderAssistant);
   includeParser.applyIncludes(context.getNode());

   // Parse selectKey after includes and remove them.
   //解析之前先解析<selectKey>
   processSelectKeyNodes(id, parameterTypeClass, langDriver);
   
   // Parse the SQL (pre: <selectKey> and <include> were parsed and removed)
   //解析成SqlSource,一般是DynamicSqlSource
   SqlSource sqlSource = langDriver.createSqlSource(configuration, context, parameterTypeClass);
   String resultSets = context.getStringAttribute("resultSets");
   //(仅对 insert 有用) 标记一个属性, MyBatis 会通过 getGeneratedKeys 或者通过 insert 语句的 selectKey 子元素设置它的值
   String keyProperty = context.getStringAttribute("keyProperty");
   //(仅对 insert 有用) 标记一个属性, MyBatis 会通过 getGeneratedKeys 或者通过 insert 语句的 selectKey 子元素设置它的值
   String keyColumn = context.getStringAttribute("keyColumn");
   KeyGenerator keyGenerator;
   String keyStatementId = id + SelectKeyGenerator.SELECT_KEY_SUFFIX;
   keyStatementId = builderAssistant.applyCurrentNamespace(keyStatementId, true);
   if (configuration.hasKeyGenerator(keyStatementId)) {
     keyGenerator = configuration.getKeyGenerator(keyStatementId);
   } else {
     keyGenerator = context.getBooleanAttribute("useGeneratedKeys",
         configuration.isUseGeneratedKeys() && SqlCommandType.INSERT.equals(sqlCommandType))
         ? new Jdbc3KeyGenerator() : new NoKeyGenerator();
   }

//又去调助手类
   builderAssistant.addMappedStatement(id, sqlSource, statementType, sqlCommandType,
       fetchSize, timeout, parameterMap, parameterTypeClass, resultMap, resultTypeClass,
       resultSetTypeEnum, flushCache, useCache, resultOrdered, 
       keyGenerator, keyProperty, keyColumn, databaseId, langDriver, resultSets);
 }
 
Example #17
Source File: DynamicDataSourceInterceptor.java    From Project with Apache License 2.0 4 votes vote down vote up
@Override
// 下面方法拦截之后,决定使用哪一个数据源
public Object intercept(Invocation invocation) throws Throwable {
    boolean synchronizationActive =
            TransactionSynchronizationManager.isActualTransactionActive();
    // 接收 mybatis传过来的操作的参数,然后进行比对;
    Object[] objects = invocation.getArgs();
    // 相当于获取 SQL 语句最前面,就是SQL是增?删?。。
    MappedStatement ms = (MappedStatement) objects[0];
    String lookupKey =  DynamicDataSourceHolder.DB_MASTER;
    // 如果操作时事务的
    if (synchronizationActive != true){

        // 读方法
        if (ms.getSqlCommandType().equals(SqlCommandType.SELECT)){
            // 如果 selectKey 为自增 id 查询主键,即mybatis 使用了select Last_insert_ID(),方法, 这是用使用主库
            if (ms.getId().contains(SelectKeyGenerator.SELECT_KEY_SUFFIX)){
                lookupKey = DynamicDataSourceHolder.DB_MASTER;
            }else{
                // 获取 SQL 语句,然后将所有的制表符、换行符等等换成空格;
                BoundSql boundSql = ms.getSqlSource().getBoundSql(objects[1]);
                String sql = boundSql.getSql().toLowerCase(Locale.CHINA).replaceAll("[\\t\\n" +
                        "\\r]"," ");
                // 使用正则判断是不是插入、删除、更新方法;
                if (sql.matches(REGEX)){
                    lookupKey = DynamicDataSourceHolder.DB_MASTER;
                }else {
                    lookupKey = DynamicDataSourceHolder.DB_SLAVE;
                }
            }
        }
    }else {
        // 如果是事务操作,一般都是写操作,使用主库
        lookupKey = DynamicDataSourceHolder.DB_MASTER;
    }
    // 日志信息
    logger.debug("设置的方法[{}] use [{}] Strategy, SqlCommanType [{}]..",ms.getId(), lookupKey,
            ms.getSqlCommandType().name());

    DynamicDataSourceHolder.setDbType(lookupKey);
    // 然后正式开始进行操作
    return invocation.proceed();
}