Yii框架数据库配置与SQL操作详解
掌握PHP Yii框架的数据库操作方法:从基础的db组件配置到多数据库切换,利用内置DAO层高效执行CRUD操作。深入理解预处理语句、事务回滚机制,以及如何配置读写分离以提升系统性能。
数据库访问核心概念
Yii提供了一个建立在PHP PDO之上的数据访问对象(DAO)层。它为不同的数据库系统提供了一套统一的API,开发者无需关心底层具体的SQL方言差异。
- Active Record (AR):实现了MVC模型中的Model,适合处理关系型数据的对象化交互。
- QueryBuilder:用于动态创建安全且符合语法的查询语句。
- DAO:提供最底层的SQL执行能力,支持高效的命令式操作。
Yii默认支持多种主流DBMS,包括MySQL、MariaDB、SQLite、PostgreSQL、Oracle和MS SQL Server(版本2005+)。
数据库连接配置
使用数据库前,必须首先在应用配置文件中定义db组件。以基础Web应用的config/web.php为例:
return [
'components' => [
'db' => [
'class' => '\\yii\\db\\Connection',
'dsn' => 'mysql:host=localhost;dbname=mydatabase', // MySQL / MariaDB
//'dsn' => 'pgsql:host=localhost;port=5432;dbname=mydatabase', // PostgreSQL
//'dsn' => 'sqlite:/path/to/database/file', // SQLite
'username' => 'root',
'password' => '',
'charset' => 'utf8',
],
],
];
配置完成后,可通过全局入口获取连接对象:$connection = \Yii::$app->db;。
第1步:连接多个数据库
若项目中需同时连接多个数据库,可在components中定义额外的组件实例:
'db' => ['class' => '\\yii\\db\\Connection', 'dsn' => 'mysql:host=localhost;dbname=db1', ...],
'secondDb' => ['class' => '\\yii\\db\\Connection', 'dsn' => 'sqlite:/path/to/db2.sqlite'],
使用时分别调用 \Yii::$app->db 和 \Yii::$app->secondDb 即可。
第2步:自定义连接属性与初始化回调
若需在使用ODBC等非标准DSN格式时,可指定driverName。此外,支持在连接建立后执行额外操作(如设置时区):
'on afterOpen' => function($event) {
$event->sender->createCommand("SET time_zone = '+08:00'")->execute();
}
基础SQL操作(CRUD)
直接使用Command类可以执行不带参数的原生SQL。对于非返回数据的操作(如更新、删除),使用execute();返回结果集的查询则使用query*系列方法。
插入、更新与删除记录
以下示例演示如何构建并执行标准的增删改语句:
// 插入单行
$connection->createCommand()->insert('user', ['name' => 'Sam', 'age' => 30])->execute();
// 批量插入
$connection->createCommand()->batchInsert('user', ['name', 'age'], [
['Tom', 30], ['Jane', 20]
])->execute();
// 更新
$connection->createCommand()->update('user', ['status' => 1], 'age > 30')->execute();
// 删除
$connection->createCommand()->delete('user', 'status = 0')->execute();
表名与列名的安全引用
为防止字段名或表名是数据库关键字导致语法错误,应使用占位符语法自动转义:
$sql = "SELECT COUNT() FROM {{%table}}";
// 若在配置中设置了 'tablePrefix' => 'tbl_',此处会自动拼接为 tbl_table
或者手动调用 $connection->quoteTableName() 进行转义。
参数绑定与安全查询
绝对禁止将用户输入拼接到SQL字符串中,请使用预处理语句防止SQL注入。
第1步:使用Named Placeholder
在SQL中使用冒号(:varname)标记位置,并在执行前绑定变量:
$command = $connection->createCommand('SELECT * FROM post WHERE id=:id');
$command->bindValue(':id', $_GET['id']);
$post = $command->queryOne();
第2步:预编译循环执行(高性能用法)
当需要多次执行同一结构的SQL时,使用bindParam可以避免重复解析:
$command = $connection->createCommand('DELETE FROM log WHERE user_id=:uid');
foreach ($uids as $id) {
$command->bindParam(':uid', $id, PDO::PARAM_INT);
$command->execute();
}
事务管理与隔离级别
事务确保多条操作的原子性:要么全部成功提交(Commit),要么发生异常时全部回滚(RollBack)。
第1步:基本事务封装
$transaction = $connection->beginTransaction();
try {
$connection->createCommand("UPDATE user SET balance=balance-100 WHERE id=1")->execute();
$connection->createCommand("UPDATE user SET balance=balance+100 WHERE id=2")->execute();
$transaction->commit();
} catch (Exception $e) {
$transaction->rollBack();
}
第2步:嵌套事务与隔离级别
部分数据库支持Savepoints实现嵌套事务。也可强制设置隔离级别(如SERIALIZABLE或READ COMMITTED)。注意PostgreSQL要求在事务开始后设置隔离级别,而SQLite仅支持特定级别。
高级架构配置
数据库读写分离(主从复制)
Yii的Connection组件可自动识别写操作(INSERT/UPDATE/DELETE等)走主库,读操作(SELECT)走从库。
[
'class' => '\\yii\\db\\Connection',
// 配置主服务器
'dsn' => 'dsn for master server',
'username' => 'master_user',
'password' => 'secret',
// 配置从服务器组
'slaves' => [
['dsn' => 'dsn for slave 1'],
['dsn' => 'dsn for slave 2'],
],
// 共享从库的额外配置
'slaveConfig' => ['username' => 'slave_readonly']
]
负载均衡策略:若配置的某个从库不可用,框架会自动故障转移到其他从库;若所有从库均失效,则回退到主库读取(只读)。如需强制写入或强制走主库读取,可使用$db->useMaster(...)闭包。
数据库模式管理(DDL)
除了DML操作,yii\db\Command同样支持修改数据结构(建表、加字段等):
// 创建新表
$connection->createCommand()->createTable('post', [
'id' => 'pk',
'title' => 'string(100) NOT NULL',
'content' => 'text',
]);
总结
Yii框架通过PDO抽象层极大地简化了数据库开发。正确配置连接组件、善用占位符绑定参数以确保安全性、合理运用事务控制数据一致性,以及在大规模系统中部署读写分离,都是构建稳定后端服务的必备技能。以上就是Yii框架数据库配置与SQL操作的详细内容,更多关于PHP Yii实战的资料请关注本站其它相关文章!
本站声明
本文内容仅供参考,不代表本站观点。转载或引用请注明出处。如发现内容问题,请通过联系我们页面反馈。













