Yii Framework Official Guide Series 23 - Using Databases: Data Access Objects (DAO)

黄舟
Release: 2023-03-05 18:06:02
Original
1276 people have browsed it



Data Access Object (DAO) provides a common API for accessing data stored in different database management systems (DBMS). Therefore, when changing the underlying DBMS to another, there is no need to modify the code that uses DAO to access data. Yii DAO is built on PHP Data Objects (PDO). It is an extension that provides unified data access for many popular DBMS, including MySQL, PostgreSQL, etc. Therefore, to use Yii DAO, the PDO extension and specific PDO database driver (such as PDO_MYSQL) must be installed. Yii DAO mainly includes the following four categories:

  • CDbConnection: represents a database connection.

  • CDbCommand: Represents a SQL statement executed through the database.

  • CDbDataReader: Represents a forward-only stream of rows from a query result set.

  • CDbTransaction: Represents a database transaction.

Below, we introduce the application of Yii DAO in different scenarios.

1. Establish a database connection

To establish a database connection, create a CDbConnection instance and activate it. Connecting to a database requires a data source name (DSN) to specify connection information. Username and password may also be used. When an error occurs while connecting to the database (for example, wrong DSN or invalid username/password), an exception will be thrown.


$connection=new CDbConnection($dsn,$username,$password);
// 建立连接。你可以使用  try...catch 捕获可能抛出的异常
$connection->active=true;
......
$connection->active=false;  // 关闭连接
Copy after login

The format of the DSN depends on the PDO database driver used. In general, the DSN contains the name of the PDO driver, followed by a colon, followed by driver-specific connection syntax. Check out the PDO documentation for more information. Below is a list of commonly used DSN formats.

  • 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

Since CDbConnection inherits from CApplicationComponent, we can also use it as an application component. To do this, configure a

db (or other name) application component in Application Configuration as follows:


##
array(
    ......
    'components'=>array(
        ......
        'db'=>array(
            'class'=>'CDbConnection',
            'connectionString'=>'mysql:host=localhost;dbname=testdb',
            'username'=>'root',
            'password'=>'password',
            'emulatePrepare'=>true,  // needed by some MySQL installations
        ),
    ),
)
Copy after login

Then we can access the database connection through

Yii::app()->db

. It is automatically activated unless we specifically configure CDbConnection::autoConnect to false. This way, this single DB connection can be shared in many places in our code. 2. Execute SQL statements

After the database connection is established, SQL statements can be executed by using CDbCommand. You can create a CDbCommand instance by calling CDbConnection::createCommand() with the specified SQL statement as argument.


$connection=Yii::app()->db;   // 假设你已经建立了一个 "db" 连接
// 如果没有,你可能需要显式建立一个连接:
// $connection=new CDbConnection($dsn,$username,$password);
$command=$connection->createCommand($sql);
// 如果需要,此 SQL 语句可通过如下方式修改:
// $command->text=$newSQL;
Copy after login

A SQL statement will be executed through CDbCommand in the following two ways:

    execute(): Execute a non-query SQL statement, such as
  • INSERT

    , UPDATE and DELETE. If successful, it returns the number of rows affected by this execution.

  • query(): Execute a SQL statement that returns several rows of data, such as
  • SELECT

    . If successful, it returns a CDbDataReader instance through which the resulting rows of data can be iterated. For simplicity, (Yii) also implements a series of queryXXX() methods to directly return query results.

  • If an error occurs when executing a SQL statement, an exception will be thrown.


$rowCount=$command->execute();   // 执行无查询 SQL
$dataReader=$command->query();   // 执行一个 SQL 查询
$rows=$command->queryAll();      // 查询并返回结果中的所有行
$row=$command->queryRow();       // 查询并返回结果中的第一行
$column=$command->queryColumn(); // 查询并返回结果中的第一列
$value=$command->queryScalar();  // 查询并返回结果中第一行的第一个字段
Copy after login

3. Get query results

After CDbCommand::query() generates CDbDataReader instance , you can obtain rows in the result by repeatedly calling CDbDataReader::read(). You can also use CDbDataReader in PHP's

foreach

language structure to retrieve data line by line.


$dataReader=$command->query();
// 重复调用 read() 直到它返回 false
while(($row=$dataReader->read())!==false) { ... }
// 使用 foreach 遍历数据中的每一行
foreach($dataReader as $row) { ... }
// 一次性提取所有行到一个数组
$rows=$dataReader->readAll();
Copy after login

