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

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

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

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

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

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

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

配置

開始使用數(shù)據(jù)庫首先需要配置數(shù)據(jù)庫連接組件,通過添加 db 組件到應(yīng)用配置實(shí)現(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',
        ],
    ],
    // ...
];

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

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

請(qǐng)參考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í)使用多個(gè)數(shù)據(jù)庫可以定義 多個(gè) 連接組件:

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ǔ)查詢

一旦有了連接實(shí)例就可以通過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();

查詢標(biāo)量值/計(jì)算值:

$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?方法,這些方法會(huì)根據(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ù)時(shí)間都使用以下語法來安全地引用表名和列名:

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

以上代碼$column?會(huì)轉(zhuǎn)變?yōu)橐们‘?dāng)?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)橐们‘?dāng)?shù)谋砻?表名有個(gè)特殊的變量 {{%Y}} ,如果設(shè)置了表前綴使用該變體可以自動(dòng)在表名前添加前綴:

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

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

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

手工引用表名和列名的另一個(gè)選擇是使用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)當(dāng)使用:placeholder占位,再將變量綁定到對(duì)應(yīng)占位符:

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

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

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

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

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

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

事務(wù)

當(dāng)你需要順序執(zhí)行多個(gè)相關(guān)的的query時(shí),你可以把他們封裝到一個(gè)事務(wù)中去保護(hù)數(shù)據(jù)一致性.Yii提供了一個(gè)簡單的接口來實(shí)現(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()開始一個(gè)事務(wù),通過try catch?捕獲異常.當(dāng)執(zhí)行成功,通過yii\db\Transaction::commit()提交事務(wù)并結(jié)束,當(dāng)發(fā)生異常失敗通過yii\db\Transaction::rollBack()進(jìn)行事務(wù)回滾.

如需要也可以嵌套多個(gè)事務(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è)置隔離級(jí)別isolation levels,當(dāng)執(zhí)行事務(wù)時(shí)會(huì)使用數(shù)據(jù)庫默認(rèn)的隔離級(jí)別,你也可以為事物指定隔離級(jí)別. Yii 提供了以下常量作為常用的隔離級(jí)別

  • \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 - 對(duì)相同字段的多次讀取結(jié)果一致,可導(dǎo)致幻讀。
  • \yii\db\Transaction::SERIALIZABLE - 完全服從ACID的原則,確保不發(fā)生臟讀、不可重復(fù)讀和幻讀。

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

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

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

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

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

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

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

通過配置yii\db\Connection可以實(shí)現(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'],
    ],
]

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

// 使用以上配置創(chuàng)建數(shù)據(jù)庫連接對(duì)象$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í)行的查詢被認(rèn)為是寫操作,所有使用yii\db\Command來執(zhí)行的其他查詢方法被認(rèn)為是讀操作.你可以通過$db->slave得到當(dāng)前正在使用能夠的從服務(wù)器.

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

>注意:在上述配置中,每個(gè)從服務(wù)器連接超時(shí)時(shí)間被指定為10s. 如果在10s內(nèi)不能連接,則被認(rèn)為該服務(wù)器已經(jīng)掛掉.你也可以自定義超時(shí)參數(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個(gè)主服務(wù)器和4個(gè)從服務(wù)器.Connection組件也支持主服務(wù)器的負(fù)載均衡和故障轉(zhuǎn)移,與從服務(wù)器不同的是,如果所有主服務(wù)器都不可用,則會(huì)拋出異常.

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

事務(wù)默認(rèn)使用主服務(wù)器的連接,并且在事務(wù)執(zhí)行中的所有操作都會(huì)使用主服務(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();

有時(shí)你想強(qiáng)制使用主服務(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實(shí)例來獲取Schema信息:

$schema = $connection->getSchema();

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

$tables = $schema->getTableNames();

更多信息請(qǐng)參考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',
]);
完整參考請(qǐng)查看yii\db\Command.
Previous article: Next article: