如何修改此代码以接受PreparedStatement 对象(而不是Statement 对象)?
package com.cs330;
import javax.ws.rs.*;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
@Path("ws2")
public class IngredientServices
@Path("/ingredients")
@GET
@Produces("text/plain")
public String getIngredients() throws SQLException, ClassNotFoundException {
String connectStr="jdbc:mysql://localhost:3306/fooddb";
//database username
String username="root";
//database password
String password="csci330pass";
/* The driver is the Java class used for accessing
* a particular database. You must download this from
* the database vendor.
*/
String driver="com.mysql.jdbc.Driver";
Class.forName(driver);
//Creates a connection object for your database
Connection con = DriverManager.getConnection(connectStr, username, password);
/* Creates a statement object to be executed on
* the attached database.
*/
Statement stmt = con.createStatement();
/* Executes a database query and returns the results
* as a ResultSet object.
*/
ResultSet rs = stmt.executeQuery("SELECT id, name, category FROM ingredient");
/* This snippet shows how to parse a ResultSet object.
* Basically, you loop through the object sort of like
* a linkedlist, and use the getX methods to get data
* from the current row. Each time you call rs.next()
* it advances to the next row returned.
* The result variable is just used to compile all the
* data into one string.
*/
String result = "";
while (rs.next())
{
int theId = rs.getInt("id");
String theName = rs.getString("name");
String theCategory = rs.getString("category");
result += "id: "+theId+ " , name: "+theName + "("+theCategory+")" + "\n" + "\n";
}
return result;
}//END
@Path("/ingredients/{id}")
@GET
@Produces("text/plain")
public String getIngredientById(@PathParam("id") String theId)
throws SQLException, ClassNotFoundException {
int intId = 0;
try
{
intId = Integer.parseInt(theId);
}
catch (NumberFormatException FAIL)
{
intId = 1;
}//Obtaining an ingredient from the database
String connectStr="jdbc:mysql://localhost:3306/fooddb";
String username="root";
String password="csci330pass";
String driver="com.mysql.jdbc.Driver";
Class.forName(driver);
Connection con = DriverManager.getConnection(connectStr, username, password);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name, category FROM ingredient
WHERE id=" +intId);
String result = "";
while (rs.next())
{
int theId2 = rs.getInt("id");
String theName2 = rs.getString("name");
String theCategory = rs.getString("category");
result += "id: "+theId2+ " , name: "+theName2 + "("+theCategory+")" + "\n" + "\n";
}
return result;
}//END METHOD
@Path("/ingredients/name")
@GET
@Produces("text/plain")
public String getIngredientByName(@QueryParam("name") String theName)
throws SQLException, ClassNotFoundException
{
//Obtaining an ingredient from the database
String connectStr="jdbc:mysql://localhost:3306/fooddb";
String username="root";
String password="csci330pass";
String driver="com.mysql.jdbc.Driver";
Class.forName(driver);
Connection con = DriverManager.getConnection(connectStr, username, password);
Statement stmt = con.createStatement();
ResultSet rs = stmt.executeQuery("SELECT id, name, category FROM ingredient WHERE
name='" + theName + "'");
String result = "";
while (rs.next())
{
int theId3 = rs.getInt("id");
String theName3 = rs.getString("name");
String theCategory = rs.getString("category");
result += "id: "+theId3+ " , name: "+theName3 + "("+theCategory+")" + "\n" + "\n";
}
return result;
}//END METHOD
}//END CODE
我知道,这并不只是将对象变量从 Statement 更改为PreparedStatement 那么简单......这就是为什么我在这里寻求一些建议。谢谢。
最佳答案
几个步骤:
- 将类型从
Statement
更改为PreparedStatement
。 - 将查询存储在
字符串
变量中。任何应该使用动态值的地方(例如连接String
的地方)都将成为查询的参数,将这些变量替换为?
。 - 使用
Connection#prepareStatement
创建PreparedStatement
,而不是使用Connection.createStatement
。 - 使用
setXxx
方法在PreparedStatement
中设置参数。 - 使用
executeQuery
方法执行语句。
PreparedStatement
中有一个示例javadoc。
您可以按照上述步骤更改 getIngredientById
方法:
Connection con = DriverManager.getConnection(connectStr, username, password);
//from "SELECT id, name, category FROM ingredient WHERE id=" + intId
//check the usage of ? instead of intId
String sql = "SELECT id, name, category FROM ingredient WHERE id = ?";
PreparedStatement pstmt = con.prepareStatement(sql);
//setting variable in PreparedStatement
pstmt.setInt(1, intId);
ResultSet rs = pstmt.executeQuery();
String result = "";
while (rs.next()) {
//consume the data...
}
您可以按照上述步骤更改 getIngredientByName
方法:
Connection con = DriverManager.getConnection(connectStr, username, password);
//? don't need you to escape it by using ' around
//? is equals to the parameter, this is why using PreparedStatement is more safe
//it will help you to avoid SQL Injection attacks
String sql = "SELECT id, name, category FROM ingredient WHERE name = ?";
PreparedStatement pstmt = con.prepareStatement(sql);
pstmt.setString(1, theName);
ResultSet rs = pstmt.executeQuery();
String result = "";
while (rs.next()) {
//consume the data...
}
对项目中必要的方法执行类似的操作。
关于java - 修改我的方法以使用PreparedStatement对象而不是Statement对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26698914/