JavaWeb学习(七): Statement 与 PreparedStatement 的区别 :

前言:

两者由哪个类产生?

Connection 产生 Statement 对象 : createStatement()
Connection 产生 PreparedStatement 对象 : prepareStatement()
Connection 产生 CallableStatement   对象 : prepareCall()

两者之间的关系:

public interface PreparedStatement extends Statement
由此可知: PreparedStatement 是Statement 的一个子接口
所以   : Statement有的东西PreparedStatement 也有,甚至子类还比父类多很多东西 

两者是通过怎么的方式操作数据库的?

Statement :

增删改 :executeUpdate()
查询  :  executeQuery()   ---  返回的是一个结果集(ResultSet)

PreparedStatement:

增删改  : executeUpdate()
查询   :  executeQuery() ---  返回的是一个结果集(ResultSet)
赋值操作:setXxx();        ---   相对于 Statement 强大的地方

两者在使用时的区别(具体看代码,更好理解):

Statement:

1、SQL 语句
2、executeUpdate(sql)

PareparedStatement:

sql(可以存在占位符?)
在创建PreparedStatement 对象时,将sql预编译 prepareStatement(sql);
setXxx()替换占位符  (两个参数: 位置,值)
executeUpdate(); -- 由于已经预编译过,所以不用再进行重复编译

PareparedStatement 的优势:

1、编码更加简便(直接用 ?代替,避免了字符串的拼接)
2、提高性能(预编译,避免了重复编译,提高了性能)
3、安全(可以有效防止 sql 注入)

sql注入: 将用户输入的内容 和开发人员的SQL语句混为一体

stmt : 存在被注入的风险
(例如输入 用户名:任意值 ' or 1 = 1 --
            密码:任意值
)
分析:
select count(*) from login where uname='任意值' or 1=1 --' and upwd = '任意值’;
(SQL语句中 -- 起注释的作用)
select count(*) from login where uname='任意值' or 1=1;
select count(*) from login;

pstmt : 有效防止 sql 注入(推荐使用)
select count(*) from login where uname=? and upwd = ?;
(没有符号跟 ?配对)

代码进行区别:

Statement:

package controlSql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SqlQuery {
    private static final String URL = "jdbc:mysql://localhost:3306/sqltest";
    private static final String User = "root";
    private static final String Pwd = "root";
    
    // 查询操作
    public static void query() {
        Connection connection = null;
        Statement stamt = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");

            connection = DriverManager.getConnection(URL, User, Pwd);
            stamt = connection.createStatement();
            String sql = "select sno,sname from s";
            // 查询操作 : 返回结果集
            rs = stamt.executeQuery(sql);
            // 指针不为空一直向下走(也可以向上走 -- rs.previous())
            while (rs.next()) {
                // 通过  getXxx 方法获得 数据库中每个字段的信息 
                String sno = rs.getString("sno");
                String sname = rs.getString("sname");
                System.out.println(sno + "--" + sname);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 用完后记得关闭,最后开的先关闭,最先开的最后关闭
                rs.close();
                stamt.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    
    // 更新操作
    
    public static void update() {
        Connection connection = null;
        Statement stamt = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");

            connection = DriverManager.getConnection(URL, User, Pwd);
            stamt = connection.createStatement();
            // 括号里面的字段值需要用 单引号 '',较为复杂时要用到字符串的拼接
            String sql = "insert into s values ('1006','sd','13')";
            
            int cnt = stamt.executeUpdate(sql);
            
            if(cnt > 0) System.out.print("操作成功!");
            else System.out.print("操作失败!");
            
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 用完后记得关闭,最后开的先关闭,最先开的最后关闭
                stamt.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
        update();
//      query();
    }
}

PreparedStatement:

package controlSql;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class PreparedStatementExample {
    private static final String URL = "jdbc:mysql://localhost:3306/sqltest";
    private static final String User = "root";
    private static final String Pwd = "root";

    public static void query() {
        Connection connection = null;
        PreparedStatement stamt = null;
        ResultSet rs = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");

            connection = DriverManager.getConnection(URL, User, Pwd);
            // 查询操作(实现模糊查询)
            String sql = "select * from s where sname like ? ";
            stamt = connection.prepareStatement(sql);           
            stamt.setString(1, "%s%");
            rs = stamt.executeQuery();
            while (rs.next()) {
                // 通过  getXxx 方法获得 数据库中每个字段的信息 
                String sno = rs.getString("sno");
                String sname = rs.getString("sname");
                System.out.println(sno + "--" + sname);
            }
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 用完后记得关闭,最后开的先关闭,最先开的最后关闭
                rs.close();
                stamt.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void update() {
        Connection connection = null;
        PreparedStatement stamt = null;
        try {
            Class.forName("com.mysql.jdbc.Driver");

            connection = DriverManager.getConnection(URL, User, Pwd);
            // 插入操作
            String sql = "insert into s values (?,?,?)";
            // 预编译
            stamt = connection.prepareStatement(sql);
            // 按照位置进行插入
            stamt.setString(1, "1005");
            stamt.setString(2, "wu");
            stamt.setString(3, "23");
            
            int cnt = stamt.executeUpdate();
            
            if(cnt > 0) System.out.print("操作成功!");
            else System.out.print("操作失败!");
            
            
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                // 用完后记得关闭,最后开的先关闭,最先开的最后关闭
                stamt.close();
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    public static void main(String[] args) {
//      query();
        update();
    }
}
上一篇:xml解析数据信息并实现DBManager操作mysql


下一篇:Java中迭代器Iterator的使用