java - 修改我的方法以使用PreparedStatement对象而不是Statement对象

标签 java sql api jdbc prepared-statement

如何修改此代码以接受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 那么简单......这就是为什么我在这里寻求一些建议。谢谢。

最佳答案

几个步骤:

  1. 将类型从 Statement 更改为 PreparedStatement
  2. 将查询存储在字符串变量中。任何应该使用动态值的地方(例如连接 String 的地方)都将成为查询的参数,将这些变量替换为 ?
  3. 使用 Connection#prepareStatement 创建 PreparedStatement,而不是使用 Connection.createStatement
  4. 使用 setXxx 方法在 PreparedStatement 中设置参数。
  5. 使用 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/

相关文章:

c# - 创建对象与直接从数据库中选择

java - 预期类型 : java. lang.Double 实际值 : java. lang.Hibernate 中的整数错误

java - eclipse java.lang.NoClassDefFoundError 中的 Hadoop

mysql - 如何使用内部联接联合

sql - 删除命名空间中的所有函数? (执行生成的 DDL 命令?)

java - 当我们有 OkHttp 时为什么要使用 Retrofit

java - 断言语句如何停止程序?

java - Storm 中的多个字段分组

mysql按月分组,自定义开始日期

javascript - 哪个 HTTP 代码应该作为状态返回?