Javaで定数定義したSQLを動的に変更する(=ただの置換) からの final修飾子のおさらい
条件に応じて参照テーブルを変更する。
ex) xxFlagがONの時はTABLE_1, OFFの時はTABLE_2を参照したい。
それ以外の結合や絞込み条件などは全く一致する前提。
--------------------------------------------------------------------------------------
【SQLを2つ書く方法】
何の捻りもなく、そのまんま。
private static final String SQL_SEARCH_1 =
"SELECT "
+ TABLE_1 + "." + field1 + ", "
+ TABLE_1 + "." + field2 + ", "
+ ・
+ ・
+ ・
+ " FROM "
+ TABLE_1
+ " WHERE "
+ 略
;
private static final String SQL_SEARCH_2 =
"SELECT "
+ TABLE_2 + "." + field1 + ", "
+ TABLE_2 + "." + field2 + ", "
+ ・
+ ・
+ ・
+ " FROM "
+ TABLE_2
+ " WHERE "
+ 略
;
メリット
・参照テーブル毎に(結合、絞込みなどの)条件を変えたい、といった変更に強い。
デメリット
・2重メンテが発生
・コードが冗長
--------------------------------------------------------------------------------------
【置換する方法】
// 置換用文字列
private static final String TABLE_X = "@TABLE_X@";
private static final String SQL_SEARCH =
"SELECT "
+ TABLE_X + "." + field1 + ", "
+ TABLE_X + "." + field2 + ", "
+ ・
+ ・
+ ・
+ " FROM "
+ TABLE_X
+ " WHERE "
+ 略
;
--------------------------
String sql = xxFlag ? SQL_SEARCH.replaceAll(TABLE_X , TABLE_1)
: SQL_SEARCH.replaceAll(TABLE_X , TABLE_2);
Point
・置換用文字列は@で囲む等、普通は使用しない形で記載する(誤置換防止)。
→例えば置換用文字列を「S」と定義すると、SELECTの「S」が置換されてしまう。
メリット
・コードが簡潔に書ける
デメリット
・参照テーブル毎に(結合、絞込みなどの)条件を変えたい、といった変更に弱い。
ちなみに、
SQL_SEARCH はstatic finalだけど、replaceAllで変更できるの?
▶︎ 変更ではなく、新規Stringインスタンスが返るので問題なし!
一応JavaDocも確認。
JavaDocのStringクラス
※1.5版から引用。古いけど多分変わってないはず。
java.lang.String
public final class String
extends Object
implements Serializable, Comparable<String>, CharSequence
文字列は定数です。この値を作成したあとに変更はできません。
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
特に意識していなかったけれど、Stringクラスはfinalだったらしい。
■final修飾子メモ
final クラス: サブクラスの作成ができなくなる
final メソッド: オーバーライドができなくなる
final 基本型変数: 変数の値の変更ができなくなる
final 参照型変数: 変数の参照の変更ができなくなる
※setter/getterなどで、インスタンスの値変更はできる点に注意
下記ケースはエラーにならずに正常に書き換えられる。
public class XxxBean {
private String str;
privateintnum;
// constructor
public XxxBean(String str, int num) {
this.str = str;
this.num = num;
}
// getter and setter
public String getStr() {
returnstr;
}
public void setStr(String str) {
this.str = str;
}
public int getNum() {
returnnum;
}
public void setNum(int num) {
this.num = num;
}
}
publicclass Test {
public static void main(String [] args) {
final XxxBean bean = new XxxBean("aaa", 1);
bean.setStr("bbb");
bean.setNum(2);
System.out.println(bean.getStr());
System.out.println(bean.getNum());
}
}
仮に、
bean = null;
と書いた場合はコンパイルエラーになる。