YII Framework学习教程-YII的Model-数据库操作3-自定义的DAO操作
虽然我们可以使用CActvieReord完成大部分对数据库的操作。他简化了数据库操作,但是有时候却把一些数据库操作复杂化了。所以YII同时允许我们可以自己连接数据库,组织查询语句,执行查询语句,获取查询结果。这样可以让我们灵活的选择使用哪一种方式。
下面讲讲YII提供的DAO操作相关类的使用方法。具体类在framework/db文件夹中
. ├── ar │ ├── CActiveFinder.php │ ├── CActiveRecordBehavior.php │ └── CActiveRecord.php ├── CDbCommand.php主要用于执行数据库相关操作的sql语句 ├── CDbConnection.php用于连接数据库 ├── CDbDataReader.php对数据库结果集操作 ├── CDbException.php数据库异常类 ├── CDbMigration.php数据库迁移 ├── CDbTransaction.php数据库事务 └── schema底层的数据库操作语法,针对不同的数据库,如果你想自定义其他数据库操作,可以在这里参考yii提供的数据库操作的类实现。 ├── CDbColumnSchema.php ├── CDbCommandBuilder.php ├── CDbCriteria.php ├── CDbExpression.php ├── CDbSchema.php ├── CDbTableSchema.php ├── mssql │ ├── CMssqlColumnSchema.php │ ├── CMssqlCommandBuilder.php │ ├── CMssqlPdoAdapter.php │ ├── CMssqlSchema.php │ └── CMssqlTableSchema.php ├── mysql │ ├── CMysqlColumnSchema.php │ ├── CMysqlSchema.php │ └── CMysqlTableSchema.php ├── oci │ ├── COciColumnSchema.php │ ├── COciCommandBuilder.php │ ├── COciSchema.php │ └── COciTableSchema.php ├── pgsql │ ├── CPgsqlColumnSchema.php │ ├── CPgsqlSchema.php │ └── CPgsqlTableSchema.php └── sqlite ├── CSqliteColumnSchema.php ├── CSqliteCommandBuilder.php └── CSqliteSchema.php 7 directories, 33 files
可以看到,数据库操作类主要是:
├── CDbConnection.php
├── CDbCommand.php
├── CDbDataReader.php
├── CDbException.php
├── CDbMigration.php
├── CDbTransaction.php
连接,执行,结果集操作,事物,异常,数据迁移。
1.数据库连接 CDbConnection.php
YII中的DAO是封装的PDO,那么连接数据库要提供的必要信息(连接方式,用户名,密码)自然也类似。打开类看看具体实现方式和使用方法。
通过类的注释可以了解连接方法。
* CDbConnection represents a connection to a database. * * CDbConnection works together with {@link CDbCommand}, {@link CDbDataReader} * and {@link CDbTransaction} to provide data access to various DBMS * in a common set of APIs. They are a thin wrapper of the {@link http://www.php.net/manual/en/ref.pdo.php PDO} * PHP extension. * * To establish a connection, set {@link setActive active} to true after * specifying {@link connectionString}, {@link username} and {@link password}. * * The following example shows how to create a CDbConnection instance and establish * the actual connection: * <pre> * $connection=new CDbConnection($dsn,$username,$password); * $connection->active=true; * </pre>
参数:
$dsn:
/** * @var string The Data Source Name, or DSN, contains the information required to connect to the database. * @see http://www.php.net/manual/en/function.PDO-construct.php * * Note that if you"re using GBK or BIG5 then it"s highly recommended to * update to PHP 5.3.6+ and to specify charset via DSN like * "mysql:dbname=mydatabase;host=127.0.0.1;charset=GBK;". */ public $connectionString;$dsn的具体规则可以参看
http://www.php.net/manual/en/function.PDO-construct.php。
http://cn2.php.net/manual/en/pdo.drivers.php
格式如下:
uri:file:///path/to/dsnfile
YII官方给出的常见的DSN格式如下:
-
SQLite:
sqlite:/path/to/dbfile
-
MySQL:
mysql:host=localhost;dbname=testdb
-
PostgreSQL:
pgsql:host=localhost;port=5432;dbname=testdb
-
SQL Server:
mssql:host=localhost;dbname=testdb
-
Oracle:
oci:dbname=//localhost:1521/testdb
$username
$password
具体举例如下:
/yii_dev/testwebap/protected/models/Member.php
<?php class Member extends CModel { private $connection = null; public function __construct () { //YII的强大,让你可以直接用下面的语句连接,更简单 $this->connection = Yii::app()->db; //or,下面也可以,就是蛮笨的,当然也是基本的 /* $dsn = Yii::app()->db->connectionString; $username = Yii::app()->db->username; $password = Yii::app()->db->password; $this->connection = new CDbConnection($dsn, $username, $password); $this->connection->charset = "utf8"; $this->connection->active = true; */ } /** * Returns the static model of the specified AR class. * @return User the static model class */ public static function model ($className = __CLASS__) { return parent::model($className); } /** * * 连接状态 */ public function stats () { return $this->connection ? "connection successful!" : "connection fail!"; } public function attributeNames () {} }
$this->connection->active = true;表示打开连接。
/yii_dev/testwebap/protected/modules/testmod/controllers/DefaultController.php
<?php class DefaultController extends Controller { public function actionDao () { $memberModel = new Member(); var_dump($memberModel->stats()); }
具体的实现方式,可以自行参考类,这里不再累述。
2.数据库基本操作CDbCommand.php
数据库连接建立后,便可以通过CDbCommand类提供的方法就可以进行数据库操作。
类给出的使用方法:
* After the DB connection is established, one can execute an SQL statement like the following: * <pre> * $command=$connection->createCommand($sqlStatement); * $command->execute(); // a non-query SQL statement execution * // or execute an SQL query and fetch the result set * $reader=$command->query(); * * // each $row is an array representing a row of data * foreach($reader as $row) ... * </pre> * * One can do prepared SQL execution and bind parameters to the prepared SQL: * <pre> * $command=$connection->createCommand($sqlStatement); * $command->bindParam($name1,$value1); * $command->bindParam($name2,$value2); * $command->execute(); * </pre>
基本使用方法如下
<?php class Member extends CModel { private $connection = null; private $command = null; public function __construct () { $this->connection = Yii::app()->db; } /** * Returns the static model of the specified AR class. * @return User the static model class */ public static function model ($className = __CLASS__) { return parent::model($className); } /** * * 连接状态 */ public function stats () { return $this->connection ? "connection successful!" : "connection fail!"; } /** * * 获取所有用户名 */ public function getUsernames () { $sqlStatement = " SELECT `username` FROM `testdrive`.`tbl_user` "; $this->command = $this->connection->createCommand($sqlStatement); return $this->command->queryAll(); } /** * * 获取指定用户的昵称 * @param string $userName */ public function getNickname ($userName) { $sqlStatement = " SELECT `username` FROM `testdrive`.`tbl_user` WHERE `username`=:username "; $this->command = $this->connection->createCommand($sqlStatement); $this->command->bindParam("username", $userName); return $this->command->queryAll(); } /** * * 添加一个用户 */ public function addUser () { $sqlStatement = " INSERT INTO `tbl_user` (`username`, `password`, `email`) VALUES ("test", "test", "test@test.com") "; $this->command = $this->connection->createCommand($sqlStatement); return $this->command->execute(); } public function attributeNames () {} }
<?php class DefaultController extends Controller { public function actionUsernames () { $memberModel = new Member(); var_dump($memberModel->getUsernames()); } public function actionNickname () { $memberModel = new Member(); var_dump($memberModel->getNickname("admin")); } public function actionAdduser () { $memberModel = new Member(); var_dump($memberModel->addUser()); }
总结:
*****常用函数
(1)如果你执行的SQL语句有返回结果集: 例如SELECT。通常用query开头的系列函数:
常见的有:
$dataReader=$command->query(); // 执行一个 SQL 查询 $rows=$command->queryAll(); // 查询并返回结果中的所有行 $row=$command->queryRow(); // 查询并返回结果中的第一行 $column=$command->queryColumn(); // 查询并返回结果中的第一列 $value=$command->queryScalar(); // 查询并返回结果中第一行的第一个字段query()方法执行如果成功,它将返回一个CDbDataReader 实例,通过此实例可以遍历数据的结果行。
为简便起见, (Yii)还实现了一系列queryXXX()
方法以直接返回查询结果。
(2)你执行的SQL语句返回的不是结果集,只是状态值,例如:INSERT ,UPDATE,DELETE.则用execute()
例如
$this->command->execute();
*****结果集操作类CDbDataReader的使用方法有两种方法,参见如下代码
/** * * 获取所有用户名 */ public function getUsernames () { $sqlStatement = " SELECT `username` FROM `testdrive`.`tbl_user` "; $this->command = $this->connection->createCommand($sqlStatement); $dataReader = $this->command->query(); // 重复调用 read() 直到它返回 false while (($row = $dataReader->read()) !== false) { var_dump($row); } foreach ($dataReader as $row) { var_dump($row); } }
CDbDataReader还提供了其他的方法。例如获取行数,将所有数据转存储到一个数组等等,具体的可参考类的代码。
*****表前缀
从版本 1.1.0 起, Yii 提供了集成了对使用表前缀的支持。 表前缀是指在当前连接的数据库中的数据表的名字前面添加的一个字符串。 它常用于共享的服务器环境,这种环境中多个应用可能会共享同一个数据库,要使用不同的表前缀以相互区分。 例如,一个应用可以使用 tbl_
作为表前缀而另一个可以使用 yii_
。
要使用表前缀,配置 CDbConnection::tablePrefix 属性为所希望的表前缀。
然后,在 SQL 语句中使用{{TableName}}
代表表的名字,其中的 TableName
是指不带前缀的表名。
例如,如果数据库含有一个名为tbl_user
的表,而 tbl_
被配置为表前缀,那我们就可以使用如下代码执行用户相关的查询:
$sql="SELECT * FROM {{user}}"; $users=$connection->createCommand($sql)->queryAll();