亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

ディレクトリ 検索
閱讀前篇 簡介 Yii 是什么 從 Yii 1.1 升級 入門 安裝 Yii 運行應(yīng)用 第一次問候 使用Forms 數(shù)據(jù)庫應(yīng)用 使用 Gii 生成代碼 進階 應(yīng)用結(jié)構(gòu) 概述 入口腳本 應(yīng)用(Applications) 應(yīng)用組件(Application Components) 控制器(Controllers) 模型(Models) 視圖(views) 模塊(Modules) 過濾器(Filters) 小部件(Widgets) 前端資源(Assets) 擴展(Extensions) 請求處理 運行概述 啟動引導(dǎo)(Bootstrapping) 路由和創(chuàng)建URL 請求(Requests) 響應(yīng)(Responses) Sessions 和 Cookies 錯誤處理(Handling Errors) 日志(Logging) 關(guān)鍵概念 組件(Component) 屬性(Property) 事件(Events) 行為(Behaviors) 配置(Configurations) 別名(Aliases) 類自動加載(Autoloading) 服務(wù)定位器(Service Locator) 依賴注入容器(Dependency Injection Container) 配合數(shù)據(jù)庫工作 數(shù)據(jù)庫訪問 (Data Access Objects) 查詢生成器(Query Builder) 活動記錄(Active Record) 數(shù)據(jù)庫遷移(Migrations) Sphinx Redis MongoDB Elasticsearch 接收用戶數(shù)據(jù) 創(chuàng)建表單(Creating Forms) 輸入驗證(Validating Input) 文件上傳(Uploading Files) 收集列表輸入(Collecting Tabular Input) 多模型的復(fù)合表單(Getting Data for Multiple Models) 顯示數(shù)據(jù) 格式化輸出數(shù)據(jù)(Data Formatting) 分頁(Pagination) 排序(Sorting) 數(shù)據(jù)提供器(Data Providers) 數(shù)據(jù)小部件(Data Widgets) 客戶端腳本使用(Working with Client Scripts) 主題(Theming) 安全 認證(Authentication) 授權(quán)(Authorization) 處理密碼(Working with Passwords) 客戶端認證(Auth Clients) 最佳安全實踐(Best Practices) 緩存 概述 數(shù)據(jù)緩存 片段緩存 頁面緩存 HTTP 緩存 RESTfull Web服務(wù) 快速入門(Quick Start) 資源(Resources) 控制器(Controllers) 路由(Routing) 格式化響應(yīng)(Response Formatting) 授權(quán)認證(Authentication) 速率限制(Rate Limiting) 版本(Versioning) 錯誤處理(Error Handling) 開發(fā)工具 調(diào)試工具欄和調(diào)試器 使用Gii生成代碼 生成API文檔 測試 概述(Overview) 配置測試環(huán)境(Testing environment setup) 單元測試(Unit Tests) 功能測試(Function Tests) 驗收測試(Acceptance Tests) 測試夾具(Fixtures) 高級專題 高級應(yīng)用模板 創(chuàng)建自定義應(yīng)用程序結(jié)構(gòu) 控制臺命令 核心驗證器(Core Validators) 國際化 收發(fā)郵件 性能優(yōu)化 共享主機環(huán)境 模板引擎 集成第三方代碼 小部件 Bootstrap 小部件 Jquery UI 助手類 概述 Array 助手(ArrayHelper) Html 助手(Html) Url 助手(Url)
テキスト

數(shù)據(jù)庫訪問 (DAO)

數(shù)據(jù)庫訪問 (DAO)

Yii 包含了一個建立在 PHP PDO 之上的數(shù)據(jù)訪問層 (DAO). DAO為不同的數(shù)據(jù)庫提供了一套統(tǒng)一的API. 其中`ActiveRecord`?提供了數(shù)據(jù)庫與模型(MVC 中的 M,Model) 的交互,`QueryBuilder`?用于創(chuàng)建動態(tài)的查詢語句. DAO提供了簡單高效的SQL查詢,可以用在與數(shù)據(jù)庫交互的各個地方.

