diff --git a/docs/guide-ja/db-active-record.md b/docs/guide-ja/db-active-record.md
index c636e3495c..4319d0c5ae 100644
--- a/docs/guide-ja/db-active-record.md
+++ b/docs/guide-ja/db-active-record.md
@@ -299,7 +299,7 @@ foreach (Customer::find()->each(10) as $customer) {
}
// イーガーローディングをするバッチクエリ
foreach (Customer::find()->with('orders')->each() as $customer) {
- // $customer は Customer オブジェクト
+ // $customer は 'orders' リレーションを投入された Customer オブジェクト
}
```
@@ -517,7 +517,8 @@ Customer::deleteAll(['status' => Customer::STATUS_INACTIVE]);
3. [[yii\db\ActiveRecord::afterDelete()|afterDelete()]]: [[yii\db\ActiveRecord::EVENT_AFTER_DELETE|EVENT_AFTER_DELETE]] イベントをトリガ。
-> Note|注意: 次のメソッドは、どれを呼んでも、上記のライフサイクルを開始させません。
+> Note|注意: 次のメソッドを呼んだ場合は、いずれの場合も、上記のライフサイクルのどれかを開始させることはありません。
+> これらのメソッドは、レコード単位ではなく、データベース上で直接に動作するためです。
>
> - [[yii\db\ActiveRecord::updateAll()]]
> - [[yii\db\ActiveRecord::deleteAll()]]
@@ -581,6 +582,9 @@ class Post extends \yii\db\ActiveRecord
複数の操作を示すためには、`|` を使って上記の定数を連結してください。
ショートカット定数 [[yii\db\ActiveRecord::OP_ALL|OP_ALL]] を使って、上記の三つの操作すべてを示すことも出来ます。
+このメソッドを使って生成されたトランザクションは、[[yii\db\ActiveRecord::beforeSave()|beforeSave()]] を呼ぶ前に開始され、
+[[yii\db\ActiveRecord::afterSave()|afterSave()]] を実行した後にコミットされます。
+
## 楽観的ロック
@@ -651,6 +655,8 @@ public function actionUpdate($id)
```php
class Customer extends ActiveRecord
{
+ // ...
+
public function getOrders()
{
return $this->hasMany(Order::className(), ['customer_id' => 'id']);
@@ -659,6 +665,8 @@ class Customer extends ActiveRecord
class Order extends ActiveRecord
{
+ // ...
+
public function getCustomer()
{
return $this->hasOne(Customer::className(), ['id' => 'customer_id']);
@@ -728,7 +736,7 @@ SQL 文の再実行を強制するためには、まず、リレーションプ
```php
$customer = Customer::findOne(123);
-// SELECT * FROM `order` WHERE `subtotal` > 200 ORDER BY `id`
+// SELECT * FROM `order` WHERE `customer_id` = 123 AND `subtotal` > 200 ORDER BY `id`
$orders = $customer->getOrders()
->where(['>', 'subtotal', 200])
->orderBy('id')
@@ -755,10 +763,10 @@ class Customer extends ActiveRecord
これによって、次のようなリレーショナルクエリを実行することが出来るようになります。
```php
-// SELECT * FROM `order` WHERE `subtotal` > 200 ORDER BY `id`
+// SELECT * FROM `order` WHERE `customer_id` = 123 AND `subtotal` > 200 ORDER BY `id`
$orders = $customer->getBigOrders(200)->all();
-// SELECT * FROM `order` WHERE `subtotal` > 100 ORDER BY `id`
+// SELECT * FROM `order` WHERE `customer_id` = 123 AND `subtotal` > 100 ORDER BY `id`
$orders = $customer->bigOrders;
```
diff --git a/docs/guide-ja/db-dao.md b/docs/guide-ja/db-dao.md
index a5f68c70b4..a087073d69 100644
--- a/docs/guide-ja/db-dao.md
+++ b/docs/guide-ja/db-dao.md
@@ -87,24 +87,26 @@ ODBC 経由でデータベースに接続しようとする場合は、[[yii\db\
> Info|情報: DB 接続のインスタンスを作成するとき、実際のデータベース接続は、最初の SQL を実行するか、[[yii\db\Connection::open()|open()]] メソッドを明示的に呼ぶかするまでは確立されません。
-> Tip|ヒント: 時として、何らかの環境変数を初期化するために、データベース接続を確立した直後に何かクエリを実行したい場合があります。
-> そのためには、データベース接続の [[yii\db\Connection::EVENT_AFTER_OPEN|afterOpen]] イベントに対するイベントハンドラを登録することが出来ます。
+> Tip|ヒント: 時として、何らかの環境変数を初期化するために、データベース接続を確立した直後に何かクエリを実行したい場合があるでしょう (例えば、タイムゾーンや文字セットを設定するなどです)。
+> そうするために、データベース接続の [[yii\db\Connection::EVENT_AFTER_OPEN|afterOpen]] イベントに対するイベントハンドラを登録することが出来ます。
> 以下のように、アプリケーションの構成情報に直接にハンドラを登録してください。
>
> ```php
> 'db' => [
> // ...
> 'on afterOpen' => function($event) {
-> $event->sender->createCommand("YOUR SQL HERE")->execute();
+> // $event->sender は DB 接続を指す
+> $event->sender->createCommand("SET time_zone = 'UTC'")->execute();
> }
> ]
> ```
+
## SQL クエリを実行する
いったんデータベース接続のインスタンスを得てしまえば、次の手順に従って SQL クエリを実行することが出来ます。
-1. 素の SQL で [[yii\db\Command]] を作成する。
+1. 素の SQL クエリで [[yii\db\Command]] を作成する。
2. パラメータをバインドする (オプション)。
3. [[yii\db\Command]] の SQL 実行メソッドの一つを呼ぶ。
@@ -112,49 +114,28 @@ ODBC 経由でデータベースに接続しようとする場合は、[[yii\db\
```php
// 行のセットを返す。各行は、カラム名と値の連想配列。
-// 結果が無い場合は空の配列が返される。
+// クエリが結果を返さなかった場合は空の配列が返される。
$posts = Yii::$app->db->createCommand('SELECT * FROM post')
->queryAll();
// 一つの行 (最初の行) を返す。
-// 結果が無い場合は false が返される。
+// クエリの結果が無かった場合は false が返される。
$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=1')
->queryOne();
// 一つのカラム (最初のカラム) を返す。
-// 結果が無い場合は空の配列が返される。
+// クエリが結果を返さなかった場合は空の配列が返される。
$titles = Yii::$app->db->createCommand('SELECT title FROM post')
->queryColumn();
// スカラ値を返す。
-// 結果が無い場合は false が返される。
+// クエリの結果が無かった場合は false が返される。
$count = Yii::$app->db->createCommand('SELECT COUNT(*) FROM post')
->queryScalar();
```
> Note|注意: 精度を保つために、対応するデータベースカラムの型が数値である場合でも、データベースから取得されたデータは、全て文字列として表現されます。
-> Tip|ヒント: 接続を確立した直後に SQL を実行する必要がある場合 (例えば、タイムゾーンや文字セットを設定したい場合) は、[[yii\db\Connection::EVENT_AFTER_OPEN]] ハンドラの中でそれをすることが出来ます。
-> 例えば、
->
-```php
-return [
- // ...
- 'components' => [
- // ...
- 'db' => [
- 'class' => 'yii\db\Connection',
- // ...
- 'on afterOpen' => function($event) {
- // $event->sender は DB 接続を指す
- $event->sender->createCommand("SET time_zone = 'UTC'")->execute();
- }
- ],
- ],
- // ...
-];
-```
-
### パラメータをバインドする
@@ -198,6 +179,7 @@ $command = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id');
$post1 = $command->bindValue(':id', 1)->queryOne();
$post2 = $command->bindValue(':id', 2)->queryOne();
+// ...
```
[[yii\db\Command::bindParam()|bindParam()]] はパラメータを参照渡しでバインドすることをサポートしていますので、上記のコードは次のように書くことも出来ます。
@@ -260,6 +242,10 @@ Yii::$app->db->createCommand()->batchInsert('user', ['name', 'age'], [
])->execute();
```
+上述のメソッド群はクエリを生成するだけであり、実際にそれを実行するためには、常に [[yii\db\Command::execute()|execute()]]
+を呼び出す必要があることに注意してください。
+
+
## テーブルとカラムの名前を引用符で囲む
特定のデータベースに依存しないコードを書くときには、テーブルとカラムの名前を適切に引用符で囲むことが、たいてい、頭痛の種になります。
@@ -269,7 +255,7 @@ Yii::$app->db->createCommand()->batchInsert('user', ['name', 'age'], [
* `[[カラム名]]`: 引用符で囲まれるカラム名を二重角括弧で包む。
* `{{テーブル名}}`: 引用符で囲まれるテーブル名を二重波括弧で包む。
-Yii DAO は、SQL に含まれるこのような構文を、対応する適切な引用符で囲まれたカラム名とテーブル名に自動的に変換します。
+Yii DAO は、このような構文を、DBMS 固有の文法に従って、適切な引用符で囲まれたカラム名とテーブル名に自動的に変換します。
例えば、
```php
@@ -280,7 +266,7 @@ $count = Yii::$app->db->createCommand("SELECT COUNT([[id]]) FROM {{employee}}")
### テーブル接頭辞を使う
-あなたの DB テーブルのほとんどが何か共通の接頭辞を持っている場合は、Yii DAO によってサポートされているテーブル接頭辞の機能を使うことが出来ます。
+あなたの DB テーブル名のほとんどが何か共通の接頭辞を持っている場合は、Yii DAO によってサポートされているテーブル接頭辞の機能を使うことが出来ます。
最初に、[[yii\db\Connection::tablePrefix]] プロパティによって、テーブル接頭辞を指定します。
@@ -322,14 +308,15 @@ Yii::$app->db->transaction(function($db) {
});
```
-上記のコードは、次のものと等価です。
+上記のコードは、次のものと等価です。こちらの方が、エラー処理のコードをより細かく制御することが出来ます。
```php
-$transaction = Yii::$app->db->beginTransaction();
+$db = Yii::$app->db;
+$transaction = $db->beginTransaction();
try {
- Yii::$app->db->createCommand($sql1)->execute();
- Yii::$app->db->createCommand($sql2)->execute();
+ $db->createCommand($sql1)->execute();
+ $db->createCommand($sql2)->execute();
// ... その他の SQL 文を実行 ...
$transaction->commit();
@@ -342,12 +329,13 @@ try {
}
```
-[[yii\db\Connection::beginTransaction()|beginTransaction()]] メソッドを呼んで、新しいトランザクションを開始します。
-トランザクションは、変数 `$transaction` に保存された [[yii\db\Transaction]] オブジェクトとして表現されています。
-そして、実行されるクエリを `try...catch...` ブロックで囲みます。
-全てのクエリの実行が成功した場合には [[yii\db\Transaction::commit()|commit()]] を呼んでトランザクションをコミットします。
-そうでなければ、例外がトリガされてキャッチされ、[[yii\db\Transaction::rollBack()|rollBack()]] が呼ばれて、失敗したクエリに先行するクエリがトランザクションの中で行った変更がロールバックされます。
-
+[[yii\db\Connection::beginTransaction()|beginTransaction()]] メソッドを呼ぶことによって、新しいトランザクションが開始されます。
+トランザクションは、変数 `$transaction` に保存された [[yii\db\Transaction]] オブジェクトとして表現されます。
+そして、実行されるクエリが `try...catch...` ブロックで囲まれます。
+全てのクエリの実行が成功した場合には、トランザクションをコミットするために [[yii\db\Transaction::commit()|commit()]] が呼ばれます。
+そうでなく、例外がトリガされてキャッチされた場合は、[[yii\db\Transaction::rollBack()|rollBack()]]
+が呼ばれて、トランザクションの中で失敗したクエリに先行するクエリによって行なわれた変更が、ロールバックされます。
+そして、`throw $e` が、まるでそれをキャッチしなかったかのように、例外を再スローしますので、通常のエラー処理プロセスがその例外の面倒を見ることになります。
### 分離レベルを指定する
@@ -380,7 +368,7 @@ Yii は、最もよく使われる分離レベルのために、四つの定数
DBMS によっては、接続全体に対してのみ分離レベルの設定を許容しているものがあることに注意してください。
その場合、すべての後続のトランザクションは、指定しなくても、それと同じ分離レベルで実行されます。
従って、この機能を使用するときは、矛盾する設定を避けるために、全てのトランザクションについて分離レベルを明示的に指定しなければなりません。
-このチュートリアルを書いている時点では、これに該当する DBMS は MSSQL と SQLite だけです。
+このチュートリアルを書いている時点では、この制約の影響を受ける DBMS は MSSQL と SQLite だけです。
> Note|注意: SQLite は、二つの分離レベルしかサポートしていません。すなわち、`READ UNCOMMITTED` と `SERIALIZABLE` しか使えません。
他のレベルを使おうとすると、例外が投げられます。
@@ -408,21 +396,24 @@ Yii::$app->db->transaction(function ($db) {
あるいは、
```php
-$outerTransaction = Yii::$app->db->beginTransaction();
+$db = Yii::$app->db;
+$outerTransaction = $db->beginTransaction();
try {
- Yii::$app->db->createCommand($sql1)->execute();
+ $db->createCommand($sql1)->execute();
- $innerTransaction = Yii::$app->db->beginTransaction();
+ $innerTransaction = $db->beginTransaction();
try {
- Yii::$app->db->createCommand($sql2)->execute();
+ $db->createCommand($sql2)->execute();
$innerTransaction->commit();
} catch (\Exception $e) {
$innerTransaction->rollBack();
+ throw $e;
}
$outerTransaction->commit();
} catch (\Exception $e) {
$outerTransaction->rollBack();
+ throw $e;
}
```
@@ -545,13 +536,14 @@ Yii::$app->db->createCommand("UPDATE user SET username='demo' WHERE id=1")->exec
例えば、
```php
+$db = Yii::$app->db;
// トランザクションはマスタ接続で開始される
-$transaction = Yii::$app->db->beginTransaction();
+$transaction = $db->beginTransaction();
try {
// クエリは両方ともマスタに対して実行される
- $rows = Yii::$app->db->createCommand('SELECT * FROM user LIMIT 10')->queryAll();
- Yii::$app->db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute();
+ $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) {
@@ -609,7 +601,12 @@ Yii::$app->db->createCommand()->createTable('post', [
]);
```
-テーブルに関する定義情報を DB 接続の [[yii\db\Connection::getTableSchema()|getTableSchema()]] メソッドによって取得することも出来ます。
+上記の配列は、生成されるカラムの名前と型を記述しています。
+Yii はカラムの型のために一連の抽象データ型を提供しているため、データベースの違いを意識せずにスキーマを定義することが可能です。
+これらの抽象データ型は、テーブルが作成されるデータベースに依存する DBMS 固有の型定義に変換されます。
+詳しい情報は [[yii\db\Command::createTable()|createTable()]] メソッドの API ドキュメントを参照してください。
+
+データベースのスキーマを変更するだけでなく、テーブルに関する定義情報を DB 接続の [[yii\db\Connection::getTableSchema()|getTableSchema()]] メソッドによって取得することも出来ます。
例えば、
```php
diff --git a/docs/guide-ja/db-query-builder.md b/docs/guide-ja/db-query-builder.md
index af2b3736d3..3ce3f5f172 100644
--- a/docs/guide-ja/db-query-builder.md
+++ b/docs/guide-ja/db-query-builder.md
@@ -1,7 +1,7 @@
クエリビルダ
============
-[データベースアクセスオブジェクト](db-dao.md) の上に構築されているクエリビルダは、SQL 文をプログラム的に、かつ、DBMS の違いを意識せずに作成することを可能にしてくれます。
+[データベースアクセスオブジェクト](db-dao.md) の上に構築されているクエリビルダは、SQL クエリをプログラム的に、かつ、DBMS の違いを意識せずに作成することを可能にしてくれます。
クエリビルダを使うと、生の SQL 文を書くことに比べて、より読みやすい SQL 関連のコードを書き、より安全な SQL 文を生成することが容易になります。
通常、クエリビルダの使用は、二つのステップから成ります。
@@ -20,7 +20,7 @@ $rows = (new \yii\db\Query())
->all();
```
-上記のコードは、次の SQL 文を生成して実行します。
+上記のコードは、次の SQL クエリを生成して実行します。
ここでは、`:last_name` パラメータは `'Smith'` という文字列にバインドされています。
```sql
@@ -36,9 +36,9 @@ LIMIT 10
## クエリを構築する
-[[yii\db\Query]] オブジェクトを構築するために、さまざまなクエリ構築メソッドを呼んで、SQL 文のさまざまな部分を定義します。
+[[yii\db\Query]] オブジェクトを構築するために、さまざまなクエリ構築メソッドを呼んで、SQL クエリのさまざまな部分を定義します。
これらのメソッドの名前は、SQL 文の対応する部分に使われる SQL キーワードに似たものになっています。
-例えば、SQL 文の `FROM` の部分を定義するためには、`from()` メソッドを呼び出します。
+例えば、SQL クエリの `FROM` の部分を定義するためには、`from()` メソッドを呼び出します。
クエリ構築メソッドは、すべて、クエリオブジェクトそのものを返しますので、複数の呼び出しをチェーンしてまとめることが出来ます。
以下で、それぞれのクエリ構築メソッドの使用方法を説明しましょう。
@@ -58,7 +58,7 @@ $query->select(['id', 'email']);
$query->select('id, email');
```
-選択されるカラム名は、生の SQL 文を書くときにするように、テーブル接頭辞 および/または カラムのエイリアスを含むことが出来ます。
+選択されるカラム名は、生の SQL クエリを書くときにするように、テーブル接頭辞 および/または カラムのエイリアスを含むことが出来ます。
例えば、
```php
@@ -145,7 +145,7 @@ $query->from(['u' => $subQuery]);
### [[yii\db\Query::where()|where()]]
-[[yii\db\Query::where()|where()]] メソッドは、SQL 文の `WHERE` 句を定義します。
+[[yii\db\Query::where()|where()]] メソッドは、SQL クエリの `WHERE` 句を定義します。
`WHERE` の条件を指定するために、次の三つの形式から一つを選んで使うことが出来ます。
- 文字列形式、例えば、`'status=1'`
@@ -289,7 +289,7 @@ if (!empty($search)) {
}
```
-`$search` が空でない場合は次の SQL が生成されます。
+`$search` が空でない場合は次の WHERE 条件 が生成されます。
```sql
WHERE (`status` = 10) AND (`title` LIKE '%yii%')
@@ -310,7 +310,7 @@ $query->filterWhere([
```
[[yii\db\Query::filterWhere()|filterWhere()]] と [[yii\db\Query::where()|where()]] の唯一の違いは、前者は [ハッシュ形式](#hash-format) の条件において提供された空の値を無視する、という点です。
-従って、`$email` が空で `$sername` がそうではない場合は、上記のコードは、結果として `...WHERE username=:username` という SQL になります。
+従って、`$email` が空で `$sername` がそうではない場合は、上記のコードは、結果として `WHERE username=:username` という SQL 条件になります。
> Info|情報: 値が空であると見なされるのは、null、空の配列、空の文字列、または空白のみを含む文字列である場合です。
@@ -318,7 +318,7 @@ $query->filterWhere([
### [[yii\db\Query::orderBy()|orderBy()]]
-[[yii\db\Query::orderBy()|orderBy()]] メソッドは SQL 文の `ORDER BY` 句を指定します。例えば、
+[[yii\db\Query::orderBy()|orderBy()]] メソッドは SQL クエリの `ORDER BY` 句を指定します。例えば、
```php
@@ -351,7 +351,7 @@ $query->orderBy('id ASC')
### [[yii\db\Query::groupBy()|groupBy()]]
-[[yii\db\Query::groupBy()|groupBy()]] メソッドは SQL 文の `GROUP BY` 句を指定します。
+[[yii\db\Query::groupBy()|groupBy()]] メソッドは SQL クエリの `GROUP BY` 句を指定します。
例えば、
```php
@@ -379,7 +379,7 @@ $query->groupBy(['id', 'status'])
### [[yii\db\Query::having()|having()]]
-[[yii\db\Query::having()|having()]] メソッドは SQL 文の `HAVING` 句を指定します。
+[[yii\db\Query::having()|having()]] メソッドは SQL クエリの `HAVING` 句を指定します。
このメソッドが取る条件は、[where()](#where) と同じ方法で指定することが出来ます。
例えば、
@@ -402,7 +402,7 @@ $query->having(['status' => 1])
### [[yii\db\Query::limit()|limit()]] と [[yii\db\Query::offset()|offset()]]
-[[yii\db\Query::limit()|limit()]] と [[yii\db\Query::offset()|offset()]] のメソッドは、SQL 文の `LIMIT` と `OFFSET` 句を指定します。
+[[yii\db\Query::limit()|limit()]] と [[yii\db\Query::offset()|offset()]] のメソッドは、SQL クエリの `LIMIT` 句と `OFFSET` 句を指定します。
例えば、
```php
@@ -417,7 +417,7 @@ $query->limit(10)->offset(20);
### [[yii\db\Query::join()|join()]]
-[[yii\db\Query::join()|join()]] メソッドは SQL 文の `JOIN` 句を指定します。例えば、
+[[yii\db\Query::join()|join()]] メソッドは SQL クエリの `JOIN` 句を指定します。例えば、
```php
// ... LEFT JOIN `post` ON `post`.`user_id` = `user`.`id`
@@ -430,6 +430,9 @@ $query->join('LEFT JOIN', 'post', 'post.user_id = user.id');
- `$table`: 結合されるテーブルの名前。
- `$on`: オプション。結合条件、すなわち、`ON` 句。
条件の指定方法の詳細については、[where()](#where) を参照してください。
+ カラムに基づく条件を指定する場合は、配列記法は**使えない**ことに注意してください。
+ 例えば、`['user.id' => 'comment.userId']` は、user の id が `'comment.userId'` という文字列でなければならない、という条件に帰結します。
+ 配列記法ではなく文字列記法を使って、`'user.id = comment.userId'` という条件を指定しなければなりません。
- `$params`: オプション。結合条件にバインドされるパラメータ。
`INNER JOIN`、`LEFT JOIN` および `RIGHT JOIN` を指定するためには、それぞれ、次のショートカットメソッドを使うことが出来ます。
@@ -460,7 +463,7 @@ $query->leftJoin(['u' => $subQuery], 'u.id = author_id');
### [[yii\db\Query::union()|union()]]
-[[yii\db\Query::union()|union()]] メソッドは SQL 文の `UNION` 句を指定します。例えば、
+[[yii\db\Query::union()|union()]] メソッドは SQL クエリの `UNION` 句を指定します。例えば、
```php
$query1 = (new \yii\db\Query())
@@ -495,7 +498,7 @@ $query1->union($query2);
上記のメソッドの全ては、オプションで、DB クエリの実行に使用されるべき [[yii\db\Connection|DB 接続]] を表す `$db` パラメータを取ることが出来ます。
このパラメータを省略した場合は、DB 接続として `db` [アプリケーションコンポーネント](structure-application-components.md) が使用されます。
-次に `count()` クエリメソッドを使う例をもう一つ挙げます。
+次に [[yii\db\Query::count()|count()]] クエリメソッドを使う例をもう一つ挙げます。
```php
// 実行される SQL: SELECT COUNT(*) FROM `user` WHERE `last_name`=:last_name
@@ -509,7 +512,7 @@ $count = (new \yii\db\Query())
* [[yii\db\QueryBuilder]] を呼んで、[[yii\db\Query]] の現在の構成に基づいた SQL 文を生成する。
* 生成された SQL 文で [[yii\db\Command]] オブジェクトを作成する。
-* [[yii\db\Command]] のクエリメソッド (例えば `queryAll()`) を呼んで、SQL 文を実行し、データを取得する。
+* [[yii\db\Command]] のクエリメソッド (例えば [[yii\db\Command::queryAll()|queryAll()]]) を呼んで、SQL 文を実行し、データを取得する。
場合によっては、[[yii\db\Query]] オブジェクトから構築された SQL 文を調べたり使ったりしたいことがあるでしょう。
次のコードを使って、その目的を達することが出来ます。
@@ -610,5 +613,6 @@ foreach ($query->batch() as $users) {
}
foreach ($query->each() as $username => $user) {
+ // ...
}
```