简体   繁体   English

MyBatis如何处理空结果集?

[英]How is MyBatis dealing with an empty result set?

Recently I was using Mybatis3 and found that when your SQL statement gets an empty result set from the database, Mybatis creates a new List and returns it to your program. 最近我使用的是Mybatis3,发现当你的SQL语句从数据库中获取一个空的结果集时,Mybatis会创建一个新的List并将其返回给你的程序。

Given some code, like: 给出一些代码,例如:

List<User> resultList = (List<User>)sqlSession.select("statementId");

<select id="statementId" resultType="User">
   select * from user where id > 100
</select>

assume that the above SQL return no rows (ie there is no id greater than 100). 假设上面的SQL没有返回任何行(即没有大于100的id)。

The variable resultList will then be an empty List , but I want it to be null instead. 变量resultList将是一个空List ,但我希望它为null How can I do that? 我怎样才能做到这一点?

It's better to have an empty collection instead of null as a result of your query. 由于您的查询,最好有一个空集合而不是null。 When working with a collection you usually loop through each item and do something with it, something like this: 使用集合时,您通常会遍历每个项目并使用它执行某些操作,如下所示:

List<User> resultList = (List<User>) sqlSession.select("statementId");
for (User u : resultList) { 
   //... 
}

which doesn't do anything if the list is empty. 如果列表为空,则不执行任何操作。

But if you return null, you have to guard your code against NullPointerExceptions and write code like this instead: 但是如果你返回null,你必须保护你的代码免受NullPointerExceptions的影响,并编写这样的代码:

List<User> resultList = (List<User>) sqlSession.select("statementId");
if (resultList != null) {
  for (User u : resultList) { 
     //... 
  }
}

The first approach is usually better and MyBatis does it like that, but you could force it to return null, if that is really what you want. 第一种方法通常更好,MyBatis就是这样做的,但你可以强制它返回null,如果这真的是你想要的。

For that you could write a MyBatis plugin and intercept calls to any query and then return null if the query result is empty. 为此,您可以编写MyBatis 插件并拦截对任何查询的调用,如果查询结果为空,则返回null。

Here is some code: 这是一些代码:

In your configuration add: 在您的配置中添加:

<plugins>
   <plugin interceptor="pack.test.MyInterceptor" />
</plugins>

The interceptor code: 拦截器代码:

package pack.test;

import java.util.List;
import java.util.Properties;

import org.apache.ibatis.executor.Executor;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.Interceptor;
import org.apache.ibatis.plugin.Intercepts;
import org.apache.ibatis.plugin.Invocation;
import org.apache.ibatis.plugin.Plugin;
import org.apache.ibatis.plugin.Signature;
import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds;

@Intercepts({ @Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class, RowBounds.class, ResultHandler.class}) })
public class MyInterceptor implements Interceptor {
    public Object intercept(Invocation invocation) throws Throwable {
        Object result = invocation.proceed();
        List<?> list = (List<?>) result;
        return (list.size() == 0 ? null : result);
    }

    public Object plugin(Object target) {
        return Plugin.wrap(target, this);
    }

    public void setProperties(Properties properties) {
    }
}

You could then further limit the scope of the interceptor if you intercept calls to ResultSetHandler instead of Executor . 如果拦截对ResultSetHandler而不是Executor调用,则可以进一步限制拦截器的范围。

It is always better to use empty list instead of null for the following reasons. 由于以下原因,最好使用空列表而不是null。

Careless use of null can cause a staggering variety of bugs. 不小心使用null会导致各种各样的错误。

Additionally, null is unpleasantly ambiguous. 另外,null是令人不快的模糊。 It's rarely obvious what a null return value is supposed to mean -- for example, Map.get(key) can return null either because the value in the map is null, or the value is not in the map. 很明显,null返回值应该是什么意思 - 例如,Map.get(key)可以返回null,因为map中的值为null,或者值不在map中。 Null can mean failure, can mean success, can mean almost anything. Null可能意味着失败,可能意味着成功,可能意味着几乎任何事情。 Using something other than null makes your meaning clear. 使用除null之外的其他内容会使您的意思清晰。

good discussion about null usage 关于null使用的好讨论

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM