在mybatis中如何在执行真正的sql之前优雅地检查参数?

时间:2015-01-18 14:32:24

标签: mybatis

例如,有一个这样的dao:

void batchInsert(List<User> userList); 
List<User> getUsersByIds(List<Long> idList); 
void deleteUsersByids(List<Long> idList); 

如果List的参数为空,则抛出异常,因为sql是错误的.eg,

mysql> select * from tb_user where id in () ;
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ')' at line 1

作为开发者,我不想关心这一点。如果参数为null(或为空),则只返回,不要继续执行sql。

通过跟踪mybatis源代码,我找到了一个方法。 这是org.mybatis.spring.SqlSessionTemplate的修改源代码。例如, 我们可以在selectList中添加check参数逻辑:

 public <E> List<E> selectList(String statement, Object parameter) {
  if(parameter instanceof List){
      if(((List) parameter).isEmpty()){
        List<E> result =  new ArrayList<>();
        return result;
      }
  }
return this.sqlSessionProxy.<E> selectList(statement, parameter);

}

并且可以在更新,删除,插入方法中这样做。但我觉得这种方法并不好。所以我想知道这个要求是否有更好的方法?

1 个答案:

答案 0 :(得分:0)

至少在mybatis中使这个解决方案通用并不容易。你建议的方法不起作用。请考虑以下selectList调用:

selectList("SELECT * FROM table WHERE NOT (id IN ())", new ArrayList()) 

随着您的修改,它将返回空列表,这很可能是客户期望的。要正确实现此功能,您需要解析查询并将column in ()等表达式替换为false,并使用1=0等表达式。

那样

select * from tb_user where id in ()

被转换为

select * from tb_user where 1 = 0

并且

select * from tb_user where NOT (id in ())

select * from tb_user where NOT (1 = 0)

但是这使得设计为薄的包装器的实现变得不必要地复杂。