談下mysql預處理基礎
阿新 • • 發佈:2017-07-22
意思 fault pre 連接 發現 myisam 定量 ont 預編譯
傳統的操作數據庫方法有兩種:
- 先寫一條sql語句,然後通過mysqli->query($sql)去操作數據庫(此處使用的是mysqli擴展庫)。這樣操作並不會有什麽大的錯誤,但是當要插入上千條上萬條數據呢?難道也還是要這樣寫一條sql語句然後再操作一下數據庫?這裏我說下mysqli自帶的操作多條sql語句的方法,即第二種方法。
- mysqli->multi_query($sql),這是操作多條sql語句的方法,如下:
insert into student(name,age,sex,studentNo,grade) values(‘馬特‘,‘14‘,‘男‘,‘20170809‘,‘六年級
如果你認為這樣就可以完全解決問題,那麽你就錯了,接下來讓我們來看一看MySQL數據庫執行sql語句的原理!
從上圖可以看出,無論我們是發送一條sql語句還是發送多條sql語句,數據庫都要對其一一的進行編譯,那麽當數據達到一定量之後,數據庫的開銷就必然很大。那究竟怎樣解決這個問題呢?此時就引入了預處理技術的概念。
下面我們來看一段預處理技術的代碼:
student表結構如下:CREATE TABLE `student` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT, `age`
<?php /** * Created by PhpStorm. * User: Administrator * Date: 2017/7/22 * Time: 10:52 */ $mysqli = new mysqli("localhost", "root", "root", "test"); if ($mysqli->connect_error) { die("連接失敗" . $mysqli->error); } $mysqli->query("set names utf8");//設置編碼格式為utf-8,這樣數據庫展示中文的時候才不會出錯 $sql = "insert into student(name,age,sex,studentNo,grade) values (?,?,?,?,?)"; //向數據庫發送sql語句,讓數據庫對該sql語句先進行編譯 $mysqli_stmt = $mysqli->prepare($sql); if( !$mysqli_stmt ) { die( $mysqli->error ); } //綁定參數 $name = "珀利"; $age = 13; $sex = ‘男‘; $stuNo = "201501225"; $grade = ‘四年級‘; $mysqli_stmt->bind_param("siisd", $name, $age, $sex, $stuNo, $grade); $mysqli_stmt->execute();//執行 $mysqli->close();//關閉連接
首先我們來看
$sql = "insert into student(name,age,sex,studentNo,grade) values (?,?,?,?,?)";
?這裏的問號相當於一個占位符,之後只要向數據庫發送數據就能夠自動把數據對應的填充進去 這就是預編譯技術的精髓之處,我們通過$mysqli_stmt = $mysqli->prepare($sql);向數據庫發送sql語句,然後數據庫對該sql語句進行編譯,
並且數據庫不會立即釋放掉編譯的結果。 $mysqli_stmt->bind_param("siisd", $name, $age, $sex, $stuNo, $grade);bind_param,顧名思義,就是綁定參數的意思,那麽,它給誰綁定參數呢?
看看上面的values (?,?,?,?,?),bind_param裏面的參數一一對應著values的每一個參數。那麽bind_param裏面的siisd又是什麽意思呢?別急,請看下方:參數有以下四種類型: i - integer(整型) d - double(雙精度浮點型) s - string(字符串) b - BLOB(布爾值) 每個參數都需要指定類型。 通過告訴數據庫參數的數據類型,可以降低 SQL 註入的風險. $mysqli_stmt->execute();這句代碼就是將數據傳遞給數據庫了。
我們來用預處理查詢數據庫:
<?php $mysqli = new mysqli("localhost","root","root","test"); if($mysqli->connect_error){ die("連接失敗".$mysqli->error); } $mysqli->query("set names utf8"); $sql="select name,sex,age from student where id>?"; $mysqli_stmt=$mysqli->prepare($sql); if( !$mysqli_stmt ) { die( $mysqli->error ); } $id=1; $mysqli_stmt->bind_param("i",$id); $mysqli_stmt->execute(); $mysqli_stmt->bind_result($name,$sex,$age);//綁定結果集,傳遞的是引用 while($mysqli_stmt->fetch()){ echo "$name:$sex:$age"."<br>"; } $mysqli_stmt->free_result();//關閉資源 $mysqli_stmt->close();//關閉預編譯語句,否則數據庫會一直保存 $mysqli->close();//關閉連接
輸出: 馬特:男:14 凱文:女:15
我們看到有這麽一句:
$sql="select name,sex,age from student where id>?";
看看這句sql語句,你會發現bind_result裏面的參數一一對應於sql語句當中你要查詢的字段(name,sex,age),當然,bind_result裏面的參數可以不與sql語句的字段名字相同,但是通常推薦這樣做。
談下mysql預處理基礎