Yii2 - 数据库访问对象

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

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();
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值