Yii 默認支持以下數(shù)據(jù)庫 (DBMS):

  • MySQL
  • MariaDB
  • SQLite
  • PostgreSQL
  • CUBRID: 版本 >= 9.3 . (由于PHP PDO 擴展的一個bug?引用值會無效,所以你需要在 CUBRID的客戶端和服務(wù)端都使用 9.3 )
  • Oracle
  • MSSQL: 版本>=2005.

配置

開始使用數(shù)據(jù)庫首先需要配置數(shù)據(jù)庫連接組件,通過添加 db 組件到應(yīng)用配置實現(xiàn)("基礎(chǔ)的" Web 應(yīng)用是 config/web.php),DSN( Data Source Name )是數(shù)據(jù)源名稱,用于指定數(shù)據(jù)庫信息.如下所示:

return [
    // ...
    'components' => [
        // ...
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=mydatabase', // MySQL, MariaDB
            //'dsn' => 'sqlite:/path/to/database/file', // SQLite
            //'dsn' => 'pgsql:host=localhost;port=5432;dbname=mydatabase', // PostgreSQL
            //'dsn' => 'cubrid:dbname=demodb;host=localhost;port=33000', // CUBRID
            //'dsn' => 'sqlsrv:Server=localhost;Database=mydatabase', // MS SQL Server, sqlsrv driver
            //'dsn' => 'dblib:host=localhost;dbname=mydatabase', // MS SQL Server, dblib driver
            //'dsn' => 'mssql:host=localhost;dbname=mydatabase', // MS SQL Server, mssql driver
            //'dsn' => 'oci:dbname=//localhost:1521/mydatabase', // Oracle
            'username' => 'root', //數(shù)據(jù)庫用戶名
            'password' => '', //數(shù)據(jù)庫密碼
            'charset' => 'utf8',
        ],
    ],
    // ...
];

請參考PHP manual獲取更多有關(guān) DSN 格式信息。 配置連接組件后可以使用以下語法訪問:

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

請參考yii\db\Connection獲取可配置的屬性列表。 如果你想通過ODBC連接數(shù)據(jù)庫,則需要配置yii\db\Connection::driverName 屬性,例如:

'db' => [
    'class' => 'yii\db\Connection',
    'driverName' => 'mysql',
    'dsn' => 'odbc:Driver={MySQL};Server=localhost;Database=test',
    'username' => 'root',
    'password' => '',
],

注意:如果需要同時使用多個數(shù)據(jù)庫可以定義 多個 連接組件:

return [
    // ...
    'components' => [
        // ...
        'db' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'mysql:host=localhost;dbname=mydatabase', 
            'username' => 'root',
            'password' => '',
            'charset' => 'utf8',
        ],
        'secondDb' => [
            'class' => 'yii\db\Connection',
            'dsn' => 'sqlite:/path/to/database/file', 
        ],
    ],
    // ...
];

在代碼中通過以下方式使用:

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

如果不想定義數(shù)據(jù)庫連接為全局應(yīng)用組件,可以在代碼中直接初始化使用:

$connection = new \yii\db\Connection([
    'dsn' => $dsn,
     'username' => $username,
     'password' => $password,
]);
$connection->open();

>小提示:如果在創(chuàng)建了連接后需要執(zhí)行額外的 SQL 查詢,可以添加以下代碼到應(yīng)用配置文件:

return [
    // ...
    'components' => [
        // ...
        'db' => [
            'class' => 'yii\db\Connection',
            // ...
            'on afterOpen' => function($event) {
                $event->sender->createCommand("SET time_zone = 'UTC'")->execute();
            }
        ],
    ],
    // ...
];

SQL 基礎(chǔ)查詢

一旦有了連接實例就可以通過yii\db\Command執(zhí)行 SQL 查詢。

SELECT 查詢

查詢返回多行:

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

返回單行:

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

查詢多行單值:

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

查詢標量值/計算值:

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

UPDATE, INSERT, DELETE 更新、插入和刪除等

如果執(zhí)行 SQL 不返回任何數(shù)據(jù)可使用命令中的 execute 方法:

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

