テーブル存在チェックはどう書くべきなのか

何でこれを書いたのか

コードレビューしていてちょっともやもやしたので吐きだしてみた。 自分の考えが間違っているかもしれないので、吐きだしてみて意見がもらえたらラッキー、程度。

前提条件

存在チェックはどうあるべきか

単純に存在しなかったら登録、存在したら更新、の時

こちらについては、nullか、そうでないかで処理分岐でよいと思う。

Hoge hoge = dao.getByPrimaryKey(キー);
if(hoge == null) {
    hoge = new Hoge();
    hoge.setXxx(xxx);
    dao.insert(hoge);
} else {
    hoge.setXxx(xxx);
    dao.update(hoge);
}

dao.getByPrimaryKey(キー) の先で呼ばれているSQLはこれ。

select * from hoge where KEY = 'キー'; 

DB反映が絡まないタイミングで重複チェックを行いたいとき

  • パターンA:nullかどうかで判定
Hoge hoge = dao.getByPrimaryKey(キー);
if(hoge == null) {
    return "OK";
} else {
    return "NG";
}
  • パターンB:count(*)を使って判定
if(dao.countByPrimaryKey(キー) == 0) {
    return "OK";
} else {
    return "NG";
}

dao.countByPrimaryKey(キー) の先で呼ばれているSQLはこれ。

select count(*) from hoge where KEY = 'キー'; 

後続処理で使わないオブジェクトがnullかどうか、の判定で使うのはなんだかもやもやする。
存在チェックを行うだけならcount(*)の方が後々の可読性も高いし、DAOだけ読んだ時もこれは存在チェックにしか使われていないなということが一目瞭然。 パターンBの方がコードの意味がわかりやすいのではなかろうか。 既にdaoにgetByPrimaryKey(キー)メソッドが実装されている時はパターンAを使う方が楽だろうし、実際に自分も使ってしまっているが・・・。

COBOLだったら?

IBM社のDB2は、SELECT時にSQLCODEが0だったら該当データ有、-100だったら該当データ無し、それ以外は異常、という判定で統一出来ててわかりやすかった記憶がある。 OracleMySQLPostgreSQLも同様のリターンコードで判定できるのだろうとは思う。

ここまで書いて気づいたこと

今のプロジェクト、何も考えないでパターンAで書いてしまったコードがいっぱいあるなぁ・・・