1. createCommand()
是什么?
(1) 定义
createCommand()
:- 生成一个
yii\db\Command
对象。 - 该对象用于执行 SQL 语句(如查询、插入、更新、删除等)。
- 生成一个
(2) 作用
-
封装 SQL 操作:
- 提供一种面向对象的方式执行原生 SQL 或构建动态 SQL。
-
支持多种数据库操作:
- 包括查询、插入、更新、删除、事务管理等。
2. 使用场景
(1) 执行原生 SQL
- 示例:
$command = \Yii::$app->db->createCommand('SELECT * FROM user WHERE status = :status'); $users = $command->bindValue(':status', 1)->queryAll();
- 场景:
- 需要执行复杂的 SQL 查询,而框架的查询构建器无法满足需求。
(2) 动态构建 SQL
- 示例:
$command = \Yii::$app->db->createCommand() ->insert('user', ['name' => 'John', 'status' => 1]); $command->execute();
- 场景:
- 动态生成插入或更新语句。
(3) 批量操作
- 示例:
$command = \Yii::$app->db->createCommand(); foreach ($data as $row) { $command->insert('user', $row)->execute(); }
- 场景:
- 批量插入或更新数据。
3. 底层原理
(1) 数据存储
- 数据库表:
- 数据存储在数据库中,SQL 命令通过
Command
对象与数据库交互。
- 数据存储在数据库中,SQL 命令通过
(2) 程序流
当调用 createCommand()
时,系统会执行以下步骤:
-
创建
Command
对象:- 初始化一个
yii\db\Command
对象。
- 初始化一个
-
绑定参数:
- 如果需要,可以使用
bindValue()
或bindParam()
方法绑定参数。
- 如果需要,可以使用
-
执行 SQL:
- 调用
execute()
或queryAll()
等方法执行 SQL。
- 调用
-
返回结果:
- 返回执行结果(如受影响的行数或查询结果集)。
(3) 数据流
-
写入数据:
- SQL 命令被发送到数据库,执行插入、更新或删除操作。
-
读取数据:
- 数据库返回查询结果,供调用者使用。
4. 示例代码及详细注释
以下是一个完整的示例,展示如何使用 createCommand()
执行原生 SQL 和动态构建 SQL,并附上详细注释。
<?php
namespace app\controllers;
use yii\web\Controller;
class UserController extends Controller
{
public function actionIndex()
{
// 创建 Command 对象并执行原生 SQL 查询
// 作用:执行 SELECT 查询并获取所有状态为 1 的用户。
// 原因:某些复杂查询可能需要直接编写 SQL。
// 知识点:Yii2 的 createCommand() 方法,用于生成 Command 对象。
$command = \Yii::$app->db->createCommand('SELECT * FROM user WHERE status = :status');
// 绑定参数
// 作用:将参数绑定到 SQL 查询中,防止 SQL 注入。
// 原因:使用占位符(:status)可以提高安全性。
// 知识点:Command 类的 bindValue() 方法,用于绑定参数。
$command->bindValue(':status', 1);
// 执行查询并获取结果
// 作用:从数据库中加载符合条件的记录。
// 原因:将查询结果返回给调用者。
// 知识点:Command 类的 queryAll() 方法,用于返回所有记录。
$users = $command->queryAll();
// 渲染视图并传递数据
// 作用:将查询结果传递给视图文件,用于展示。
// 原因:视图负责展示数据,控制器负责准备数据。
// 知识点:Yii2 的 render() 方法,用于渲染视图文件。
return $this->render('index', [
'users' => $users,
]);
}
public function actionCreate()
{
// 创建 Command 对象并动态构建插入语句
// 作用:向 user 表中插入一条新记录。
// 原因:动态构建 SQL 可以避免硬编码。
// 知识点:Yii2 的 createCommand() 方法,用于生成 Command 对象。
$command = \Yii::$app->db->createCommand()
->insert('user', [
'name' => 'John',
'status' => 1,
'created_at' => time(),
]);
// 执行插入操作
// 作用:将数据插入到数据库中。
// 原因:确保数据持久化。
// 知识点:Command 类的 execute() 方法,用于执行非查询语句。
$command->execute();
// 返回成功信息
// 作用:通知用户操作成功。
// 原因:便于用户了解操作结果。
// 知识点:PHP 的 return 语句,用于返回函数结果。
return 'User created successfully!';
}
}
5. 注意事项
(1) SQL 注入防护
- 使用参数绑定(如
bindValue()
或bindParam()
)防止 SQL 注入。
(2) 性能优化
- 如果批量操作较多,建议使用事务管理(
beginTransaction()
)。
(3) 错误处理
- 捕获异常并提供友好的错误提示。
6. 程序流和数据流
(1) 程序流
-
创建
Command
对象:- 初始化一个
yii\db\Command
对象。
- 初始化一个
-
绑定参数:
- 如果需要,可以使用
bindValue()
或bindParam()
方法绑定参数。
- 如果需要,可以使用
-
执行 SQL:
- 调用
execute()
或queryAll()
等方法执行 SQL。
- 调用
-
返回结果:
- 返回执行结果(如受影响的行数或查询结果集)。
(2) 数据流
-
写入数据:
- SQL 命令被发送到数据库,执行插入、更新或删除操作。
-
读取数据:
- 数据库返回查询结果,供调用者使用。
7. 总结
-
组成部分:
createCommand()
方法。yii\db\Command
对象。
-
使用场景:
- 执行原生 SQL。
- 动态构建 SQL。
- 批量操作。
-
底层原理:
- 数据存储在数据库中。
- 使用
Command
对象与数据库交互。
-
程序流和数据流:
- 写入数据:SQL 命令被发送到数据库。
- 读取数据:数据库返回查询结果,供调用者使用。