java MyBatis 如何处理空结果集?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12156562/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 07:49:12  来源:igfitidea点击:

How is MyBatis dealing with an empty result set?

javamysqlmybatis

提问by user1629796

Recently I was using Mybatis3 and found that when your SQL statement gets an empty result set from the database, Mybatis creates a new Listand 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 (i.e. there is no id greater than 100).

假设上面的 SQL 没有返回任何行(即没有大于 100 的 id)。

The variable resultListwill then be an empty List, but I want it to be nullinstead. How can I do that?

该变量resultList将是一个空的List,但我希望它是null。我怎样才能做到这一点?

回答by Bogdan

It's better to have an empty collection instead of null as a result of your query. When working with a collection you usually loop through each item and do something with it, something like this:

作为查询的结果,最好有一个空集合而不是 null。处理集合时,您通常会遍历每个项目并对其进行处理,如下所示:

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 pluginand 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 ResultSetHandlerinstead of Executor.

如果您拦截对ResultSetHandler而不是 的调用,则可以进一步限制拦截器的范围Executor

回答by Bala

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. 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 can mean failure, can mean success, can mean almost anything. Using something other than null makes your meaning clear.

此外,null 令人不快地模棱两可。null 返回值的含义很少很明显——例如, Map.get(key) 可以返回 null,因为映射中的值为 null,或者该值不在映射中。Null 可能意味着失败,可能意味着成功,几乎可以意味着任何事情。使用 null 以外的其他内容可以使您的意思清晰。

good discussion about null usage

关于空用法的好讨论