首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >MyBatis内部查询

MyBatis内部查询
EN

Stack Overflow用户
提问于 2016-01-12 04:08:18
回答 1查看 756关注 0票数 0

在我的代码库中,我们有一个如下所示的MyBatis查询,

代码语言:javascript
复制
INSERT INTO TABLE_A(
        ID,
        NAME,
        VERSION
    )
    VALUES  (
        #id#,
        #name#,
        (select NVL(max(version), 0 ) + 1 from SAE_PROC_SETTING where name = #name#)
    )

unique约束针对列名和版本。如果多个用户同时插入值,有时我们会得到唯一的约束错误。当我们检查时,名称和版本是相同的,并如预期的那样抛出错误。

我的问题是,MyBatis如何处理内部查询

代码语言:javascript
复制
(select NVL(max(version), 0 ) + 1 from TABLE_Awhere name = #name#)

这个查询是由Oracle提交给oracle,然后MyBatis先执行SELECT,然后执行INSERT查询,还是MyBatis先执行SELECT,然后替换INSERT中的值,然后在Oracle中提交INSERT查询(由MyBatis执行2步)?

如果像第二个选项一样处理,当两个人同时使用相同的名称插入时,两个人都有可能获得相同的版本。然后,当尝试插入时,我们将得到UniqueConstraint错误。

请让我知道MyBatis是如何在内部处理这个问题的。任何指针都可以。

谢谢,SD

EN

回答 1

Stack Overflow用户

发布于 2016-07-26 23:50:27

MyBatis只是替换查询参数,然后通过prepareStatement传递查询。

日志将insert显示为一条语句。

代码语言:javascript
复制
2016-07-26 17:34:23.776 DEBUG 91036 --- [           main] sample.mybatis.mapper.CityMapper.insert  : ==>  Preparing: insert into city (name, state, country) values ((select DISTINCT 'a' from city), 'CA', 'US'); 
2016-07-26 17:34:23.777 DEBUG 91036 --- [           main] sample.mybatis.mapper.CityMapper.insert  : ==> Parameters: 
2016-07-26 17:34:23.779 DEBUG 91036 --- [           main] sample.mybatis.mapper.CityMapper.insert  : <==    Updates: 1

然后我调试它,当它被调用这个方法(source github)时,只需传递INSERT case:

代码语言:javascript
复制
public Object execute(SqlSession sqlSession, Object[] args) {
    Object result;
    switch (command.getType()) {

      case INSERT: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.insert(command.getName(), param));
        break;
      }
      case UPDATE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.update(command.getName(), param));
        break;
      }
      case DELETE: {
        Object param = method.convertArgsToSqlCommandParam(args);
        result = rowCountResult(sqlSession.delete(command.getName(), param));
        break;
      }
      case SELECT:
       .....
          Object param = method.convertArgsToSqlCommandParam(args);
          result = sqlSession.selectOne(command.getName(), param);
       ....
        }
        break;
      case FLUSH:
        result = sqlSession.flushStatements();
        break;
      default:
        throw new BindingException("Unknown execution method for: " + command.getName());
    }
    ....
  }
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34730156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档