LoginSignup
2
1

More than 1 year has passed since last update.

PreparedStatementでin述語を使いたい場合の解決策(雑ですみません)

Last updated at Posted at 2021-06-05

(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円以上送料無料】

//追記
先輩がこのサイト教えてくれました。

2
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
1