Yii 数据库相关操作
CDbConnection: 一个抽象数据库连接
CDbCommand: SQL
statement
CDbDataReader:
匹配结果集的一行记录
CDbTransaction:数据库事务
访问数据库前需要建立数据库连接;使用DAO建立一个抽象数据库链接
1 $connection = new CDbConnection($dsn, $username, $password); 2 $connection->active = true; // 只有激活了连接才可以使用 3 $connection->active = false; // 关闭连接
CDbConnection继承自CApplicationComponent,所以他可以像组件一样在任何地方使用。因此可以这样访问
Yii::app()->db
执行SQL语句需要CDbCommand对象,而该对象由CdbConnection::createCommand()返回,因此
$connection=Yii::app()->db; $command=$connection->createCommand($sql);
如果SQL语句想要完全由自己写,可以这样
$newSQL = ‘SQL语句‘; $command->text=$newSQL;
CDbCommand对象有两个方法execute()用于非查询SQL执行,而query(),通俗的讲就是用于SELECT查询
execute()返回的是INSERT,
UPDATE and DELETE操作受影响的记录行数
query()返回一个CDbDataReader对象,使用CDbDataReader对象可以遍历匹配结果集中的所有记录
$rowCount=$command->execute(); // execute the non-query SQL $dataReader=$command->query(); // execute a query SQL // 返回CDbDataReader对像 $rows=$command->queryAll(); // query and return all rows of result $row=$command->queryRow(); // query and return the first row of result $column=$command->queryColumn(); // query and return the first column of result $value=$command->queryScalar(); // query and return the first field in the first row
query()返回的是代表结果集的对象而非直接的结果,因此要获取结果集的记录可以这样
$dataReader=$command->query();
// CDbDataReader::read()可以一次获取一行数据,到末尾时返回false while(($row=$dataReader->read())!==false) {...}
// CDbDataReader实现了迭代器接口因此可以使用foreach遍历 foreach($dataReader as $row) {...}
// 一次性返回所有的记录(数组) $rows=$dataReader->readAll();
queryXXX() 形式的方法会直接返回匹配的记录集合,当query()不是,他返回一个代表结果集的对象
YII中的CDbTransaction类用于事务
// 首先,建立一个连接 $connection = Yii::app()->db; // 第二,开始事务 $transaction=$connection->beginTransaction(); // 第三,执行SQL,如果错误就抛出异常,在异常处理中回滚。 try { $connection->createCommand($sql1)->execute(); $connection->createCommand($sql2)->execute(); //.... other SQL executions // 如果SQL执行都没有抛出异常,那就提交。 $transaction->commit(); } catch(Exception $e) { $transaction->rollBack(); // 在异常处理中回滚 }
执行SQL中,一般都需要绑定一些用户参数,对于用户参数,需要防止SQL注入攻击
PDO对象的绑定参数的方法可以防止SQL注入攻击,同样扩展自PDO的DAO也有这样的功能
举例说明:
// 第一,建立一个连接: $connection = Yii::app()->db; // 第二,写下无敌的SQL语句,比如: $sql="INSERT INTO tbl_user (username, email) VALUES(:username,:email)"; // 第三,创建CDbCommand对象用于执行SQL $command=$connection->createCommand($sql); // 接下来,将SQL语句中的形式参数,替换为实际参数 $command->bindParam(":username",$username,PDO::PARAM STR); // 这与PDO有点不同,PDO中不带冒号 $command->bindParam(":email",$email,PDO::PARAM STR); // 同样 // 最后,执行 $command->execute(); // 如果还有其他的数据需要插入,可以再次绑定实参。
使用CDbDataReader对象的bindColumn()方法将结果集中的列绑定到PHP变量。
因此,读取一行记录,列值将自动填充到对应的PHP对象中
比如这样:
$connection = Yii::app()->db; $sql = "SELECT username, email FROM tbl_user"; $dataReader = $connection->createCommand($sql)->query(); //很赞的方法链, 可惜不能接着.each() $dataReader->bindColumn(1, $username); //第一列值绑定到$username $dataReader->bindColumn(2, $email); //第二列值绑定到$email //接着循环读取并操作数据 while( $dataReader->read() !== false ) { ... // 与先前的 while(($row=$dataReader->read())!==false) 有所不同哦! }
设置表前缀,使用 CDbConnection::tablePrefix 属性在配置文件中设置
// Yii实现了把一条完整的SQL语句完完全全肢解的能力,比如这样: $user = Yii::app()->db->createCommand(); ->select(‘id, username, profile‘) ->from(‘tbl_user u‘) ->join(‘tbl_profile p‘, ‘u.id=p.user_id‘) ->where(‘id=:id‘, array(‘:id‘=>$id) ->queryRow(); //返回匹配的结果集的第一行
其实这条语句是这样的: $newSQL =‘SELECT id, username, profile from tbl_user u INNER JOIN tbl_profile p ON u.id = p.user_id WHERE u.id =:id‘
yii提供了一种构建SQL的机制(也就是说不用自己写长长的SQL)
首相要实例化一个CDbCommand对象
$command = Yii::app()->db->createCommand(); // 注意参数留空了。。
可用的方法列表如下:
->select(): SELECT子句 ->selectDistinct(): SELECT子句,并保持了记录的唯一性 ->from(): 构建FROM子句 ->where(): 构建WHERE子句 ->join(): 在FROM子句中构建INNER JOIN 子句 ->leftJoin(): 在FROM子句中构建左连接子句 ->rightJoin(): 在FROM子句中构建右连接子句 ->crossJoin(): 添加交叉查询片段(没用过) ->naturalJoin(): 添加一个自然连接子片段 ->group(): GROUP BY子句 ->having(): 类似于WHERE的子句,但要与GROUP BY连用 ->order(): ORDER BY子句 ->limit(): LIMIT子句的第一部分 ->offset(): LIMIT子句的第二部分 ->union(): appends a UNION query fragment
select()默认返回全部列
// 但你可以这样: select(‘username, email‘); // 或使用表限定,或使用别名 select(‘tbl_user.id, username name‘); // 或使用数组作为参数 select(array(‘id‘, ‘count(*) as num‘));
from() 如果制定了多个表需要使用逗号分隔的字符串,就像原生SQL语句那样:
from(‘tbl_user, tbl_post, tbl_profile‘); // 当然,你也可以使用表别名, 还可以使用完整的数据库限定名 from(‘tbl_user u, public.tbl_profile p‘);
WHERE子句
// 在where()中使用 AND where(array(‘and‘, ‘id=:id‘, ‘username=:username‘), array(‘:id‘=>$id, ‘:username‘=>$username); // 在where()中使用 OR 与 AND用法相同,如下: ##看起来比直接写更加繁琐## where( array(‘and‘, ‘type=1‘, array(‘or‘, ‘id=:id‘,‘username=:username‘) ),array(‘:id‘=>$id, ‘:username‘=>$username ));
IN 操作符用法
where(array(‘in‘, ‘id‘, array(1,2,3)))
LIKE用法
where( array(‘like‘, ‘name‘, ‘%tester%‘) ); where( array(‘like‘,‘name‘, array(‘%test%‘, ‘%sample%‘)) ) // 等于 name LIKE ‘%test%‘ AND name LIKE ‘%sample% // 再这样复杂下去, 使用这种方法简直是自杀行为。 $keyword=$ GET[‘q‘]; // escape % and characters $keyword=strtr($keyword, array(‘%‘=>‘n%‘, ‘ ‘=>‘n ‘)); $command->where(array(‘like‘, ‘title‘, ‘%‘.$keyword.‘%‘));
添加了这么多,你都不知道合成后的SQL长啥样了,可以使用->text()查看(魔术方法)
如果觉得组合的SQL没有错误,那就执行他,添加->queryAll(); 这可以获得所有匹配的结果集。
当然,如果你确定执行的结果集中只有一行,可以添加->queryRow();来直接获取。
如果一个CDbCommand对象需要执行多次,那么在下一次执行之前记得调用reset();
$command = Yii::app()->db->createCommand(); $users = $command->select(‘*‘)->from(‘tbl_users‘)->queryAll(); $command->reset(); // clean up the previous query $posts = $command->select(‘*‘)->from(‘tbl_posts‘)->queryAll();
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。