你可以使用insert,update,delete?方法,這些方法會根據(jù)參數(shù)生成合適的SQL并執(zhí)行.

// INSERT$connection->createCommand()->insert('user', [
    'name' => 'Sam',
    'age' => 30,
])->execute();

// INSERT 一次插入多行$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();

引用的表名和列名

大多數(shù)時間都使用以下語法來安全地引用表名和列名:

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

以上代碼$column?會轉(zhuǎn)變?yōu)橐们‘數(shù)牧忻?code style="box-sizing: border-box; font-family: Menlo, Monaco, Consolas, 'Courier New', monospace; font-size: 12.6px; padding: 2px 4px; color: rgb(199, 37, 78); border-radius: 4px; background-color: rgb(249, 242, 244);">{{table}}?就轉(zhuǎn)變?yōu)橐们‘數(shù)谋砻?表名有個特殊的變量 {{%Y}} ,如果設(shè)置了表前綴使用該變體可以自動在表名前添加前綴:

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

如果在配置文件如下設(shè)置了表前綴,以上代碼將在 tbl_table 這個表查詢結(jié)果:

return [
    // ...
    'components' => [
        // ...
        'db' => [
            // ...
            'tablePrefix' => 'tbl_',
        ],
    ],
];

手工引用表名和列名的另一個選擇是使用yii\db\Connection::quoteTableName() 和 yii\db\Connection::quoteColumnName():

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

預(yù)處理語句

為安全傳遞查詢參數(shù)可以使用預(yù)處理語句,首先應(yīng)當使用:placeholder占位,再將變量綁定到對應(yīng)占位符:

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

另一種用法是準備一次預(yù)處理語句而執(zhí)行多次查詢:

$command = $connection->createCommand('DELETE FROM post WHERE id=:id');
$command->bindParam(':id', $id);

$id = 1;
$command->execute();

$id = 2;
$command->execute();

>提示,在執(zhí)行前綁定變量,然后在每個執(zhí)行中改變變量的值(一般用在循環(huán)中)比較高效.

事務(wù)

當你需要順序執(zhí)行多個相關(guān)的的query時,你可以把他們封裝到一個事務(wù)中去保護數(shù)據(jù)一致性.Yii提供了一個簡單的接口來實現(xiàn)事務(wù)操作. 如下執(zhí)行 SQL 事務(wù)查詢語句:

$transaction = $connection->beginTransaction();
try {
    $connection->createCommand($sql1)->execute();
     $connection->createCommand($sql2)->execute();
    // ... 執(zhí)行其他 SQL 語句 ...
    $transaction->commit();
} catch(Exception $e) {
    $transaction->rollBack();
}

我們通過yii\db\Connection::beginTransaction()開始一個事務(wù),通過try catch?捕獲異常.當執(zhí)行成功,通過yii\db\Transaction::commit()提交事務(wù)并結(jié)束,當發(fā)生異常失敗通過yii\db\Transaction::rollBack()進行事務(wù)回滾.

如需要也可以嵌套多個事務(wù):

// 外部事務(wù)$transaction1 = $connection->beginTransaction();
try {
    $connection->createCommand($sql1)->execute();

    // 內(nèi)部事務(wù)
    $transaction2 = $connection->beginTransaction();
    try {
        $connection->createCommand($sql2)->execute();
        $transaction2->commit();
    } catch (Exception $e) {
        $transaction2->rollBack();
    }

    $transaction1->commit();
} catch (Exception $e) {
    $transaction1->rollBack();
}

>注意你使用的數(shù)據(jù)庫必須支持Savepoints才能正確地執(zhí)行,以上代碼在所有關(guān)系數(shù)據(jù)中都可以執(zhí)行,但是只有支持Savepoints才能保證安全性。

