PreparedStatement与Statement
相同点:创建对象,通过此对象调用executeQuery方法执行sql语句
不同点
语句格式不同:PrepareStatement把SQL中的参数、变量剥离出来,看似代码行数增加,实则提高了代码的可阅读性
语句中的变量用问号代替,而后通过setString给变量传值,有效防止SQL注入,增强了安全性
实现SQL语句模板化,模板可以预定义,相同的SQL语句可以发送给SQL引擎预处理,提高了执行效率
预处理:创建 SQL 语句模板并发送到数据库。预留的值使用参数 "?" 标记,例如:
INSERT INTO MyGuests(username, pwd, age) VALUES(?, ?, ?);
SELECT * FROM tableName WHERE columName1 = ? AND columName2 = ?
数据库解析,编译,对SQL语句模板执行查询优化,并存储结果(不输出)。
执行:最后,将应用绑定的值传递给参数("?" 标记),数据库执行语句。应用可以多次执行语句,如果参数的值不一样。
例子
由于数据库对语句进行了预处理,所以相同语句看似多次执行,但实际只做了一次查询,减少了分析时间。
绑定参数减少了服务器带宽,执行时只需发送查询参数,而非整个语句。
参数值发送后使用不同的协议,有效防止SQL注入,保证了数据的合法性。
预处理语句分为DML预处理(操作数据)和DQL预处理(查询数据)
DML预处理:
相同点:创建对象,通过此对象调用executeQuery方法执行sql语句
不同点
语句格式不同:PrepareStatement把SQL中的参数、变量剥离出来,看似代码行数增加,实则提高了代码的可阅读性
语句中的变量用问号代替,而后通过setString给变量传值,有效防止SQL注入,增强了安全性
实现SQL语句模板化,模板可以预定义,相同的SQL语句可以发送给SQL引擎预处理,提高了执行效率
例1:用CreateStatement方法创建对象stmt,通过stmt执行SQL
String $sql = "select * from users where username = $username and userpwd = $userpwd";
$stmt = conn.createStatement();
$rs = stmt.executeQuery($sql);
例2:用PrepareStatement方法创建对象pstmt,通过stmt执行SQL
$sql = "select * from users where username = ? and userpwd= ? ";
$pstmt = conn.prepareStatement(sql);
$pstmt.setString(1, username);
$pstmt.setString(2, userpwd);
$rs = pstmt.executeQuery($sql);
预处理语句的工作原理:
预处理:创建 SQL 语句模板并发送到数据库。预留的值使用参数 "?" 标记,例如:
INSERT INTO MyGuests(username, pwd, age) VALUES(?, ?, ?);
SELECT * FROM tableName WHERE columName1 = ? AND columName2 = ?
数据库解析,编译,对SQL语句模板执行查询优化,并存储结果(不输出)。
执行:最后,将应用绑定的值传递给参数("?" 标记),数据库执行语句。应用可以多次执行语句,如果参数的值不一样。
例子
$sql = "INSERT INTO MyGuests(username, pwd, age) VALUES(?, ?, ?)"; //预定义语句
$username = "Admin"; //准备参数值
$pwd = "123";
$age = 25;
$pstmt = conn.prepareStatement(sql); //传参
$pstmt.setString(1, $username);
$pstmt.setString(2, $pwd);
$pstmt.setString(3, $age);
$rs = pstmt.executeQuery($sql); //执行
预处理语句的优点:
由于数据库对语句进行了预处理,所以相同语句看似多次执行,但实际只做了一次查询,减少了分析时间。
绑定参数减少了服务器带宽,执行时只需发送查询参数,而非整个语句。
参数值发送后使用不同的协议,有效防止SQL注入,保证了数据的合法性。
预处理语句分为DML预处理(操作数据)和DQL预处理(查询数据)
DML预处理:
$mysqli = new mysqli('localhost','root','mayi1991','dbname'); //创建连接对象
$mysqli->query('set names utf8'); //设置编码
$mysqli_stmt = $mysqli->prepare("INSERT tableName(username, pwd, age) values(?, ?, ?)"); //发送SQL模板给数据库引擎进行预编译
$username = "Admin";
$pwd = "123";
$age = 25;
$mysqli_stmt->bind_param("ds", $username, $pwd, $age); //传递参数给数据库引擎(不能直接传值,只能用变量)
$mysqli_stmt->execute(); //执行(返回boolean值)
DQL预处理:
$mysqli = new mysqli('localhost','root','mayi1991','dbname'); //创建连接对象
$mysqli_stmt = $mysqli->prepare('SELECT username, pwd, age FROM tableName WHERE username = ?'); //发送SQL模板给数据库引擎进行预编译
$username = "Admin"; //绑定参数
$mysqli_stmt->bind_param('i', $username); //传递参数给数据库引擎(不能直接传值,只能用变量)
$mysqli_stmt->execute();//执行
$mysqli_stmt->bind_result($username, $pwd, $age); //绑定结果集(变量指向的是内存地址)
while($mysqli_stmt->fetch() //输出结果集
{
echo "$username--$pwd--$age";
}
bind_param函数:bind_param(“sss”, firstname,firstname,lastname, $email);
1:该函数绑定了 SQL 的参数,且告诉数据库参数的值。 “sss” 参数列处理其余参数的数据类型。s 字符告诉数据库该参数为字符串。
参数有以下四种类型:
i - integer(整型)
d - double(双精度浮点型)
s - string(字符串)
b - BLOB(布尔值)
每个参数都需要指定类型。