##Note:
is different from query(), all

The queryXXX() method will return data directly. For example, queryRow() returns an array representing the first row of the query results. 4. Use transactions

When an application needs to execute several queries, and each query needs to read information from the database and/or write information to the database, ensure that the database It is very important that there are no queries left and only a few others executed. Transactions, represented as CDbTransaction instances in Yii, may be started in the following situations:

Start transaction.
  • Execute queries one by one . Any updates to the database are not visible to the outside world.
  • 提交事务。如果事务成功,更新变为可见。

  • 如果查询中的一个失败,整个事务回滚。

上述工作流可以通过如下代码实现:


$transaction=$connection->beginTransaction();
try
{
    $connection->createCommand($sql1)->execute();
    $connection->createCommand($sql2)->execute();
    //.... other SQL executions
    $transaction->commit();
}
catch(Exception $e) // 如果有一条查询失败,则会抛出异常
{
    $transaction->rollBack();
}
Copy after login

5. 绑定参数

要避免 SQL 注入攻击 并提高重复执行的 SQL 语句的效率, 你可以 "准备(prepare)"一条含有可选参数占位符的 SQL 语句,在参数绑定时,这些占位符将被替换为实际的参数。 参数占位符可以是命名的 (表现为一个唯一的标记) 或未命名的 (表现为一个问号)。调用 CDbCommand::bindParam()或 CDbCommand::bindValue() 以使用实际参数替换这些占位符。 这些参数不需要使用引号引起来:底层的数据库驱动会为你搞定这个。 参数绑定必须在 SQL 语句执行之前完成。


// 一条带有两个占位符 ":username" 和 ":email"的 SQL
$sql="INSERT INTO tbl_user (username, email) VALUES(:username,:email)";
$command=$connection->createCommand($sql);
// 用实际的用户名替换占位符 ":username" 
$command->bindParam(":username",$username,PDO::PARAM_STR);
// 用实际的 Email 替换占位符 ":email" 
$command->bindParam(":email",$email,PDO::PARAM_STR);
$command->execute();
// 使用新的参数集插入另一行
$command->bindParam(":username",$username2,PDO::PARAM_STR);
$command->bindParam(":email",$email2,PDO::PARAM_STR);
$command->execute();
Copy after login

方法 bindParam() 和 bindValue() 非常相似。唯一的区别就是前者使用一个 PHP 变量绑定参数, 而后者使用一个值。对于那些内存中的大数据块参数,处于性能的考虑,应优先使用前者。 关于绑定参数的更多信息,请参考 相关的PHP文档。

6. 绑定列

当获取查询结果时,你也可以使用 PHP 变量绑定列。 这样在每次获取查询结果中的一行时就会自动使用最新的值填充。


$sql="SELECT username, email FROM tbl_user";
$dataReader=$connection->createCommand($sql)->query();
// 使用 $username 变量绑定第一列 (username) 
$dataReader->bindColumn(1,$username);
// 使用 $email 变量绑定第二列 (email) 
$dataReader->bindColumn(2,$email);
while($dataReader->read()!==false)
{
    // $username 和 $email 含有当前行中的 username 和 email 
}
Copy after login

7. 使用表前缀

从版本 1.1.0 起, Yii 提供了集成了对使用表前缀的支持。 表前缀是指在当前连接的数据库中的数据表的名字前面添加的一个字符串。 它常用于共享的服务器环境,这种环境中多个应用可能会共享同一个数据库,要使用不同的表前缀以相互区分。 例如,一个应用可以使用 tbl_ 作为表前缀而另一个可以使用 yii_。 要使用表前缀,配置 CDbConnection::tablePrefix 属性为所希望的表前缀。 然后,在 SQL 语句中使用{{TableName}} 代表表的名字,其中的 TableName 是指不带前缀的表名。 例如,如果数据库含有一个名为tbl_user 的表,而 tbl_ 被配置为表前缀,那我们就可以使用如下代码执行用户相关的查询:

$sql='SELECT * FROM {{user}}';
$users=$connection->createCommand($sql)->queryAll();
Copy after login


以上就是Yii框架官方指南系列23——使用数据库:数据访问对象(DAO)的内容,更多相关内容请关注PHP中文网(www.php.cn)!



source:php.cn
Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template