Java MyBatis如何处理一个空的结果集?

Java MyBatis如何处理一个空的结果集?,java,mysql,mybatis,Java,Mysql,Mybatis,最近,我在使用Mybatis3时发现,当SQL语句从数据库中获取一个空结果集时,Mybatis会创建一个新的列表,并将其返回到程序中 给出一些代码,比如: List<User> resultList = (List<User>)sqlSession.select("statementId"); <select id="statementId" resultType="User"> select * from user where id > 100

最近,我在使用Mybatis3时发现,当SQL语句从数据库中获取一个空结果集时,Mybatis会创建一个新的
列表
,并将其返回到程序中

给出一些代码,比如:

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

<select id="statementId" resultType="User">
   select * from user where id > 100
</select>
List resultList=(List)sqlSession.select(“statementId”);
从id>100的用户中选择*
假设上述SQL不返回任何行(即没有大于100的id)

变量
resultList
将是一个空的
列表
,但我希望它改为
null

如何才能做到这一点?

查询结果最好是空集合,而不是空集合。在使用集合时,您通常会循环遍历每个项目并对其执行某些操作,例如:

List<User> resultList = (List<User>) sqlSession.select("statementId");
for (User u : resultList) { 
   //... 
}
List resultList=(List)sqlSession.select(“statementId”);
对于(用户u:resultList){
//... 
}
如果列表为空,则不会执行任何操作

但如果返回null,则必须防止代码出现NullPointerException,并编写如下代码:

List<User> resultList = (List<User>) sqlSession.select("statementId");
if (resultList != null) {
  for (User u : resultList) { 
     //... 
  }
}
List resultList=(List)sqlSession.select(“statementId”);
如果(结果列表!=null){
对于(用户u:resultList){
//... 
}
}
第一种方法通常更好,MyBatis就是这样做的,但是如果你真的想要的话,你可以强迫它返回null

为此,您可以编写MyBatis并拦截对任何查询的调用,如果查询结果为空,则返回null

下面是一些代码:

在您的配置中添加:

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

拦截器代码:

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) {
    }
}
package.test;
导入java.util.List;
导入java.util.Properties;
导入org.apache.ibatis.executor.executor;
导入org.apache.ibatis.mapping.MappedStatement;
导入org.apache.ibatis.plugin.Interceptor;
导入org.apache.ibatis.plugin.Intercepts;
导入org.apache.ibatis.plugin.Invocation;
导入org.apache.ibatis.plugin.plugin;
导入org.apache.ibatis.plugin.Signature;
导入org.apache.ibatis.session.ResultHandler;
导入org.apache.ibatis.session.RowBounds;
@截取({@Signature(type=Executor.class,method=“query”,args={MappedStatement.class,Object.class,RowBounds.class,ResultHandler.class})
公共类MyInterceptor实现拦截器{
公共对象拦截(调用)抛出可丢弃的{
对象结果=调用。继续();
列表=(列表)结果;
返回值(list.size()==0?空:结果);
}
公共对象插件(对象目标){
返回Plugin.wrap(target,this);
}
公共void集合属性(属性){
}
}

如果拦截对
ResultSetHandler
而不是
Executor

的调用,则可以进一步限制拦截器的作用域。出于以下原因,最好使用空列表而不是null

不小心使用null会导致各种各样的错误

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