Yii 也支持為事務(wù)設(shè)置隔離級別isolation levels,當執(zhí)行事務(wù)時會使用數(shù)據(jù)庫默認的隔離級別,你也可以為事物指定隔離級別. Yii 提供了以下常量作為常用的隔離級別

  • \yii\db\Transaction::READ_UNCOMMITTED - 允許讀取改變了的還未提交的數(shù)據(jù),可能導(dǎo)致臟讀、不可重復(fù)讀和幻讀
  • \yii\db\Transaction::READ_COMMITTED - 允許并發(fā)事務(wù)提交之后讀取,可以避免臟讀,可能導(dǎo)致重復(fù)讀和幻讀。
  • \yii\db\Transaction::REPEATABLE_READ - 對相同字段的多次讀取結(jié)果一致,可導(dǎo)致幻讀。
  • \yii\db\Transaction::SERIALIZABLE - 完全服從ACID的原則,確保不發(fā)生臟讀、不可重復(fù)讀和幻讀。

你可以使用以上常量或者使用一個string字符串命令,在對應(yīng)數(shù)據(jù)庫中執(zhí)行該命令用以設(shè)置隔離級別,比如對于postgres有效的命令為SERIALIZABLE READ ONLY DEFERRABLE.

>注意:某些數(shù)據(jù)庫只能針對連接來設(shè)置事務(wù)隔離級別,所以你必須要為連接明確制定隔離級別.目前受影響的數(shù)據(jù)庫:MSSQL SQLite

>注意:SQLite 只支持兩種事務(wù)隔離級別,所以你只能設(shè)置READ UNCOMMITTED?和?SERIALIZABLE.使用其他隔離級別會拋出異常.

>注意:PostgreSQL 不允許在事務(wù)開始前設(shè)置隔離級別,所以你不能在事務(wù)開始時指定隔離級別.你可以在事務(wù)開始之后調(diào)用yii\db\Transaction::setIsolationLevel() 來設(shè)置.

關(guān)于隔離級別[isolation levels]:?http://en.wikipedia.org/wiki/Isolation_(database_systems)#Isolation_levels

數(shù)據(jù)庫復(fù)制和讀寫分離

很多數(shù)據(jù)庫支持數(shù)據(jù)庫復(fù)制?database replication來提高可用性和響應(yīng)速度. 在數(shù)據(jù)庫復(fù)制中,數(shù)據(jù)總是從主服務(wù)器?到?從服務(wù)器. 所有的插入和更新等寫操作在主服務(wù)器執(zhí)行,而讀操作在從服務(wù)器執(zhí)行.

通過配置yii\db\Connection可以實現(xiàn)數(shù)據(jù)庫復(fù)制和讀寫分離.

[
    'class' => 'yii\db\Connection',

    // 配置主服務(wù)器
    'dsn' => 'dsn for master server',
    'username' => 'master',
    'password' => '',

    // 配置從服務(wù)器
    'slaveConfig' => [
        'username' => 'slave',
        'password' => '',
        'attributes' => [
            // use a smaller connection timeout
            PDO::ATTR_TIMEOUT => 10,
        ],
    ],

    // 配置從服務(wù)器組
    'slaves' => [
        ['dsn' => 'dsn for slave server 1'],
        ['dsn' => 'dsn for slave server 2'],
        ['dsn' => 'dsn for slave server 3'],
        ['dsn' => 'dsn for slave server 4'],
    ],
]

以上的配置實現(xiàn)了一主多從的結(jié)構(gòu),從服務(wù)器用以執(zhí)行讀查詢,主服務(wù)器執(zhí)行寫入查詢,讀寫分離的功能由后臺代碼自動完成.調(diào)用者無須關(guān)心.例如:

// 使用以上配置創(chuàng)建數(shù)據(jù)庫連接對象$db = Yii::createObject($config);

// 通過從服務(wù)器執(zhí)行查詢操作$rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();

// 通過主服務(wù)器執(zhí)行更新操作$db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();

>注意:通過yii\db\Command::execute() 執(zhí)行的查詢被認為是寫操作,所有使用yii\db\Command來執(zhí)行的其他查詢方法被認為是讀操作.你可以通過$db->slave得到當前正在使用能夠的從服務(wù)器.

