在学习PDO数据库抽象层的视频的时候,整理Mr.King老师的视频笔记如下,算是一个学习记录,如果对此感兴趣的同学请移步至imooc网站上自行查看学习该系列视频=> http://www.imooc.com/learn/164
----------------------------------------------------我是笔记的分割线---------------------------------------------------------
1. PDO简介
2. PDO的安装与配置
3. PDO链接数据库(MySQL数据库)
4. PDO对象方法介绍及使用
5. PDOStatement对象方法介绍及使用
6. PDO错误处理
7. PDO参数绑定与预处理
8. PDO事务处理
9. PDO实战
PDO(PHP Data Object),数据库访问抽象层,统一各种数据库的访问接口。
为什么要使用PDO?
PHP支持市面上所有的数据库。PHP对数据库的支撑不好。应用程序之间难以维护。抽象度不够,访问接口不通一。让PHP对多种数据库比较艰难。重新编写跟数据库相关的函数。PDO出现了,可以让代码变得更简洁。无论使用哪一种数据库都可以。
PDO有什么优点?
编码一致性。
灵活性。
高性能。PDO使用C语言编写的。
面向对象特性。PDO利用PHP5面向对象的特性。
PDO支持的数据库
PDO安装与配置
1. 配置PHP配置文件,开启相应扩展
extension=pdo.so(linux)
extension=php_pdo.dll(windows)
2. 开启对相应数据库的扩展(以MySQL为例)
extension=pdo_mysql.so(linux)
extension=php_pdo_mysql.dll(windows)
3. 通过查看phpinfo可以看到PDO扩展的详细信息
PDO连接数据库
1. 通过参数的形式连接数据库2. 通过URI形式连接数据库
3. 通过配置文件形式连接数据库
通过参数的形式连接数据库(推荐这种形式)
<?php
try{
$dsn='mysql:host=localhost;dbname=imooc';
$username='root';
$passwd='root';
$pdo=new PDO($dsn,$username,$passwd);
}catch(PDOException $e){
echo $e->getMessage();
}
?>
output:
object(PDO)#1 (0) { }
<?php
try{
$dsn='uri:/var/www/html/dsn.txt'; //Linux
//windows: $dsn='uri:file://G:\phpdev\apache\htdocs\pdo\dsn.txt';
$username='root';
$passwd='root';
$pdo=new PDO($dsn,$username,$passwd);
var_dump($pdo);
}catch(PDOException $e){
echo $e->getMessage();
}
?>
dsn.txt
mysql:dbname=imooc;host=localhost
output:
object(PDO)#1 (0) { }
修改php.ini文件,在php.ini文件里任意一个位置加入以下这行:
<span style="font-size:14px;">pdo.dsn.imooc="mysql:host=localhost;dbname=imooc"</span>
修改完后重启apache
代码
<span style="font-size:14px;">
<?php
try{
$dsn='imooc'; //数据库名字
$username='root';
$passwd='root';
$pdo=new PDO($dsn,$username,$passwd);
var_dump($pdo);
}catch(PDOException $e){
echo $e->getMessage();
}
?>
</span>
output:object(PDO)#1 (0) { }
PDO对象的方法
exec() 执行一条SQL语句,并返回其受影响的行数
query() 执行一条SQL语句,返回一个PDOStatement对象
prepare() 准备要执行的SQL语句,返回PDOStatement对象
quote() 返回一个添加引号的字符串,用于SQL语句中
lastInsertId() 返回最后插入行的ID
setAttribute() 设置数据库连接属性
getAttribute() 得到数据库连接的属性
errorCode() 获取跟数据库句柄上一次操作相关的SQLSTATE
errorInfo() 获取跟数据库句柄上一次操作的错误信息
创建表以及插入一条数据
MySQL版本:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
//exec() 执行一条SQL语句,并返回其受影响的行数, 如果没有受影响的记录,他返回0
//exec()对于select没有作用
$sql=<<<EOF
CREATE TABLE IF NOT EXISTS user(
id INT UNSIGNED AUTO_INCREMENT KEY,
username VARCHAR(20) NOT NULL UNIQUE,
password CHAR(32) NOT NULL,
email VARCHAR(30) NOT NULL
);
EOF;
$res=$pdo->exec($sql);
var_dump($res);
$sql='INSERT user(username,password,email) VALUES("king","'.md5('king').'","imooc@qq.com")';
$res=$pdo->exec();
echo $res;
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
DB2版本:
<?php
try{
$database = 'odbc:TEST';
$username='db2inst1';
$password='';
$pdo=new PDO($database,$username,$password);
//exec() 执行一条SQL语句,并返回其受影响的行数, 如果没有受影响的记录,他返回0
//exec()对于select没有作用
$sql=" CREATE TABLE TEST.USER_TABLE(
id INT not null GENERATED ALWAYS AS IDENTITY (START WITH 1 INCREMENT BY 1),
username VARCHAR(20) NOT NULL UNIQUE,
password CHAR(32) NOT NULL,
email VARCHAR(30) NOT NULL
)";
$res=$pdo->exec($sql);
echo $res;
//插入一条数据
$sql="INSERT INTO TEST.USER_TABLE (USERNAME,PASSWORD,EMAIL) VALUES ('elsa2','".md5("dfsdfsdfs")."','elsa13@cn.ibm.com');";
$res=$pdo->exec($sql);
echo $res;
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output:
int(0)
int(1)
exec()方法执行插入多条数据
插入多条数据:
MySQL版本:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
//exec() 执行一条SQL语句,并返回其受影响的行数, 如果没有受影响的记录,他返回0
//exec()对于select没有作用
$sql=<<<EOF
INSERT user(username,password,email) VALUES("king1","king1","imooc1@qq.com"),
("king2","king2","imooc2@qq.com"),
("king3","king3","imooc3@qq.com")
EOF;
$res=$pdo->exec($sql);
var_dump($res); //output: 3 意味3条记录插入成功
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
DB2版本:
<?php
try{
$database = 'odbc:TEST';
$username='db2inst1';
$password='';
$pdo=new PDO($database,$username,$password);
//插入多条数据
$sql="INSERT INTO TEST.USER_TABLE (USERNAME,PASSWORD,EMAIL) VALUES ('king1','king1','imooc1@qq.com'),
('king2','king2','imooc2@qq.com'),
('king3','king3','imooc3@qq.com')";
$res=$pdo->exec($sql);
var_dump($res);
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output: int(3)
返回最后插入一行的ID号:
MySQL版本:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
//exec() 执行一条SQL语句,并返回其受影响的行数, 如果没有受影响的记录,他返回0
//exec()对于select没有作用
$sql=‘INSERT user(username,password,email) VALUES("king1","king1","imooc1@qq.com")’;
$res=$pdo->exec($sql);
echo 'affected row count:'.$res;
//$pdo->lastInsertId(); 得到新插入记录的ID号
echo 'last inserted id:'.$pdo->lastInsertId();
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
DB2版本:
<?php
try{
$database = 'odbc:TEST';
$username='db2inst1';
$password='';
$pdo=new PDO($database,$username,$password);
//var_dump($pdo);
//插入一条数据
$sql="INSERT INTO TEST.USER_TABLE (USERNAME,PASSWORD,EMAIL) VALUES ('king4','king4','imooc4@qq.com')";
$res=$pdo->exec($sql);
echo 'affected row count:'.$res;
//$pdo->lastInsertId(); 得到新插入记录的ID号
echo 'last inserted id:'.$pdo->lastInsertId();
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output:
affected row count:1
Warning: PDO::lastInsertId(): SQLSTATE[IM001]: Driver does not support this function: driver does not support lastInsertId() in /var/www/html/test/exec.php on line 33
last inserted id:
因为我的IBM DB2 ODBC Driver不支持lastInsertId这个function,查了PHP官网,也没有个解决方案。
更改auto_increment的值:alter table user auto_increment=10;
更新和删除:
更新:
MySQL版本:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql='UPDATE user set username = "imooc" where id = 1';
$res=$pdo->exec($sql);
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
DB2版本:
<?php
try{
$database = 'odbc:TEST';
$username='db2inst1';
$password='';
$pdo=new PDO($database,$username,$password);
//var_dump($pdo);
//更改某条记录
$sql="UPDATE TEST.USER_TABLE SET USERNAME = 'imooc' where ID = 1;";
$res=$pdo->exec($sql);
echo $res.'条记录被影响';
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output: 1条记录被影响
删除:
MySQL版本:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql='DELETE user where id = 3';
$res=$pdo->exec($sql);
echo 'affected row count:'.$res;
//$pdo->lastInsertId(); 得到新插入记录的ID号
echo 'last inserted id:'.$pdo->lastInsertId();
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
DB2版本:
<?php
try{
$database = 'odbc:TEST';
$username='db2inst1';
$password='';
$pdo=new PDO($database,$username,$password);
$sql="DELETE FROM TEST.USER_TABLE where ID = 4;";
$res=$pdo->exec($sql);
echo $res.'条记录被影响';
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output:
1条记录被影响
注意:
sql语句有问题, var_dump($res)返回bool(false)
查询:
Mysql版本:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql=‘select * from user where id=2’;
//$pdo->query($sql),执行SQL语句,返回PDOStatement对象
$stmt=$pdo->query($sql);
//var_dump($stmt);
//loop print this statement
foreach($stmt as $row){
print_r($row);
}
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
DB2版本:
<?php
try{
$database = 'odbc:TEST';
$username='db2inst1';
$password='';
$pdo=new PDO($database,$username,$password);
$sql="SELECT * FROM TEST.USER_TABLE where ID = 4;";
$res=$pdo->exec($sql);
var_dump($res);
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output:
int(0)
注意:
查询语句, var_dump($res), int(0)代表没有受影响记录
errorCode()和errorInfo()方法查看错误信息
DB2版本:
<?php
try{
$database = 'odbc:TEST';
$username='db2inst1';
$password='';
$pdo=new PDO($database,$username,$password);
//USER_TABLE1 doesn't exist
$sql="SELECT * FROM TEST.USER_TABLE1 where ID = 4;";
$res=$pdo->exec($sql);
//var_dump($res);
if($res==false){
//$pdo->errorCode(); SQLSTATE的值
echo $pdo->errorCode();
echo "<hr/>";
//$pdo->errorInfo(); 返回的错误信息的数组,数组中包含3个单元
//0=>SQLSTATE, 1=>CODE, 2=> Info
print_r($pdo->errorInfo());
}
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output:
42S02
<hr/>
Array
(
[0] => 42S02
[1] => -204
[2] => [IBM][CLI Driver][DB2/LINUXX8664] SQL0204N "TEST.USER_TABLE1" is an undefined name. SQLSTATE=42704
(SQLExecDirect[4294967092] at xxxx)
[3] => 42S02
)
query()方法执行查询
MySQL版本:
<?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql=‘select * from user where id=2’;
//$pdo->query($sql),执行SQL语句,返回PDOStatement对象
$stmt=$pdo->query($sql);
//var_dump($stmt);
//loop print this statement
foreach($stmt as $row){
print_r($row);
}
}catch(PDOException $e){
echo $e->getMessage();
}
?>
DB2版本:
<?php
try{
$database = 'odbc:TEST';
$username='db2inst1';
$password='';
$pdo=new PDO($database,$username,$password);
$sql="SELECT * FROM TEST.USER_TABLE where id=2";
//$pdo->query($sql),执行SQL语句,返回PDOStatement对象
$stmt=$pdo->query($sql);
//var_dump($stmt);
//loop print this statement
foreach($stmt as $row){
print_r($row);
}
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output:
Array
(
[ID] => 2
[0] => 2
[USERNAME] => king1
[1] => king1
[PASSWORD] => king1
[2] => king1
[EMAIL] => imooc1@qq.com
[3] => imooc1@qq.com
)
遍历数组
<?php
try{
$database = 'odbc:TEST';
$username='db2inst1';
$password='';
$pdo=new PDO($database,$username,$password);
$sql="SELECT * FROM TEST.USER_TABLE";
//$pdo->query($sql),执行SQL语句,返回PDOStatement对象
$stmt=$pdo->query($sql);
//var_dump($stmt);
//loop print this statement
foreach($stmt as $row){
echo "ID: ".$row['ID'],"<br/>";
echo "username: ".$row['USERNAME'],"<br/>";
echo "Password: ".$row['PASSWORD'],"<br/>";
echo "Email: ".$row['EMAIL'],"<br/>";
echo "<hr/>";
}
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output:
ID: 1
username: imooc
Password: 6a247bf79ec8e85271b9e97da136e559
Email: elsa@qq.com
ID: 2
username: king1
Password: king1
Email: imooc1@qq.com
ID: 3
username: king2
Password: king2
Email: imooc2@qq.com
ID: 5
username: king4
Password: king4
Email: imooc4@qq.com
使用query()插入一条记录
<?php
try{
$database = 'odbc:SR';
$username='db2inst1';
$password='zaq12wsx';
$pdo=new PDO($database,$username,$password);
$sql="INSERT INTO TEST.USER_TABLE (USERNAME,PASSWORD,EMAIL) VALUES ('king6','king6','imooc6@qq.com')";
$stmt=$pdo->query($sql);
var_dump($stmt);
}catch(PDOException $e){
echo $e->getMessage();
}
?>
Output:
object(PDOStatement)#2 (1) { ["queryString"]=> string(94) "INSERT INTO TEST.USER_TABLE (USERNAME,PASSWORD,EMAIL) VALUES ('king6','king6','imooc6@qq.com')" }
<?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql=‘select * from user’;
$stmt=$pdo->prepare($sql);
$res=$stmt->execute();
$row=$stmt->fetch();
print_r($row);
}catch(PDOException $e){
echo $e->getMessage();
}
?>
<?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql=‘select * from user’;
$stmt=$pdo->prepare($sql);
$res=$stmt->execute();
if($res){
//fetch()从结果集中返回一行
while($row=$stmt->fetch()){
print_r($row);
echo '<hr/>';
}
}
}catch(PDOException $e){
echo $e->getMessage();
}
?>
<?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql=‘select * from user’;
$stmt=$pdo->prepare($sql);
$res=$stmt->execute();
//取他的值和下标
$rows=$stmt->fetchAll();
print_r($rows);
}catch(PDOException $e){
echo $e->getMessage();
}
?>
<?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql=‘select * from user’;
$stmt=$pdo->prepare($sql);
$res=$stmt->execute();
if($res){
//fetch()从结果集中返回一行
while($row=$stmt->fetch(PDO::FETCH_ASSOC)){
print_r($row);
echo '<hr/>';
}
}
}catch(PDOException $e){
echo $e->getMessage();
}
?>
关联部分:
//PDO::FETCH_ASSOC 返回关联 Array ([id]=>2 [username]=>king1 [password]=>king1 [email]=>imooc1@qq.com)
//PDO::FETCH_BOTH 返回关联+索引 Array([id]=>2 [0]=>2 [username]=>king1 [1]=>king1 [password]=>king1 [2]=>king1 [email]=>imooc1@qq.com [3]=>imooc1@qq.com)
//PDO::FETCH_OBJ返回对象 stdClass Object ([id]=>2 [username]=>king1 [password]=>king1 [email]=>imooc1@qq.com)
PDOStatement对象的方法
execute() 执行一条预处理语句
rowCount() 返回上一个SQL语句影响的行数
fetch() 从结果集中获取一行
fetchAll() 返回一个包含结果集中所有行的数组
setFetchModel() 为语句设置默认的获取模式
fetchColumn() 从结果集中的下一行返回单独的一列
fetchObject() 获取下一行并作为一个对象返回
bindParam() 绑定一个参数到指定的变量名
bindValue() 把一个值绑定到一个参数
设置数据库连接属性
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
echo '自动提交'.$pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);
echo '<br/>';
echo ‘PDO默认的错误处理模式:’.$pdo->getAttribute(PDO::ATTR_ERRMODE);
$pdo->setAttribute(PDO::ATTR_AUTOCOMMIT,0);
echo '自动提交'.$pdo->getAttribute(PDO::ATTR_AUTOCOMMIT);
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
bindParam() 绑定一个参数到指定的变量名
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql = "insert user(username, password, email) VALUES (:username, :password, :email)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(":username",$username, PDO::PARAM_STR);
$stmt->bindParam(":password",$password, PDO::PARAM_STR);
$stmt->bindParam(":email",$email);
$username="imooc";
$password="imooc";
$email="imooc@imooc.com";
$stmt->execute();
echo $stmt->rowCount(); //返回受影响的行数
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql = "insert user(username, password, email) VALUES (?,?,?)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(1,$username);
$stmt->bindParam(2,$password);
$stmt->bindParam(3,$email);
$username="imooc";
$password="imooc";
$email="imooc@imooc.com";
$stmt->execute();
echo $stmt->rowCount(); //return affected row
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
//$sql = "delete from user where username = :username and password = :password";
$sql = "delete from user where id <: id ";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(":id",$id, PDO::PARAM_INT);
$id=10;
$stmt->execute();
echo $stmt->rowCount(); //return affected rows count
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
bindValue() 把一个值绑定到一个参数
写法一:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql = 'insert user(username, password, email) VALUES(?,?,?) ';
$stmt=$pdo->prepare($sql);
$username='imooc';
$password='imooc';
$email='imooc@imooc.com';
$stmt->bindValue(1,$username);
$stmt->bindValue(2,$password);
$stmt->bindValue(3,$email);
$stmt->execute();
echo $stmt->rowCount();
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
写法二:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql = 'insert user(username, password, email) VALUES(:username,:password,:email) ';
$stmt=$pdo->prepare($sql);
$username='imooc';
$password='imooc';
$email='imooc@imooc.com';
$stmt->bindValue(':username',$username);
$stmt->bindValue(':password',$password);
$stmt->bindValue(':email',$email);
$stmt->execute();
echo $stmt->rowCount();
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
PDOStatement对象的方法
PDO函数 说明
bindColumn() 绑定一列到一个PHP变量
getColumnMeta() 返回结果集中一列的元数据
columnCount() 返回结果集中的列数
setAttribute() 设置一个语句属性
getAttribute() 检索一个语句属性
errorCode() 获取跟上一次语句句柄操作相关的SQLSTATE
errorInfo() 获取跟上一次语句句柄操作相关的扩展错误信息
debugDumpParam() 打印一条SQL预处理命令
nextRowset() 在一个多行集语句句柄中推进到下一个行集
bindColumn() 绑定一列到一个PHP变量
<span style="font-size:14px;"><?php
header('content-type:text/html;charset=utf-8');
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql = 'select username, password, email from user';
$stmt=$pdo->prepare($sql);
$stmt->execute();
echo "how many columns in result? ".$stmt->columnCount(); //under development
echo '<hr/>';
print_r($stmt->getColumnMeta(0)); //under development
$stmt->bindColumn(1,$username);
$stmt->bindColumn(2,$password);
$stmt->bindColumn(3,$email);
while($stmt->fetch(PDO::FETCH_BOUND)){
echo 'username: ' . $username . 'password: ' . $password .'email: '. $email.'<hr/>';
}
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
<span style="font-size:14px;"><?php
header('content-type:text/html;charset=utf-8');
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql = 'select username, password, email from user';
$stmt=$pdo->query($sql);
$stmt->fetchColumn(0),'<br/>'; //第一行的第一列
$stmt->fetchColumn(1),'<br/>'; //第二行的第二列(当执行完一次指针下移,无法继续取得第一行的第二列,此时在fetchColumn中,第二行为第一行)
$stmt->fetchColumn(2),'<br/>'; //第三行的第三列(同上,指针下移,第三行为第一行)
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
debugDumpParam() 打印一条SQL预处理命令
写法一:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql='INSERT user(username,password,email) VALUES(?,?,?);';
$stmt->$pdo->prepare($sql);
$stmt->bindParam(1,$username,PDO::PARAM_STR);
$stmt->bindParam(2,$password,PDO::PARAM_STR);
$stmt->bindParam(3,$email,PDO::PARAM_STR);
$username='testParam';
$password='testParam';
$email='testParam@imooc.com';
$stmt->execute();
$stmt->debugDumpParams();
}catch(PDOException $e){
echo $e->getMessage();
}
?>
</span>
写法二:
<span style="font-size:14px;"><?php
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql='select * user where username=:username AND password =:password;';
$stmt->$pdo->prepare($sql);
$stmt->bindParam(':username',$username,PDO::PARAM_STR);
$stmt->bindParam(':password',$password,PDO::PARAM_STR);
$username='testParam';
$password='testParam';
$stmt->execute();
$stmt->debugDumpParams();
}catch(PDOException $e){
echo $e->getMessage();
}
?>
</span>
nextRowset() 在一个多行集语句句柄中推进到下一个行集
/***创建一个存储过程***/
DELIMITER //
CREATE PROCEDURE test1)
BEGIN
SELECT * FROM user;
SELECT * FROM userAccount;
END
//
DELIMITER;
<?php
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql='call test1()';
$stmt=$pdo->query($sql);
$rowset=$stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($rowset);
echo '<hr color="red"/>';
$stmt->nextRowset();
$rowset=$stmt->fetchAll(PDO::FETCH_ASSOC);
print_r($rowset);
?>
PDO错误处理模式
<span style="font-size:14px;"><?php
/*
PDO::ERRMODE_SLIENT:默认模式
PDO::ERRMODE_WARNING:警告模式
PDO::ERRMODE_EXCEPTION:异常模式
*/
try{
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_WARNING);
$sql = 'select * from noneTable'; //没有这个表格
$pdo->query($sql);
echo $pdo->errorCode(); //sqlstate error code
echo '<br/>';
print_r($pdo->errorInfo()); //错误信息以数组的形式打印出来
}catch(PDOException $e){
echo $e->getMessage();
}
?></span>
PDO对象的方法
方法 | 描述 |
beginTransaction() | 启动一个事务 |
commit() | 提交一个事务 |
rollBack() | 回滚一个事务 |
inTransaction() | 检测是否在一个事务内 |
事务:把很多事情当作一件事情做,要么都成功,要么都失败
四大特性(ACID):
https://en.wikipedia.org/wiki/ACID
http://stackoverflow.com/questions/3740280/acid-and-database-transactions
原子型(Atomicity) - all or nothing,如果事务中的一部分失败了,那么整个事务都失败。数据库状态不会被改变。
一致性(Consistency) - 因为是要么提交全部,要么全部都未提交成功,所以所有数据是一致的,不会有数据不全的现象出现。
独立性(Isolation) - 一个事务在没有完成当前事务的时候,不能进行下一个事务。如果两个事务是同时运行的,那他们可能是按照序列并行。如果一个事务需要读取另一个事务的数据,那需要等待。
持久性(Durability) - 一旦一个事务完成后,他将会保存在一个持久的媒介上比如一个硬盘,而且事务完成就好象被记录好了一样。
/***************以下是一个银行转账的例子******************/
userAccount.sql
create table if not exist userAccount(
id TINYINT UNSIGNED AUTO_INCREMENT KEY,
username VARCHAR(20) NOT NULL UNIQUE,
money DECIMAL(10,2)
)ENGINE=INNOOB;
INSERT userAccount(username, money) VALUES ('imooc', 10000),('king',5000);
<?php
try{
$options=array(PDO::ATTR_AUTOCOMMIT,0);
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root',$options);
var_dump($pdo->inTransaction()); //返回bool(false),因为还未开启事务
$pdo->beginTransaction(); //开启事务
var_dump($pdo->inTransaction()); //返回bool(true),因为事务已开启
$sql='UPDATE userAccount SET money = money-2000 where username="imooc"';
$res1=$pdo->exec($sql);
if($res1==0){
throw new PDOException('imooc 转账失败!');
}
$res2=$pdo->exec('UPDATE userAccount SET money=money+2000 where username="king";');
if($res2==0){
throw new PDOException('king 接收失败!');
}
//提交事务:二者都成功
$pdo->commit();
}catch(PDOException $e){
//回滚事务:二者都失败
$pdo->rollBack();
echo $e->getMessage();
}
?>
PDO效率剖析
setAttribute() 设置一个语句属性
getAttribute() 检索一个语句属性
测试PDO连接数据库和MySQL连接数据库的效率
testPDO.php
<?php
//1. 通过PDO连接数据库
$pStartTime=microtime(true);
for($i=1;$i<=100;$i++){
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
}
$pEndTime=microtime(true);
$res1=$pEndTime-$pStartTime;
//2. 通过MySQL连接数据库
$mStartTime=microtime(true);
for($=1;$i<=100;$i++){
mysql_connect('localhost','root','root');
mysql_select_db('imooc');
}
$mEndTime=microtime(true);
$res2=$mEndTime-$mStartTime;
echo $res1,'<br/>',$res2;
echo '<hr/>';
//3. 两者对比效率
if($res1>$res2){
echo 'PDO连接数据库效率是MySQL的'.round($res1/$res2)."倍";
}else{
echo 'MySQL连接数据库效率是PDO的'.round($res2/$res1)."倍";
}
?>
结论:PDO连接数据库MySQL的13倍(PDO连接数据库的效率较MySQL低)
测试通过PDO插入100条记录和MySQL插入100条记录的效率
CREATE TABLE test2(
id INT
);
<?php
//1. 通过PDO连接数据库
$pStartTime=microtime(true);
$pdo=new PDO('mysql:host=localhost;dbname=imooc','root','root');
$sql='INSERT test2 values(:id)';
$stmt=$pdo->prepare($sql);
for($i=1;$i<=500;$i++){
$id=1;
$stmt->bindParam(':id',$id,PDO::PARAM_INT);
$stmt->execute();
}
$pEndTime=microtime(true);
$res1=$pEndTime-$pStartTime;
unset($pdo); //$pdo=null
//2. 通过MySQL连接数据库
$mStartTime=microtime(true);
mysql_connect('localhost','root','root');
mysql_select_db('imooc');
for($=1;$i<=500;$i++){
$sql='INSERT test2 values(2)';
mysql_query($sql);
}
mysql_close();
$mEndTime=microtime(true);
$res2=$mEndTime-$mStartTime;
echo $res1,'<br/>',$res2;
echo '<hr/>';
//3. 两者对比效率
if($res1>$res2){
echo 'PDO插入500条记录的是MySQL的'.round($res1/$res2)."倍";
}else{
echo 'MySQL插入500条记录的是PDO的'.round($res2/$res1)."倍";
}
?>
结论:PDO插入500条记录的是MySQL的1倍(PDO插入数据的效率较MySQL低)