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();
	}
}

原文地址:https://www.cnblogs.com/prjruckyone/p/12503410.html