`
lyunabc
  • 浏览: 551471 次
  • 性别: Icon_minigender_2
社区版块
存档分类
最新评论

Yii Framework 开发教程(24) 数据库-DAO 示例

 
阅读更多

数据访问对象(DAO) 对访问存储在不同数据库管理系统(DBMS)中的数据提供了一个通用的API。 因此,在将底层 DBMS 更换为另一个时,无需修改使用了 DAO 访问数据的代码。

Yii DAO 基于PHP Data Objects (PDO)构建。它是一个为众多流行的DBMS提供统一数据访问的扩展,这些 DBMS 包括 MySQL, PostgreSQL 等等。因此,要使用 Yii DAO,PDO 扩展和特定的 PDO 数据库驱动(例如PDO_MYSQL) 必须安装。

Yii DAO 主要包含如下四个类:

  • CDbConnection: 代表一个数据库连接。
  • CDbCommand: 代表一条通过数据库执行的 SQL 语句。
  • CDbDataReader: 代表一个只向前移动的,来自一个查询结果集中的行的流。
  • CDbTransaction: 代表一个数据库事务。

下面,我们介绍 Yii DAO 在不同场景中的应用。

1. 建立数据库连接

要建立一个数据库连接,创建一个CDbConnection实例并将其激活。 连接到数据库需要一个数据源的名字(DSN)以指定连接信息。用户名和密码也可能会用到。 当连接到数据库的过程中发生错误时 (例如,错误的 DSN 或无效的用户名/密码),将会抛出一个异常。

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

DSN 的格式取决于所使用的 PDO 数据库驱动。总体来说, DSN 要含有 PDO 驱动的名字,跟上一个冒号,再跟上驱动特定的连接语法。可查阅PDO 文档获取更多信息。 下面是一个常用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

由于CDbConnection继承自CApplicationComponent,我们也可以将其作为一个应用组件使用。要这样做的话, 请在应用配置中配置一个db(或其他名字)应用组件如下:

本例使用MySQL chinook 数据库,修改protected/config/main.php

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

然后我们就可以通过Yii::app()->db访问数据库连接了。它已经被自动激活了,除非我们特意配置了CDbConnection::autoConnect为 false。通过这种方式,这个单独的DB连接就可以在我们代码中的很多地方共享。

2. 执行 SQL 语句

数据库连接建立后,SQL 语句就可以通过使用CDbCommand执行了。你可以通过使用指定的SQL语句作为参数调用CDbConnection::createCommand()创建一个CDbCommand实例。

为简单起见,我们使用Chinook数据库中的Employee表,修改DataModel

class DataModel
{
	public $employeeId;
	public $firstName;
	public $lastName;
	public $title;
	public $address;
	public $email;
}

注:创建DataModel这一步可以选。

修改SiteController的indexAction方法:

public function actionIndex()
	{

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

		$dataReader=$command->query();

		// each $row is an array representing a row of data
		foreach($dataReader as $row)
		{
			$employee = new DataModel();
			$employee->employeeId=$row['EmployeeId'];
			$employee->firstName=$row['FirstName'];
			$employee->lastName=$row['LastName'];
			$employee->title=$row['Title'];
			$employee->address=$row['Address'];
			$employee->email=$row['Email'];

			$model[]=$employee;
		}

		$this->render('index', array(
			'model' => $model,

			));
	}

一条 SQL 语句会通过CDbCommand以如下两种方式被执行:

  • execute(): 执行一个无查询 (non-query)SQL语句, 例如INSERT,UPDATEDELETE。如果成功,它将返回此执行所影响的行数。
  • query(): 执行一条会返回若干行数据的 SQL 语句,例如SELECT。 如果成功,它将返回一个CDbDataReader实例,通过此实例可以遍历数据的结果行。为简便起见, (Yii)还实现了一系列queryXXX()方法以直接返回查询结果。

执行 SQL 语句时如果发生错误,将会抛出一个异常。

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

3. 获取查询结果

CDbCommand::query()生成CDbDataReader实例之后,你可以通过重复调用CDbDataReader::read()获取结果中的行。你也可以在 PHP 的foreach语言结构中使用CDbDataReader一行行检索数据。

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

4. 显示查询结果

为简单起见,本例使用echo语句显示Employee的记录,后面可以使用GridView或是ListView来显示数据库的表格。

修改protected/views/site/index.php

<?php foreach($model as $employee)
{

	echo 'EmployeeId:' . $employee->employeeId . '<br />';
	echo 'First Name:' . $employee->firstName . '<br />';
	echo 'Last Name:' . $employee->lastName . '<br />';
	echo 'Title:' . $employee->title . '<br />';
	echo 'Address:' . $employee->address . '<br />';
	echo 'Email:' . $employee->email . '<br />';
	echo '---------------------- <br />';
}

 ?>

201212127002
本例下载
此外Dao 支持事务处理,绑定参数等。

5. 使用事务

当一个应用要执行几条查询,每条查询要从数据库中读取并/或向数据库中写入信息时, 保证数据库没有留下几条查询而只执行了另外几条查询是非常重要的。 事务,在 Yii 中表现为CDbTransaction实例,可能会在下面的情况中启动:

  • 开始事务.
  • 一个个执行查询。任何对数据库的更新对外界不可见。
  • 提交事务。如果事务成功,更新变为可见。
  • 如果查询中的一个失败,整个事务回滚。

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

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

6. 绑定参数

要避免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();

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

关于绑定参数的更多信息,请参考相关的PHP文档

7. 绑定列

当获取查询结果时,你也可以使用 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
}

8. 使用表前缀

从版本 1.1.0 起, Yii 提供了集成了对使用表前缀的支持。 表前缀是指在当前连接的数据库中的数据表的名字前面添加的一个字符串。 它常用于共享的服务器环境,这种环境中多个应用可能会共享同一个数据库,要使用不同的表前缀以相互区分。 例如,一个应用可以使用tbl_作为表前缀而另一个可以使用yii_

要使用表前缀,配置CDbConnection::tablePrefix属性为所希望的表前缀。 然后,在 SQL 语句中使用{{TableName}}代表表的名字,其中的TableName是指不带前缀的表名。 例如,如果数据库含有一个名为tbl_user的表,而tbl_被配置为表前缀,那我们就可以使用如下代码执行用户相关的查询:

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


分享到:
评论

相关推荐

    yii-advanced-app-2.0.36.tgz

    Yii 2 Advanced Application 是一个基于 Yii 2 框架的高级项目模板,适用于构建复杂的、多应用的 Web 应用程序。版本号 2.0.36 表示这是该框架的一个稳定版本,提供了许多改进和修复。这个 `.tgz` 文件是该模板的...

    yii-advanced-app-2.0.10.tgz

    这个版本是“yii-advanced-app-2.0.10.tgz”,它是一个压缩包,包含了 Yii 2 框架的高级应用模板,版本号为 2.0.10。这个版本可能包含了一些修复和改进,以提供更稳定和高效的开发环境。 Yii 2 是一个基于组件的高...

    yii1-ueditor-ext-1.1

    Yii1-UEditor-Ext-1.1 是一个专为Yii框架1.x版本设计的扩展插件,它将流行的富文本编辑器——百度UEditor整合到了Yii应用中。这个组件的目的是提供一个易于使用且功能丰富的文本编辑工具,使得开发者在处理用户内容...

    yii-advanced-app-2.0.4

    "yii-advanced-app-2.0.4" 是 Yii 2.0 框架的一个高级应用模板,适用于构建复杂的多层应用程序。这个版本是 2.0.4,意味着它包含了该框架在 2.0 主线版本中的第四次更新,通常会包含修复的错误、改进的性能以及可能...

    yii2-file-upload-master.zip

    Yii2.0是一个基于组件的高性能PHP框架,用于开发Web 2.0应用程序。这个"yii2-file-upload-master.zip"压缩包包含了一个针对Yii2.0框架的图片上传扩展,特别设计来支持异步加载缩略图功能。这种功能在现代网页应用中...

    yii-basic-app-2.0.5.tgz

    "yii-basic-app-2.0.5.tgz" 是一个压缩包,其中包含了Yii2框架的基础版(Basic App)的源代码,版本号为2.0.5。这个版本修复了一个重要的安全问题,具体涉及到`yii\web\ViewAction`类。 `yii\web\ViewAction`是Yii2...

    Yii Framework API手册

    1. **基础组件**: Yii的核心组件包括MVC(模型-视图-控制器)架构、数据库访问对象(DAO)、ActiveRecord模式、I18N(国际化)与L10N(本地化)、缓存机制、URL管理等。这些组件的API文档详细阐述了它们的功能、用法...

    yii-docs-2.0-zh-cn.tar.gz

    这个"yii-docs-2.0-zh-cn.tar.gz"压缩包包含了Yii 2.0框架的中文离线HTML版文档,使得开发者无需互联网连接也能查阅详尽的指导和API参考。同时,它还提供了英文版本的离线HTML文档以及"yii-guide-2.0-zh-cn"官方中文...

    yiren-p8Yii-ve2467575-x64.apk

    yiren-p8Yii-ve2467575-x64.apk

    yii扩展--ip地址识别--QQWRY

    YII扩展 IP地址识别组件 采用QQWRY数据库 使用条件: 解压到相应的目录。 确定QQWRY.DAT 放入 protacted/data 确定IpLocation 放入 protacted/components 修改main.php 'components'=&gt;array( //......

    Yii Framework 1.1.6

    Yii Framework 1.1.6 是一个高效、可扩展的 PHP 开发框架,它为开发者提供了构建大型Web应用所需的工具和功能。这个版本是Yii框架的稳定版本之一,发布于2011年,旨在提高开发效率并降低维护成本。 在Yii 1.1.6中,...

    YII Framework框架教程之使用YIIC快速创建YII应用详解

    主要介绍了YII Framework框架教程之使用YIIC快速创建YII应用的方法,详细分析说明了YII Framework框架使用YIIC命令行创建应用的相关技巧与注意事项,需要的朋友可以参考下

    yii-basic-app-2.0.0.tgz

    在"yii-basic-app-2.0.0.tgz"这个压缩包中,我们看到的是Yii 2.0框架的基础应用模板。这个模板是专门为初学者和快速原型设计准备的,包含了创建一个基本Web应用所需的所有基础结构。它提供了一个起点,开发者可以在...

    yii-advanced-app-2.0.11.tgz

    这个名为 "yii-advanced-app-2.0.11.tgz" 的压缩包包含了所有必要的文件和配置,使得开发者可以快速地搭建起基于Yii 2的多层架构项目。 Yii 2.0框架是Yii框架的最新迭代,它在性能、安全性和可扩展性方面都有显著...

    YII 2数据库迁移(Migrations) 使用教程

    ### YII 2数据库迁移(Migrations) 使用教程 #### 一、数据库迁移概念与作用 在软件开发过程中,随着项目的推进和技术需求的变化,数据库结构往往也需要进行调整或更新。为了更好地管理和跟踪这些变更,YII 2框架...

    yii快速入门教程--一个非常好的php框架

    ### Yii快速入门教程知识点 #### 一、基本概念 **1. 入口文件** - **功能**: 入口文件是整个Yii应用的第一个脚本,它负责加载Yii框架以及初始化应用。 - **内容**: 通常包含如下代码: ```php $yii = dirname...

    YII框架翻译整理最终稿 -

    4. **丰富的功能**:Yii 内置了多种实用功能,包括缓存机制、安全防护、数据库访问对象(DAO)、ActiveRecord 模式、I18N 和 L10N 支持等。 5. **清晰的文档**:Yii 提供详尽的文档,便于开发者快速学习和上手。 **...

    Yii Framework 2.0 权威指南 pdf格式 中文高清离线版 有书签

    ### Yii Framework 2.0 权威指南知识点详解 #### 一、Yii框架概述 - **定义**:Yii是一款高效能、基于组件的PHP框架,主要用于加速现代Web应用的开发进程。其名称“Yii”(发音类似于“易”)在中国文化中有“极致...

    YII Framework框架教程之缓存用法详解

    首先,Yii框架的缓存是通过组件方式定义的,位于/yii_dev/yii/framework/caching目录下。该目录包括了多种缓存组件实现,例如CApcCache、CCache、CDbCache等,它们分别对应不同的缓存存储媒介,如APC、文件、数据库...

Global site tag (gtag.js) - Google Analytics