12

最近、Mybatis3 を使用していて、SQL ステートメントがデータベースから空の結果セットを取得すると、Mybatis が新しい結果セットを作成Listしてプログラムに返すことがわかりました。

次のようなコードが与えられます。

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

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

上記の SQL が行を返さないと仮定します (つまり、100 より大きい ID はありません)。

変数resultListは空になりますが、代わりにListそれをしたいです。nullどうやってやるの?

4

2 に答える 2

24

クエリの結果として 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プラグインを作成して任意のクエリの呼び出しをインターセプトし、クエリ結果が空の場合は 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

于 2012-09-16T17:06:54.143 に答える
1

次の理由により、null の代わりに空のリストを使用することを常にお勧めします。

null を不注意に使用すると、驚くほどさまざまなバグが発生する可能性があります。

さらに、 null は不愉快なほどあいまいです。null の戻り値が何を意味するのかが明確になることはめったにありません。たとえば、Map.get(key) は、マップ内の値が null であるか、値がマップ内にないために null を返すことがあります。Null は、失敗を意味することも、成功を意味することもあり、ほとんどすべてを意味する可能性があります。null 以外のものを使用すると、意味が明確になります。

null の使用法についての良い議論

于 2013-07-24T06:13:49.117 に答える