2012-08-28 265 views
9

最近我使用Mybatis3,發現當你的SQL語句得到一個空的結果從數據庫設置,MyBatis的創建一個新的List並返回給你的程序。MyBatis如何處理空的結果集?

鑑於一些代碼,如:

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

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

假定上述SQL不返回行(即沒有ID大於100)。

變量​​將是一個空的List,但我希望它是null而不是。 我該怎麼做?

回答

15

最好是有一個空的集合,而不是null作爲查詢的結果。當收集你通常遍歷每個項目的工作,並用它做什麼,這樣的事情:

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

如果列表爲空它不會做任何事情。

但是,如果你返回null,你要保護你的代碼對NullPointerExceptions的像這樣寫代碼,而不是:

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

第一種方法通常是更好的MyBatis確實是這樣,但你可能會迫使它返回null,如果這真的是你想要的。

對於您可以編寫一個MyBatis的plugin和攔截調用任何查詢,然後返回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) { 
    } 
} 

然後,您可以進一步限制攔截的範圍,如果你攔截來電到ResultSetHandler而不是Executor

1

它始終是更好地使用空列表而不是空,原因如下。

使用不慎空,則可能導致驚人的各種錯誤。

此外,null很不明確。很少有人明白空返回值應該是什麼意思 - 例如,Map.get(key)可以返回null,因爲map中的值爲null,或者該值不在map中。空可能意味着失敗,可能意味着成功,幾乎意味着任何事情。使用除null之外的其他內容可以明確您的意思。

good discussion about null usage