Statement 和 PreparedStatement之间的关系和区别

Statement是java执行数据库操作的一个重要方法,用于在已经建立数据库连接的基础上,向数据库发送要执行的SQL语句。具体步骤:

  1.首先导入java.sql.*;这个包。

  2.然后加载驱动,创建连接,得到Connection接口的的实现对象,比如对象名叫做conn。

  3.然后再用conn对象去创建Statement的实例,方法是:Statement stmt = conn.creatStatement("SQL语句字符串");

  Statement 对象用于将 SQL 语句发送到数据库中。实际上有三种 Statement 对象,它们都作为在给定连接上执行 SQL语句的包容器:Statement、PreparedStatement(它从 Statement 继承而来)和CallableStatement(它从 PreparedStatement 继承而来)。它们都专用于发送特定类型的 SQL 语句:Statement 对象用于执行不带参数的简单 SQL 语句;PreparedStatement 对象用于执行带或不带参数的预编译 SQL 语句;CallableStatement 对象用于执行对数据库已存储过程的调用。

      Statement:用于执行静态 SQL 语句并返回它所生成结果的对象。
      接口:public interface Statement extends Wrapper
     在默认情况下,同一时间每个 Statement 对象只能打开一个 ResultSet 对象。因此,如果读取一个 ResultSet 对象与另一个交叉,则这两个对象必须是由不同的 Statement 对象生成的。如果存在某个语句的打开的当前 ResultSet 对象,则 Statement 接口中的所有执行方法都会隐式关闭它。  
   如以下操作:创建statement对象
          Statement stat=conn.createStatement();
          String sql="insert into lover values(6,'suxingxing',to_date('21-9-2016','dd-mm-yyyy'))";
          stat.execute(sql);//这里提交时应该有sql语句,不同于PreparedStatment

    import java.sql.Connection;  
    import java.sql.DriverManager;  
    import java.sql.SQLException;  
    import java.sql.Statement;  
    public class StatementTest {  
        public static void main(String[] args) {  
            test_autoCommit();  
        }  
        public static void test_autoCommit()  
            {  
            String driver="oracle.jdbc.driver.OracleDriver";  
            String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl";  
            String user="briup";  
            String password="briup";  
            Connection conn=null;  
            Statement stat=null;  
            try {  
                //1、注册驱动  
                Class.forName(driver);  
                //2、获取连接  
                 conn= DriverManager.getConnection(url, user, password);  
                 conn.setAutoCommit(false);  
                 //System.out.println(conn);  
                //3、创建statement对象  
                 stat=conn.createStatement();  
                 //4、执行sql语句  
                 String sql="insert into lover values(22,'suxingxing',to_date('21-9-2016','dd-mm-yyyy'))"; //注意格式              
    //           stat.execute(sql);  
                 System.out.println(stat.execute(sql)); //返回值为false,因为同样没有ResultSet返回集  
                 conn.commit();  
                 //5、处理结果集  
            } catch (Exception e) {  
                e.printStackTrace();  
                try {  
                    conn.rollback();  
                } catch (SQLException e1) {  
                    e1.printStackTrace();  
                }  
            }  
            finally{  
                //6、关闭资源  
                try {  
                    if(stat!=null)stat.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
                try {  
                    if(conn!=null)conn.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }  



PreparedStatement:表示预编译的 SQL 语句的对象。
   接口:public interface PreparedStatement extends Statement之间的继承关系
   SQL 语句被预编译并存储在 PreparedStatement 对象中。然后可以使用此对象多次高效地执行该语句。
   注:用于设置 IN 参数值的设置方法(setShort、setString 等等)必须指定与输入参数的已定义 SQL 类型兼容的类型。例如,如果 IN 参数具有 SQL 类型 INTEGER,那么应该使用 setInt 方法,问号的位置也是应该注意的,因为第一个问好的位置为1,第二个问号的位置为2.以此类推。
   如果需要任意参数类型转换,使用 setObject 方法时应该将目标 SQL 类型作为其参数。
   在以下设置参数的示例中,con 表示一个活动连接:
              PreparedStatement pstmt = con.prepareStatement("UPDATE EMPLOYEES SALARY = ? WHERE ID = ?");
              pstmt.setBigDecimal(1, 1533.00)
              pstmt.setInt(2, 1102)
              pstmt.execute()//注意提交时这里不能再有sql语句,不同于Statment

 

    import java.sql.Connection;  
    import java.sql.DriverManager;  
    import java.sql.PreparedStatement;  
    import java.sql.SQLException;  
    import java.sql.Statement;  
    public class PreparedStatementTest {  
        public static void main(String[] args) {  
            test_autoCommit();  
        }  
        public static  void test_autoCommit()  
        {  
            String driver="oracle.jdbc.driver.OracleDriver";  
            String url="jdbc:oracle:thin:@127.0.0.1:1521:orcl";  
            String user="briup";  
            String password="briup";  
            Connection conn=null;  
            PreparedStatement ps=null;  
            try {  
                //1、注册驱动  
                Class.forName(driver);  
                //2、获取连接  
                 conn= DriverManager.getConnection(url, user, password);  
                 //System.out.println(conn);  
                //3、创建prepareStatement对象  
                 String sql="insert into lover values(?,?,?)";  
                 ps=conn.prepareStatement(sql);  
                 //4、执行sql语句  
                 ps.setInt(1,21);//代表设置给第一个?号位置的值为Int类型的21  
                 ps.setString(2,"suwu150");//代表设置给第二个?号位置的值为String类型的suwu150  
                 java.util.Date utilDate=new java.util.Date();//进行类型转换,由util类型的date转化为sql类型的  
                 ps.setDate(3, new java.sql.Date(utilDate.getTime()));  
                 //ps.execute();//执行  
                 System.out.println(ps.execute());//执行表输出返回的结果,结果为false,因为没有返回的结果集  
                 //5、处理结果集  
            } catch (Exception e) {  
                e.printStackTrace();  
            }  
            finally{  
                //6、关闭资源  
                try {  
                    if(ps!=null)ps.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
                try {  
                    if(conn!=null)conn.close();  
                } catch (SQLException e) {  
                    e.printStackTrace();  
                }  
            }  
        }  
    }     

PreparedStatement 继承了 Statement 的所有功能。另外它还添加了一整套方法,用于设置发送给数据库以取代 IN 参数占位符的值。同时,三种方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要参数。这些方法的 Statement 形式(接受 SQL 语句参数的形式)不应该用于 PreparedStatement 对象。


  综上所述,总结如下:Statement每次执行sql语句,数据库都要执行sql语句的编译,最好用于仅执行一次查询并返回结果的情形,效率高于PreparedStatement.但存在sql注入风险。PreparedStatement是预编译执行的。在执行可变参数的一条SQL时,PreparedStatement要比Statement的效率高,因为DBMS预编译一条SQL当然会比多次编译一条SQL的效率高。安全性更好,有效防止SQL注入的问题。对于多次重复执行的语句,使用PreparedStatement效率会更高一点。执行SQL语句是可以带参数的,并支持批量执行SQL。由于采用了Cache机制,则预编译的语句,就会放在Cache中,下次执行相同的SQL语句时,则可以直接从Cache中取出来。

猜你喜欢

转载自blog.csdn.net/lzh_86/article/details/80055765