Statement、PreparedStatement、CallableStatement的区别
此三个接口的声明如下:
1 public interface Statement extends Wrapper, AutoCloseable 2 public interface PreparedStatement extends Statement 3 public interface CallableStatement extends PreparedStatement
Statement用于执行不带参数的简单SQL语句,每次执行SQL语句时,数据库都要编译该SQL语句,以下是一个最简单的SQL语句
Statement stmt = conn.getStatement();
stmt.executeUpdate("insert into tableName(col, col) values('val', 'val')");
PreparedStatement表示预编译的SQL语句对象,用于执行带参数的预编译SQL语句。
import java.sql.*; public class Test{ public static void main(String[] args) throws Exception{ String user = "userName"; // 登录数据库的用户名 String password = "password"; // 登录数据库的密码 String url = "jdbc:mysql://localhost:3306/Test?useSSL=false"; // jdbc:mysql:数据库IP地址/数据库名称 String driver = "com.mysql.jdbc.cj.Driver"; // 数据库驱动 Connection conn = null; PreparedStatement stmt = null; ResultSet rs = null; try{ Class.forName(driver); // 加载数据库驱动 conn = DriverManager.getConnection(url, user, password); // 获得数据库连接 stmt = conn.preparedStatement("select * from Employee where id = ?"); // 预编译SQL语句 stmt.setInt(1, 1); // 设置参数 rs = stmt.executeQuery(); // 执行SQL语句 while(rs.next()){ System.out.println(rs.getInt(1) + " " + rs.getString(2) + " " + rs.getInt(3)); // 获得结果集数据 } }catch(SQLException e){ e.printStackTrace(); }finally{ try{ if (rs != null){ rs.close(); } if (stmt != null){ stmt.close(); } if (conn != null){ conn.close(); } } catch (SQLException e1) { System.out.println(e1.getMessage()); } } } }
CallableStatement提供了用来调用数据库中存储过程的接口,如果有输出参数要注册,则说明是输出参数。
虽然Statement对象与PreparedStatement对象能够实现相同的功能,但相比之下,PreparedStatement具有以下优点:
1)效率更高。在使用PreparedStatement对象执行SQL命令时,命令会被数据库编译与解析,并放到命令缓冲区。然后,每当执行同一个PreparedStatement对象时,由于在缓冲区中可以发现预编译的命令,虽然它会被再解析一次,但不会被再次编译,是可以重复使用的,能够有效提升系统性能。故如果要执行插入、更新、删除等操作时最好使用PreparedStatement。
2)代码可读性和可维护性更好。
3)安全性更高,可有效预防SQL注入攻击。