(in述語って言葉を初めて知ったが、、、)
daoクラスを書いているときに、
select fizz, buzz from HOGE where fizz in (?,?,,,)
のようなSQLを投げたいと思った。
しかし、SQLInjectionの観点から、
String sql ="select fizz, buzz from HOGE where fizz in ({1})";
StringBuilder sb = new StringBuilder();
for(String fizz : fizzList ){
sb.append(fizz+",");
}
String tmpBindParam = sb.toString();
String bindParam tmpBindParam.sbString(0,tmpBindParam.length()-1)
sql = sql.replace("{1}",bindParam);
PreparedStatement ps = conn.prepareStatement(sql);
rs = ps.executeQuery();
...
のようなことは危険である。
間違っているので実際には書いてないが、
要するにPreparedStatement#setStringなどでバインド変数を使わない手法。
そこで、Bestかわかからないがこうやったらできるだろうと思った。
StringBuilder sb = new StringBuilder();
for(String fizz : fizzList ){
sb.append("?,");
}
String placeHolder = sb.deleteCharAt( sb.length() -1 ).toString();
String sql ="select fizz, buzz from HOGE where fizz in (" +placeHolder+ ")";
PreparedStatement ps = conn.prepareStatement(sql);
int i = 1;
for(String fizz : fizzList ){
ps.setString(i++, fizz);
}
rs = ps.executeQuery();
こんな感じでやったら、一応バインド変数を用いて、
同じ数の ? に動的に値を渡すことが可能である。
ただ本当にこれがベストなのかわからない。
もしもっと効率的な書き方があれば教えてほしい。
Java8で書けるもっといい方法があれば。。とくに。。。知りたい。
(あんま調べても出てこなかったのよね)。。
ちなみにin述語って言葉はSQLアンチパターンで本にありました。↓↓
SQLアンチパターン/BillKarwin/和田卓人/和田省二【3000円以上送料無料】
//追記
先輩がこのサイト教えてくれました。