PreparedStatement setString失效仍留问号,数据库排序方法实现求助
Hey there! Let’s work through your two backend project issues step by step: building the column-sorting method you need, and fixing that annoying problem where PreparedStatement.setString() doesn’t replace the question marks in your SQL.
1. Implementing the meineDaten Sorting Method
First, let’s clarify the core logic: this method should only retrieve files owned by the specified user, then sort those results by your chosen column and order (ASC/DESC). A critical note here: you can’t use PreparedStatement placeholders for column names or sort directions—those are SQL identifiers, not parameter values. So we need to validate these inputs first to avoid SQL injection risks.
Here’s a complete, safe implementation:
import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import java.util.ArrayList; public ArrayList<Daten> meineDaten(Connection conn, String username, String sortColumn, String sortOrder) throws SQLException { ArrayList<Daten> dataList = new ArrayList<>(); // Validate sort column to prevent SQL injection (adjust allowed columns to match your table) String[] allowedColumns = {"filename", "upload_timestamp", "file_size", "file_type"}; boolean validColumn = false; for (String col : allowedColumns) { if (col.equalsIgnoreCase(sortColumn)) { validColumn = true; sortColumn = col; // Standardize column name case for SQL consistency break; } } if (!validColumn) { throw new IllegalArgumentException("Invalid sort column: " + sortColumn); } // Validate sort order (default to ASC if invalid) if (!"ASC".equalsIgnoreCase(sortOrder) && !"DESC".equalsIgnoreCase(sortOrder)) { sortOrder = "ASC"; // Or throw an exception if you want to enforce valid inputs: // throw new IllegalArgumentException("Sort order must be ASC or DESC"); } sortOrder = sortOrder.toUpperCase(); // Build the safe SQL query String sql = "SELECT * FROM your_file_table WHERE username = ? ORDER BY " + sortColumn + " " + sortOrder; // Use try-with-resources to auto-close resources and avoid leaks try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, username); // Bind the username parameter safely try (ResultSet rs = pstmt.executeQuery()) { // Map ResultSet rows to your Daten objects while (rs.next()) { Daten daten = new Daten(); // Adjust these to match your Daten class fields and table columns daten.setFileName(rs.getString("filename")); daten.setUploadTime(rs.getTimestamp("upload_timestamp")); daten.setFileSize(rs.getLong("file_size")); // Add other field mappings here dataList.add(daten); } } } return dataList; }
Key takeaways for this method:
- Always validate user-provided sort columns/directions to block SQL injection
- Only use
PreparedStatement.setString()for actual parameter values (likeusername), not SQL identifiers - Use try-with-resources to ensure database resources are properly closed
2. Fixing the PreparedStatement setString Failure
If your SQL still has question marks after calling setString(), you’re likely hitting one of these common issues:
Issue 1: Trying to bind SQL identifiers (columns, sort order) with placeholders
As mentioned earlier, placeholders only work for parameter values (like username). You can’t bind column names or ASC/DESC with setString()—the database won’t replace those question marks because they’re not values. That’s why we validate and directly append those values to the SQL (after checking they’re safe!).
Issue 2: Re-creating the PreparedStatement after setting parameters
If you do something like this, your parameters get lost:
// ❌ Wrong: Re-creating the pstmt overwrites your set parameters PreparedStatement pstmt = conn.prepareStatement(sql); pstmt.setString(1, username); pstmt = conn.prepareStatement(sql); // This resets everything! ResultSet rs = pstmt.executeQuery();
Always use the same PreparedStatement object you set parameters on to execute the query.
Issue 3: Incorrect parameter index
Double-check that the index in setString() matches the position of the placeholder in your SQL. For example, if your SQL has two placeholders, use setString(1, ...) for the first, setString(2, ...) for the second.
Correct Example (No More Question Marks)
// ✅ Correct: Bind only parameter values, validate identifiers first String sql = "SELECT * FROM your_file_table WHERE username = ? ORDER BY filename ASC"; try (PreparedStatement pstmt = conn.prepareStatement(sql)) { pstmt.setString(1, "HTLgurl"); // Binds to the first (and only) placeholder ResultSet rs = pstmt.executeQuery(); // Now the SQL executed will have "HTLgurl" instead of ? }
内容的提问来源于stack exchange,提问作者HTLgurl