Connection組件支持從服務(wù)器的負載均衡和故障轉(zhuǎn)移,當?shù)谝淮螆?zhí)行讀查詢時,會隨即選擇一個從服務(wù)器進行連接,如果連接失敗則又選擇另一個,如果所有從服務(wù)器都不可用,則會連接主服務(wù)器。你可以配置yii\db\Connection::serverStatusCache來記住那些不能連接的從服務(wù)器,使Yii 在一段時間[[yii\db\Connection::serverRetryInterval].內(nèi)不會重復(fù)嘗試連接那些根本不可用的從服務(wù)器.

>注意:在上述配置中,每個從服務(wù)器連接超時時間被指定為10s. 如果在10s內(nèi)不能連接,則被認為該服務(wù)器已經(jīng)掛掉.你也可以自定義超時參數(shù).

你也可以配置多主多從的結(jié)構(gòu),例如:

[
    'class' => 'yii\db\Connection',

    // 配置主服務(wù)器
    'masterConfig' => [
        'username' => 'master',
        'password' => '',
        'attributes' => [
            // use a smaller connection timeout
            PDO::ATTR_TIMEOUT => 10,
        ],
    ],

    // 配置主服務(wù)器組
    'masters' => [
        ['dsn' => 'dsn for master server 1'],
        ['dsn' => 'dsn for master server 2'],
    ],

    // 配置從服務(wù)器
    'slaveConfig' => [
        'username' => 'slave',
        'password' => '',
        'attributes' => [
            // use a smaller connection timeout
            PDO::ATTR_TIMEOUT => 10,
        ],
    ],

    // 配置從服務(wù)器組
    'slaves' => [
        ['dsn' => 'dsn for slave server 1'],
        ['dsn' => 'dsn for slave server 2'],
        ['dsn' => 'dsn for slave server 3'],
        ['dsn' => 'dsn for slave server 4'],
    ],
]

上述配置制定了2個主服務(wù)器和4個從服務(wù)器.Connection組件也支持主服務(wù)器的負載均衡和故障轉(zhuǎn)移,與從服務(wù)器不同的是,如果所有主服務(wù)器都不可用,則會拋出異常.

>注意:當你使用yii\db\Connection::masters來配置一個或多個主服務(wù)器時,Connection中關(guān)于數(shù)據(jù)庫連接的其他屬性(例如:dsn,username,?password)都會被忽略.

事務(wù)默認使用主服務(wù)器的連接,并且在事務(wù)執(zhí)行中的所有操作都會使用主服務(wù)器的連接,例如:

// 在主服務(wù)器連接上開始事務(wù)$transaction = $db->beginTransaction();

try {
    // 所有的查詢都在主服務(wù)器上執(zhí)行
    $rows = $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
    $db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();

    $transaction->commit();
} catch(\Exception $e) {
    $transaction->rollBack();
    throw $e;
}

如果你想在從服務(wù)器上執(zhí)行事務(wù)操作則必須要明確地指定,比如:

$transaction = $db->slave->beginTransaction();

有時你想強制使用主服務(wù)器來執(zhí)行讀查詢,你可以調(diào)用seMaster()方法.

$rows = $db->useMaster(function ($db) {
    return $db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
});

你也可以設(shè)置$db->enableSlaves?為false來使所有查詢都在主服務(wù)器上執(zhí)行.

操作數(shù)據(jù)庫模式

獲得模式信息

你可以通過 yii\db\Schema實例來獲取Schema信息:

$schema = $connection->getSchema();

該實例包括一系列方法來檢索數(shù)據(jù)庫多方面的信息:

$tables = $schema->getTableNames();

更多信息請參考yii\db\Schema

修改模式

除了基礎(chǔ)的 SQL 查詢,yii\db\Command還包括一系列方法來修改數(shù)據(jù)庫模式:

  • 創(chuàng)建/重命名/刪除/清空表
  • 增加/重命名/刪除/修改字段
  • 增加/刪除主鍵
  • 增加/刪除外鍵
  • 創(chuàng)建/刪除索引

使用示例:

// 創(chuàng)建表$connection->createCommand()->createTable('post', [
    'id' => 'pk',
    'title' => 'string',
    'text' => 'text',
]);
完整參考請查看yii\db\Command.
前の記事: 次の記事: