每次將查詢發送給MySql服務器時,都必須解析該查詢的語法,確保結構正確並能夠執行。這是這個過程的必要步驟,但也確實帶來了一些開銷。做一次是必要的,但如果反復地執行相同的查詢,批量插入多行並只改變列值時會怎么樣呢?預處理語句會在服務器上緩存查詢的語法和執行過程,而只在服務器和客戶端之間傳輸有變化的列值,以此來消除這些額外的開銷。
PDO為支持此特性的數據庫提供了預處理語句功能。因為MySql支持這個特性,所以可以在適當時使用預處理語句。
預處理語句是使用兩個方法實現的:prepare()方法負責准備要執行的查詢,execute()方法使用一組給定的列參數反復執行查詢。這些參數可以顯示地作為數組傳遞給execute()方法,也可以使用通過bindParam()方法指定的綁定參數提供給execute()方法。
使用預處理語句--prepare()方法:
Prepare()方法負責准備要執行的查詢,語法格式如下:
PDOStatement PDO::prepare(string statement[,array driver_options]);
但是,使用准備語句的查詢和以往使用的查詢略有區別,因為對於每次執行迭代中要改變的值,必須使用占位符而不是具體的列值。
查詢支持兩種不同的語法:命名參數和問號參數。
使用命名參數的查詢如下:
insert into tb_chengji set xuesheng=:xuesheng,yuwen=:yuwen;
其中:xuesheng與:yuwen都是列占位符。
使用問號參數的查詢如下:
insert into tb_chengji set xuesheng=?,yuwen=?;
其中?也是列占位符。
選着哪一種語法都可以,但是前者更明確一些。
下面使用prepare()方法准備一個用於迭代執行的查詢:、
$dsn = "mysql:host= $db_host;dbname= $db_name";
$pdo = new PDO( $dsn, $db_user, $db_pwd);
$query = "insert into tb_chengji set xuesheng=:xuecheng,yuwen=:yuwen";
$result = $pdo->prepare( $query);
?>
上面的代碼將查詢准備好了,繼續下面的操作。
執行准備查詢--execute()方法
execute()方法負責執行准備好的查詢。語法格式如下:
bool PDOStatement::execute([array input_parameters]);
該方法需要有每次迭代執行中替換輸入的參數。可以通過兩種方法實現:作為數組將值傳遞給方法,或者通過bindParam()方法把綁定到查詢中相應的變量名或位置偏移。
下面介紹第一種方法,第二種方法在bindParam()方法中介紹。
實例代碼中准備了一條語句並通過execute()方法反復執行,每次使用不同的參數:
$db_host = '127.0.0.1';
$db_name = 'student';
$db_user = 'root';
$db_pwd = '';
$dsn = "mysql:host= $db_host;dbname= $db_name";
$pdo = new PDO( $dsn, $db_user, $db_pwd);
$pdo->query('set names utf8');
$query = "insert into tb_chengji set xuesheng=:xuesheng,yuwen=:yuwen";
$result = $pdo->prepare( $query);
$result->execute( array(':xuesheng'=>'趙天平',':yuwen'=>90));
$result->execute( array(':xuesheng'=>'張冬雪',':yuwen'=>115));
?>
下面通過使用bindParam()方法進行綁定來傳遞查詢參數。
綁定參數--bindparam()方法
execute()方法中的input_parameters參數是可選的,雖然很方便,但是如果需要傳遞多個變量時,以這種方式提供數組會很快變得難以處理(當數組元素過多時,也就是當數據表中的列過多時,代碼設計會變得特別難以閱讀或出錯)。使用bindParam()方法可以解決這個問題。預防格式如下:
Boolean PDOStatement::bindParam(mixed parameter,mixed &variable[,int datatype[,int length[,mixed driver_options]]]);
parameter:當在prepare()方法中使用命名參數時,parameter是預處理語句中使用語法(例如:xuesheng)指定的列值占位符的名字;使用問號參數時,parameter是查詢中列值占位符的索引偏移。
variable:該參數存儲將賦給占位符的值。它按引用傳遞,因為結合准備存儲過程使用此方法時,可以根據存儲過程的某個動作修改這個值。
下面修改前面的實例,使用bindParam()方法來賦列值:
$db_host = '127.0.0.1';
$db_name = 'student';
$db_user = 'root';
$db_pwd = '';
$dsn = "mysql:host= $db_host;dbname= $db_name";
$pdo = new PDO( $dsn, $db_user, $db_pwd);
$pdo->query('set names utf8');
$query = "insert into tb_chengji set xuesheng=:xuesheng,yuwen=:yuwen";
$result = $pdo->prepare( $query);
$xuesheng = '趙明明';
$yuwen = 98;
$result->bindParam(':xuesheng', $xuesheng);
$result->bindParam(':yuwen', $yuwen);
$result->execute();
$xuesheng = '王大大';
$yuwen = 120;
$result->bindParam(':xuesheng', $xuesheng);
$result->bindParam(':yuwen', $yuwen);
$result->execute();
?>