cypher256's blog

Pleiades とか作った

SQL 発行

次のようなインターフェースを持つ Sql クラスを作成し、複雑な SQL に対応しました。このクラスは SQL 文字列とパラメータのリストを持つ単純なクラスです。メソッドは append しかありません。

  • public class Sql
    • public Sql(boolean isAndOr)
    • publilc Sql append(String sqlFragment)
    • publilc Sql append(String sqlFragment, Object... params)
    • publilc Sql append(Sql sql)


上記のような StringBuilder ライクな単純なインターフェースで下記を実現できました。コンストラクタで条件を AND でつなげるか、OR でつなげるか設定し、AND と OR 複合の場合は Sql オブジェクト自体をネストして append します。第 2 引数以降が指定されている場合のみ AND や OR で連結されます。

  • S2JDBC の流れるインターフェースに近い少ないコード量
  • like エスケープなども勝手に対応 (エスケープ文字は決めうち)
  • 値が null の場合は条件無視
  • in の場合は自動で (?,?,,) のように展開
  • SQL 文の簡易構文チェック機能つき
  • 副問い合わせや UNION など、どんな SQL でも対応可能


こんな感じ。Dao は JdbcManagerImple を継承したクラス。

Sql sql = new Sql("1".equals(fooDto.andOr))
    .append("select * from TABLE1 where")
    .append("col1 = ?", "a")
    .append("col2 in ?", "a", "b")
    .append("col3 like ?||'%'", "a");

if (dao.getCountBySql(sql) == 0) {
    return;
}
List<BeanMap> list = dao.selectBySql(BeanMap.class, sql)
    .offset(20)
    .limmit(10)
    .getResultList();

今回のプロジェクトでは検索画面の検索項目が多く、かつ AND、OR が切り替え可能なため、このような措置を取りました。検索画面以外では S2JDBC デフォルトの SQL 自動生成を使用します。selectBySql の場合、結果を格納するクラスは最初は型安全にするために、エンティティを継承したクラスを、SQL ごとに作成することを考えていましたが、結局、ほとんどがフォームにコピーするだけなので、S2JDBC の BeanMap を使う方針にしました。