Yii2 - 数据库访问对象

本文介绍了如何在Yii框架中配置并使用数据库连接,包括执行基本的SQL查询、更新、插入和删除操作,以及如何处理表名和列名引用。此外还讲解了如何使用预备声明提高安全性,以及如何通过事务来保证数据的一致性和完整性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

配置好数据库连接后,你就可以通过下面的语法来使用了:

1
$connection= \Yii::$app->db;

你可以参考 [[yii\db\Connection]] 以了解有哪些属性可以配置。而且你可以配置多个连接,在应用程序中同时使用它们:

1
2
$primaryConnection= \Yii::$app->db;
$secondaryConnection= \Yii::$app->secondDb;

如果你不想把数据库连接定义为应用程序的组件,你也可以直接创建一个实例:

1
2
3
4
5
6
$connection=new \yii\db\Connection([
    'dsn'=>$dsn,
     'username'=>$username,
     'password'=>$password,
]);
$connection->open();

提示:如果你需要在建立连接时执行额外的SQL查询,你可以添加如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
return [
    // ...
    'components'=> [
        // ...
        'db'=> [
            'class'=>'yii\db\Connection',
            // ...
            'on afterOpen'=>function($event) {
                $event->sender->createCommand("SET time_zone = 'UTC'")->execute();
            }
        ],
    ],
    // ...
];

 

基本SQL查询

有了数据库连接实例,你可以使用 [[yii\db\Command]] 来执行SQL查询。

SELECT

返回多行数据:

1
2
$command = $connection->createCommand('SELECT * FROM post');
$posts = $command->queryAll();

返回单行数据:

1
2
$command = $connection->createCommand('SELECT * FROM post WHERE id=1');
$post = $command->queryOne();

返回列数据:

1
2
$command = $connection->createCommand('SELECT title FROM post');
$titles = $command->queryColumn();

返回统计数:

1
2
$command = $connection->createCommand('SELECT COUNT(*) FROM post');
$postCount=$command->queryScalar();

UPDATE, INSERT, DELETE etc.

对于非查询语句,你可以使用[[ yii\db\Command]]的 execute 方法:

1
2
$command = $connection->createCommand('UPDATE post SET status=1 WHERE id=1');
$command->execute();

也可以使用下面的语法,会自动处理好表名和列名引用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// INSERT
$connection->createCommand()->insert('user', [
    'name'=>'Sam',
    'age'=> 30,
])->execute();
 
// INSERT multiple rows at once
$connection->createCommand()->batchInsert('user', ['name','age'], [
    ['Tom', 30],
    ['Jane', 20],
    ['Linda', 25],
])->execute();
 
// UPDATE
$connection->createCommand()->update('user', ['status'=> 1], 'age > 30')->execute();
 
// DELETE
$connection->createCommand()->delete('user','status = 0')->execute();

 

引用表名和列名

大多数情况下,你使用如下语法引用表名和列名:

1
2
$sql = "SELECT COUNT([[$column]]) FROM {{$table}}";
$rowCount=$connection->createCommand($sql)->queryScalar();

在上述代码中 [[$column]] 将被转换为合适的列名引用,而 {{$table}} 将被转换为表名引用。

对于表名,有一个特殊变量 {{%$table}} ,会自动为表名添加前缀(如果有的话):

1
2
$sql = "SELECT COUNT([[$column]]) FROM {{%$table}}";
$rowCount=$connection->createCommand($sql)->queryScalar();

上述代码将会应用于 tbl_table ,如果你在配置文件中配置了如下的表前缀的话:

1
2
3
4
5
6
7
8
9
10
return [
    // ...
    'components'=> [
        // ...
        'db'=> [
            // ...
            'tablePrefix'=>'tbl_',
        ],
    ],
];

另外一个可选方法是使用[[yii\db\Connection::quoteTableName()]]和 [[yii\db\Connection::quoteColumnName()]] 方法来手动引用:

1
2
3
4
$column = $connection->quoteColumnName($column);
$table = $connection->quoteTableName($table);
$sql = "SELECT COUNT($column) FROM $table";
$rowCount=$connection->createCommand($sql)->queryScalar();

 

在Model 或 Controller中获取表前缀

var_dump(Admin::getDb()->tablePrefix); exit();


预备声明(Prepared statements)

为了安全传递查询参数,你可以使用预备声明(prepared statements),(译注:先声明参数,对用户输入进行escape后,进行参数替换,主要为了防止SQL注入):

1
2
3
$command = $connection->createCommand('SELECT * FROM post WHERE id=:id');
$command->bindValue(':id',$_GET['id']);
$post = $command->query();

此外,使用预备声明还可以对查询命令进行复用,如下使用不同的参数查询只需要准备一次command:

1
2
3
4
5
6
7
8
$command = $connection->createCommand('DELETE FROM post WHERE id=:id');
$command->bindParam(':id',$id);
 
$id = 1;
$command->execute();
 
$id = 2;
$command->execute();

 

事务(Transaction)

你可以向下面这样执行一个数据库事务:

1
2
3
4
5
6
7
8
9
$transaction=$connection->beginTransaction();
try {
    $connection->createCommand($sql1)->execute();
     $connection->createCommand($sql2)->execute();
    // ... 执行查询语句  ...
    $transaction->commit();
} catch(Exception$e) {
    $transaction->rollBack();
}

还可以嵌套事务:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 外层事务
$transaction1=$connection->beginTransaction();
try {
    $connection->createCommand($sql1)->execute();
 
    // 内层事务
    $transaction2=$connection->beginTransaction();
    try{
        $connection->createCommand($sql2)->execute();
        $transaction2->commit();
    }catch(Exception $e) {
        $transaction2->rollBack();
    }
 
    $transaction1->commit();
} catch(Exception$e) {
    $transaction1->rollBack();
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值