ถ้าเรามี list หรือ array ของข้อมูลที่ต้องการค้นหาจาก table ใน DB
โดยเราไม่ต้องการ select ทั้ง table เพราะมันจะเยอะไป
แล้วเราไม่ต้องการวนลูป select ทีละตัว เพราะจะเสียเวลามากไป
หลักการ คือ เราใช้ WHERE – IN ในการส่ง list เข้าไปทำ query
SELECT user_id, username, email
FROM users
WHERE username IN ('A', 'B', 'D');
ทีนี้ เวลาจะใช้งานใน Java ล่ะ เราจะไม่สร้าง string แบบ (‘A’, ‘B’, ‘D’) แต่เราจะส่ง array เข้าไปทั้งอันเลย
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class SelectWithInClause {
public void getUsers(List<String> usernames) {
if (usernames == null || usernames.isEmpty()) {
return; // ไม่ต้องทำอะไรถ้าลิสต์ว่าง
}
// 1. สร้าง String ของ placeholder "(?, ?, ?)"
String placeholders = usernames.stream()
.map(name -> "?")
.collect(Collectors.joining(", "));
// 2. สร้าง SQL Query ที่สมบูรณ์
String sql = "SELECT user_id, username, email FROM users WHERE username IN (" + placeholders + ")";
System.out.println("Executing SQL: " + sql);
try (Connection conn = getDbConnection(); // สมมติว่ามีเมธอดสำหรับเชื่อมต่อ DB
PreparedStatement pstmt = conn.prepareStatement(sql)) {
// 3. วนลูปเพื่อตั้งค่า parameter ทีละตัว
int index = 1;
for (String name : usernames) {
pstmt.setString(index++, name);
}
// 4. สั่งให้ Query ทำงาน
try (ResultSet rs = pstmt.executeQuery()) {
System.out.println("ผลลัพธ์:");
while (rs.next()) {
System.out.printf("ID: %d, Username: %s, Email: %s\n",
rs.getInt("user_id"),
rs.getString("username"),
rs.getString("email"));
}
}
} catch (SQLException e) {
e.printStackTrace();
}
}
// ตัวอย่างการเรียกใช้งาน
public static void main(String[] args) {
SelectWithInClause selector = new SelectWithInClause();
List<String> namesToFind = Arrays.asList("A", "B", "D");
selector.getUsers(namesToFind);
}
// เมธอดจำลองการเชื่อมต่อฐานข้อมูล
private static Connection getDbConnection() throws SQLException {
// ในโค้ดจริง ส่วนนี้จะเป็นการเชื่อมต่อฐานข้อมูลของคุณ
// return DriverManager.getConnection(URL, USER, PASS);
return null; // Dummy implementation
}
}
ตัวอย่างข้างบน จะใช้ preparedStatement
โดยสร้าง place holder สำหรับ array ที่จะใส่ใน WHERE – IN
โดยใช้ stream ในการสร้าง ซึ่งวิธีการค่อนข้างดูดีทีเดียว
ไม่ต้องเขียน code วนลูปทีละตัวเอง
String placeholders = usernames.stream().map(name -> “?”).collect(Collectors.joining(“, “));
เอา ArrayList มาทำ stream -> จากนั้น map ค่าใน stream ที่ตอนนี้แทนด้วยตัวแปร name ให้เป็น “?” -> จากนั้นรวบเข้าด้วยกัน ด้วย collect โดยเชื่อมกันด้วย joining “,”
แต่ตอน set string เข้าไปใน prepareStatement ยังต้องวนลูป set อยู่
int index = 1;
for (String name : usernames) {
pstmt.setString(index++, name);
}
ก็ดูแปลกๆดี
แต่ preparedStatement มันมีข้อดีคือตัวมันช่วยเรื่อง security อย่างการป้องกันพวก Sql Injection
เพราะ ถ้าไม่อย่างนั้น เราก็ใช้ stream ในการสร้าง query แทน Place holder ไปเลย

