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

时间:2014-11-02 11:44:23

标签: java sql api jdbc prepared-statement

如何修改此代码以接收PreparedStatement对象(而不是语句对象)?

    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 个答案:

答案 0 :(得分:2)

几步:

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

    为项目中的必要方法做类似的事情。