From bd0605d6e289d46f7196c85288923415af13f1b2 Mon Sep 17 00:00:00 2001 From: Nobuo Kihara Date: Wed, 3 Dec 2014 07:59:47 +0900 Subject: [PATCH 1/6] docs/guide-ja/db-query-builder.md - started translation [ci skip] --- docs/guide-ja/db-dao.md | 12 +- docs/guide-ja/db-query-builder.md | 469 ++++++++++++++++++++++++++++++ 2 files changed, 475 insertions(+), 6 deletions(-) create mode 100644 docs/guide-ja/db-query-builder.md diff --git a/docs/guide-ja/db-dao.md b/docs/guide-ja/db-dao.md index 427036c31a..89297c4d9a 100644 --- a/docs/guide-ja/db-dao.md +++ b/docs/guide-ja/db-dao.md @@ -4,9 +4,9 @@ > Note|注意: この節はまだ執筆中です。 Yii は、PHP の [PDO](http://www.php.net/manual/ja/book.pdo.php) の上に構築されたデータベースアクセスレイヤを含んでいます。 -データベースアクセスオブジェクト (DAO) のインタフェイスは、統一された API を提供し、さまざまなデータベース製品間に存在する不統一をいくらか解決します。 -アクティブレコードがモデルを通じてのデータベースとの相互作用を提供し、クエリビルダが動的なクエリの構成を支援する一方で、DAO -はデータベースに対して直接に SQL を実行する単純で効率的な方法を提供するものです。 +データベースアクセスオブジェクト (DAO) のインタフェイスは、統一された API を提供し、さまざまなデータベース製品間に存在する不統一のいくらかを解決します。 +アクティブレコードは、モデルを通じてのデータベースとの相互作用を提供し、クエリビルダは、動的なクエリの作成を支援します。 +一方、DAO はデータベースに対して直接に SQL を実行する単純で効率的な方法を提供します。 実行すべきクエリが高価なものである場合、かつ/または、アプリケーションモデル (および対応するビジネスロジック) が必要でない場合に、あなたは DAO を使いたいと思うでしょう。 Yii はデフォルトで下記の DBMS をサポートしています。 @@ -384,7 +384,7 @@ DBMS によっては、接続全体に対してのみ分離レベルの設定を 'username' => 'slave', 'password' => '', 'attributes' => [ - // 短めの接続タイムアウトを使う + // 短かめの接続タイムアウトを使う PDO::ATTR_TIMEOUT => 10, ], ], @@ -439,7 +439,7 @@ $db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute(); 'username' => 'master', 'password' => '', 'attributes' => [ - // 短めの接続タイムアウトを使う + // 短かめの接続タイムアウトを使う PDO::ATTR_TIMEOUT => 10, ], ], @@ -455,7 +455,7 @@ $db->createCommand("UPDATE user SET username='demo' WHERE id=1")->execute(); 'username' => 'slave', 'password' => '', 'attributes' => [ - // 短めの接続タイムアウトを使う + // 短かめの接続タイムアウトを使う PDO::ATTR_TIMEOUT => 10, ], ], diff --git a/docs/guide-ja/db-query-builder.md b/docs/guide-ja/db-query-builder.md new file mode 100644 index 0000000000..cde40e345c --- /dev/null +++ b/docs/guide-ja/db-query-builder.md @@ -0,0 +1,469 @@ +クエリビルダとクエリ +==================== + +> Note|注意: この節はまだ執筆中です。 + +[データベースの基礎](db-dao.md) の節で説明したように、Yii は基本的なデータベースアクセスレイヤを提供します。 +このデータベースアクセスレイヤは、データベースと相互作用するための低レベルな方法を提供するものです。 +それが有用な状況もありますが、生の SQL を書くことは面倒くさく、間違いを生じやすいものでもあります。 +これに取って代る方法の一つがクエリビルダを使用することです。 +クエリビルダは、実行すべきクエリを生成するためのオブジェクト指向の手法です。 + +クエリビルダの典型的な使用例は以下のようなものです。 + +```php +$rows = (new \yii\db\Query()) + ->select('id, name') + ->from('user') + ->limit(10) + ->all(); + +// これは下記のコードと等価 + +$query = (new \yii\db\Query()) + ->select('id, name') + ->from('user') + ->limit(10); + +// コマンドを作成。$command->sql で実際の SQL を取得できる +$command = $query->createCommand(); + +// コマンドを実行 +$rows = $command->queryAll(); +``` + +クエリメソッド +-------------- + +ご覧のように、[[yii\db\Query]] が、あなたが扱わねばならない主役のオブジェクトです。 +舞台裏では、`Query` は、実際には、さまざまなクエリ情報を表現する役目を負っているに過ぎません。 +実際のクエリ構築のロジックは、`createCommand()` コマンドを呼んだときに、[[yii\db\QueryBuilder]] によって実行され、クエリの実行は [[yii\db\Command]] によって実行されます。 + +便宜上の理由から、[[yii\db\Query]] が、よく使われる一連のクエリメソッド (クエリを構築し、実行して、結果を返すメソッド) を提供しています。 +例えば、 + +- [[yii\db\Query::all()|all()]]: クエリを構築し、実行して、全ての結果を配列として返します。 +- [[yii\db\Query::one()|one()]]: 結果の最初の行を返します。 +- [[yii\db\Query::column()|column()]]: 結果の最初のカラムを返します。 +- [[yii\db\Query::scalar()|scalar()]]: 結果の最初の行の最初のカラムを返します。 +- [[yii\db\Query::exists()|exists()]]: 何らかのクエリ結果が有るかどうかを返します。 +- [[yii\db\Query::count()|count()]]: `COUNT` クエリの結果を返します。 + 他の似たようなメソッドに、`sum($q)`、`average($q)`、`max($q)`、`min($q)` があり、いわゆる統計データクエリをサポートしています。 + これらのメソッドでは `$q` パラメータは必須であり、カラム名または式を取ります。 + + +クエリを構築する +---------------- + +In the following, we will explain how to build various clauses in a SQL statement. For simplicity, +we use `$query` to represent a [[yii\db\Query]] object. + + +### `SELECT` + +In order to form a basic `SELECT` query, you need to specify what columns to select and from what table: + +```php +$query->select('id, name') + ->from('user'); +``` + +Select options can be specified as a comma-separated string, as in the above, or as an array. +The array syntax is especially useful when forming the selection dynamically: + +```php +$query->select(['id', 'name']) + ->from('user'); +``` + +> Info: You should always use the array format if your `SELECT` clause contains SQL expressions. +> This is because a SQL expression like `CONCAT(first_name, last_name) AS full_name` may contain commas. +> If you list it together with other columns in a string, the expression may be split into several parts +> by commas, which is not what you want to see. + +When specifying columns, you may include the table prefixes or column aliases, e.g., `user.id`, `user.id AS user_id`. +If you are using array to specify the columns, you may also use the array keys to specify the column aliases, +e.g., `['user_id' => 'user.id', 'user_name' => 'user.name']`. + +Starting from version 2.0.1, you may also select sub-queries as columns. For example, + +```php +$subQuery = (new Query)->select('COUNT(*)')->from('user'); +$query = (new Query)->select(['id', 'count' => $subQuery])->from('post'); +// $query represents the following SQL: +// SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post` +``` + +To select distinct rows, you may call `distinct()`, like the following: + +```php +$query->select('user_id')->distinct()->from('post'); +``` + +### `FROM` + +To specify which table(s) to select data from, call `from()`: + +```php +$query->select('*')->from('user'); +``` + +You may specify multiple tables using a comma-separated string or an array. +Table names can contain schema prefixes (e.g. `'public.user'`) and/or table aliases (e.g. `'user u'`). +The method will automatically quote the table names unless it contains some parenthesis +(which means the table is given as a sub-query or DB expression). For example, + +```php +$query->select('u.*, p.*')->from(['user u', 'post p']); +``` + +When the tables are specified as an array, you may also use the array keys as the table aliases +(if a table does not need alias, do not use a string key). For example, + +```php +$query->select('u.*, p.*')->from(['u' => 'user', 'p' => 'post']); +``` + +You may specify a sub-query using a `Query` object. In this case, the corresponding array key will be used +as the alias for the sub-query. + +```php +$subQuery = (new Query())->select('id')->from('user')->where('status=1'); +$query->select('*')->from(['u' => $subQuery]); +``` + + +### `WHERE` + +Usually data is selected based upon certain criteria. Query Builder has some useful methods to specify these, the most powerful of which being `where`. It can be used in multiple ways. + +The simplest way to apply a condition is to use a string: + +```php +$query->where('status=:status', [':status' => $status]); +``` + +When using strings, make sure you're binding the query parameters, not creating a query by string concatenation. The above approach is safe to use, the following is not: + +```php +$query->where("status=$status"); // Dangerous! +``` + +Instead of binding the status value immediately, you can do so using `params` or `addParams`: + +```php +$query->where('status=:status'); +$query->addParams([':status' => $status]); +``` + +Multiple conditions can simultaneously be set in `where` using the *hash format*: + +```php +$query->where([ + 'status' => 10, + 'type' => 2, + 'id' => [4, 8, 15, 16, 23, 42], +]); +``` + +That code will generate the following SQL: + +```sql +WHERE (`status` = 10) AND (`type` = 2) AND (`id` IN (4, 8, 15, 16, 23, 42)) +``` + +NULL is a special value in databases, and is handled smartly by the Query Builder. This code: + +```php +$query->where(['status' => null]); +``` + +results in this WHERE clause: + +```sql +WHERE (`status` IS NULL) +``` + +You can also create sub-queries with `Query` objects like the following, + +```php +$userQuery = (new Query)->select('id')->from('user'); +$query->where(['id' => $userQuery]); +``` + +which will generate the following SQL: + +```sql +WHERE `id` IN (SELECT `id` FROM `user`) +``` + + +Another way to use the method is the operand format which is `[operator, operand1, operand2, ...]`. + +Operator can be one of the following (see also [[yii\db\QueryInterface::where()]]): + +- `and`: the operands should be concatenated together using `AND`. For example, + `['and', 'id=1', 'id=2']` will generate `id=1 AND id=2`. If an operand is an array, + it will be converted into a string using the rules described here. For example, + `['and', 'type=1', ['or', 'id=1', 'id=2']]` will generate `type=1 AND (id=1 OR id=2)`. + The method will NOT do any quoting or escaping. + +- `or`: similar to the `and` operator except that the operands are concatenated using `OR`. + +- `between`: operand 1 should be the column name, and operand 2 and 3 should be the + starting and ending values of the range that the column is in. + For example, `['between', 'id', 1, 10]` will generate `id BETWEEN 1 AND 10`. + +- `not between`: similar to `between` except the `BETWEEN` is replaced with `NOT BETWEEN` + in the generated condition. + +- `in`: operand 1 should be a column or DB expression. Operand 2 can be either an array or a `Query` object. + It will generate an `IN` condition. If Operand 2 is an array, it will represent the range of the values + that the column or DB expression should be; If Operand 2 is a `Query` object, a sub-query will be generated + and used as the range of the column or DB expression. For example, + `['in', 'id', [1, 2, 3]]` will generate `id IN (1, 2, 3)`. + The method will properly quote the column name and escape values in the range. + The `in` operator also supports composite columns. In this case, operand 1 should be an array of the columns, + while operand 2 should be an array of arrays or a `Query` object representing the range of the columns. + +- `not in`: similar to the `in` operator except that `IN` is replaced with `NOT IN` in the generated condition. + +- `like`: operand 1 should be a column or DB expression, and operand 2 be a string or an array representing + the values that the column or DB expression should be like. + For example, `['like', 'name', 'tester']` will generate `name LIKE '%tester%'`. + When the value range is given as an array, multiple `LIKE` predicates will be generated and concatenated + using `AND`. For example, `['like', 'name', ['test', 'sample']]` will generate + `name LIKE '%test%' AND name LIKE '%sample%'`. + You may also provide an optional third operand to specify how to escape special characters in the values. + The operand should be an array of mappings from the special characters to their + escaped counterparts. If this operand is not provided, a default escape mapping will be used. + You may use `false` or an empty array to indicate the values are already escaped and no escape + should be applied. Note that when using an escape mapping (or the third operand is not provided), + the values will be automatically enclosed within a pair of percentage characters. + + > Note: When using PostgreSQL you may also use [`ilike`](http://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) + > instead of `like` for case-insensitive matching. + +- `or like`: similar to the `like` operator except that `OR` is used to concatenate the `LIKE` + predicates when operand 2 is an array. + +- `not like`: similar to the `like` operator except that `LIKE` is replaced with `NOT LIKE` + in the generated condition. + +- `or not like`: similar to the `not like` operator except that `OR` is used to concatenate + the `NOT LIKE` predicates. + +- `exists`: requires one operand which must be an instance of [[yii\db\Query]] representing the sub-query. + It will build a `EXISTS (sub-query)` expression. + +- `not exists`: similar to the `exists` operator and builds a `NOT EXISTS (sub-query)` expression. + +Additionally you can specify anything as operator: + +```php +$userQuery = (new Query)->select('id')->from('user'); +$query->where(['>=', 'id', 10]); +``` + +It will result in: + +```sql +SELECT id FROM user WHERE id >= 10; +``` + +If you are building parts of condition dynamically it's very convenient to use `andWhere()` and `orWhere()`: + +```php +$status = 10; +$search = 'yii'; + +$query->where(['status' => $status]); +if (!empty($search)) { + $query->andWhere(['like', 'title', $search]); +} +``` + +In case `$search` isn't empty the following SQL will be generated: + +```sql +WHERE (`status` = 10) AND (`title` LIKE '%yii%') +``` + +#### Building Filter Conditions + +When building filter conditions based on user inputs, you usually want to specially handle "empty inputs" +by ignoring them in the filters. For example, you have an HTML form that takes username and email inputs. +If the user only enters something in the username input, you may want to build a query that only tries to +match the entered username. You may use the `filterWhere()` method achieve this goal: + +```php +// $username and $email are from user inputs +$query->filterWhere([ + 'username' => $username, + 'email' => $email, +]); +``` + +The `filterWhere()` method is very similar to `where()`. The main difference is that `filterWhere()` +will remove empty values from the provided condition. So if `$email` is "empty", the resulting query +will be `...WHERE username=:username`; and if both `$username` and `$email` are "empty", the query +will have no `WHERE` part. + +A value is *empty* if it is null, an empty string, a string consisting of whitespaces, or an empty array. + +You may also use `andFilterWhere()` and `orFilterWhere()` to append more filter conditions. + + +### `ORDER BY` + +For ordering results `orderBy` and `addOrderBy` could be used: + +```php +$query->orderBy([ + 'id' => SORT_ASC, + 'name' => SORT_DESC, +]); +``` + +Here we are ordering by `id` ascending and then by `name` descending. + +### `GROUP BY` and `HAVING` + +In order to add `GROUP BY` to generated SQL you can use the following: + +```php +$query->groupBy('id, status'); +``` + +If you want to add another field after using `groupBy`: + +```php +$query->addGroupBy(['created_at', 'updated_at']); +``` + +To add a `HAVING` condition the corresponding `having` method and its `andHaving` and `orHaving` can be used. Parameters +for these are similar to the ones for `where` methods group: + +```php +$query->having(['status' => $status]); +``` + +### `LIMIT` and `OFFSET` + +To limit result to 10 rows `limit` can be used: + +```php +$query->limit(10); +``` + +To skip 100 fist rows use: + +```php +$query->offset(100); +``` + +### `JOIN` + +The `JOIN` clauses are generated in the Query Builder by using the applicable join method: + +- `innerJoin()` +- `leftJoin()` +- `rightJoin()` + +This left join selects data from two related tables in one query: + +```php +$query->select(['user.name AS author', 'post.title as title']) + ->from('user') + ->leftJoin('post', 'post.user_id = user.id'); +``` + +In the code, the `leftJoin()` method's first parameter +specifies the table to join to. The second parameter defines the join condition. + +If your database application supports other join types, you can use those via the generic `join` method: + +```php +$query->join('FULL OUTER JOIN', 'post', 'post.user_id = user.id'); +``` + +The first argument is the join type to perform. The second is the table to join to, and the third is the condition. + +Like `FROM`, you may also join with sub-queries. To do so, specify the sub-query as an array +which must contain one element. The array value must be a `Query` object representing the sub-query, +while the array key is the alias for the sub-query. For example, + +```php +$query->leftJoin(['u' => $subQuery], 'u.id=author_id'); +``` + + +### `UNION` + +`UNION` in SQL adds results of one query to results of another query. Columns returned by both queries should match. +In Yii in order to build it you can first form two query objects and then use `union` method: + +```php +$query = new Query(); +$query->select("id, category_id as type, name")->from('post')->limit(10); + +$anotherQuery = new Query(); +$anotherQuery->select('id, type, name')->from('user')->limit(10); + +$query->union($anotherQuery); +``` + + +Batch Query +----------- + +When working with large amount of data, methods such as [[yii\db\Query::all()]] are not suitable +because they require loading all data into the memory. To keep the memory requirement low, Yii +provides the so-called batch query support. A batch query makes uses of data cursor and fetches +data in batches. + +Batch query can be used like the following: + +```php +use yii\db\Query; + +$query = (new Query()) + ->from('user') + ->orderBy('id'); + +foreach ($query->batch() as $users) { + // $users is an array of 100 or fewer rows from the user table +} + +// or if you want to iterate the row one by one +foreach ($query->each() as $user) { + // $user represents one row of data from the user table +} +``` + +The method [[yii\db\Query::batch()]] and [[yii\db\Query::each()]] return an [[yii\db\BatchQueryResult]] object +which implements the `Iterator` interface and thus can be used in the `foreach` construct. +During the first iteration, a SQL query is made to the database. Data are since then fetched in batches +in the iterations. By default, the batch size is 100, meaning 100 rows of data are being fetched in each batch. +You can change the batch size by passing the first parameter to the `batch()` or `each()` method. + +Compared to the [[yii\db\Query::all()]], the batch query only loads 100 rows of data at a time into the memory. +If you process the data and then discard it right away, the batch query can help keep the memory usage under a limit. + +If you specify the query result to be indexed by some column via [[yii\db\Query::indexBy()]], the batch query +will still keep the proper index. For example, + +```php +use yii\db\Query; + +$query = (new Query()) + ->from('user') + ->indexBy('username'); + +foreach ($query->batch() as $users) { + // $users is indexed by the "username" column +} + +foreach ($query->each() as $username => $user) { +} +``` From d456319988dccc65fd0bbf75132ada69d57c16be Mon Sep 17 00:00:00 2001 From: Nobuo Kihara Date: Wed, 3 Dec 2014 23:26:53 +0900 Subject: [PATCH 2/6] docs/guide-ja/db-query-builder.md - WIP [ci skip] --- docs/guide-ja/db-query-builder.md | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/docs/guide-ja/db-query-builder.md b/docs/guide-ja/db-query-builder.md index cde40e345c..68d1e38d94 100644 --- a/docs/guide-ja/db-query-builder.md +++ b/docs/guide-ja/db-query-builder.md @@ -55,42 +55,41 @@ $rows = $command->queryAll(); クエリを構築する ---------------- -In the following, we will explain how to build various clauses in a SQL statement. For simplicity, -we use `$query` to represent a [[yii\db\Query]] object. +以下に、SQL 文の中のさまざまな句を組み立てる方法を説明します。 +話を単純にするために、`$query` という変数を使って [[yii\db\Query]] オブジェクトを表すものとします。 ### `SELECT` -In order to form a basic `SELECT` query, you need to specify what columns to select and from what table: +基本的な `SELECT` クエリを形作るためには、どのテーブルからどのカラムをセレクトするかを指定する必要があります。 ```php $query->select('id, name') ->from('user'); ``` -Select options can be specified as a comma-separated string, as in the above, or as an array. -The array syntax is especially useful when forming the selection dynamically: +セレクトのオプションは、上記のように、カンマで区切られた文字列で指定することも出来ますが、配列によって指定することも出来ます。 +配列を使う構文は、セレクトを動的に形作る場合に、特に有用です。 ```php $query->select(['id', 'name']) ->from('user'); ``` -> Info: You should always use the array format if your `SELECT` clause contains SQL expressions. -> This is because a SQL expression like `CONCAT(first_name, last_name) AS full_name` may contain commas. -> If you list it together with other columns in a string, the expression may be split into several parts -> by commas, which is not what you want to see. +> Info|情報: `SELECT` 句が SQL 式を含む場合は、常に配列形式を使うべきです。 +> これは、`CONCAT(first_name, last_name) AS full_name` のように、SQL 式がカンマを含みうるからです。 +> そういう式を他のカラムと一緒に文字列の中に含めると、式がカンマによっていくつかの部分に分離されるおそれがあります。 +> それはあなたの意図するところではないでしょう。 -When specifying columns, you may include the table prefixes or column aliases, e.g., `user.id`, `user.id AS user_id`. -If you are using array to specify the columns, you may also use the array keys to specify the column aliases, -e.g., `['user_id' => 'user.id', 'user_name' => 'user.name']`. +カラムを指定するときは、例えば `user.id` や `user.id AS user_id` などのように、テーブル接頭辞やカラムエイリアスを含めることが出来ます。 +カラムを指定するのに配列を使っている場合は、例えば `['user_id' => 'user.id', 'user_name' => 'user.name']` のように、配列のキーを使ってカラムエイリアスを指定することも出来ます。 -Starting from version 2.0.1, you may also select sub-queries as columns. For example, +バージョン 2.0.1 以降では、サブクエリをカラムとしてセレクトすることも出来ます。例えば、 ```php $subQuery = (new Query)->select('COUNT(*)')->from('user'); $query = (new Query)->select(['id', 'count' => $subQuery])->from('post'); -// $query represents the following SQL: +// $query は次の SQL を表現する // SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post` ``` From b1d3853d207fac3e6757032220b544858110cd6b Mon Sep 17 00:00:00 2001 From: Nobuo Kihara Date: Thu, 4 Dec 2014 08:10:19 +0900 Subject: [PATCH 3/6] docs/guide-ja/db-query-builder.md - WIP [ci skip] --- docs/guide-ja/db-query-builder.md | 52 +++++++++++++++++-------------- 1 file changed, 28 insertions(+), 24 deletions(-) diff --git a/docs/guide-ja/db-query-builder.md b/docs/guide-ja/db-query-builder.md index 68d1e38d94..84b3c9e6a2 100644 --- a/docs/guide-ja/db-query-builder.md +++ b/docs/guide-ja/db-query-builder.md @@ -61,7 +61,7 @@ $rows = $command->queryAll(); ### `SELECT` -基本的な `SELECT` クエリを形作るためには、どのテーブルからどのカラムをセレクトするかを指定する必要があります。 +基本的な `SELECT` クエリを組み立てるためには、どのテーブルからどのカラムをセレクトするかを指定する必要があります。 ```php $query->select('id, name') @@ -69,7 +69,7 @@ $query->select('id, name') ``` セレクトのオプションは、上記のように、カンマで区切られた文字列で指定することも出来ますが、配列によって指定することも出来ます。 -配列を使う構文は、セレクトを動的に形作る場合に、特に有用です。 +配列を使う構文は、セレクトを動的に組み立てる場合に、特に有用です。 ```php $query->select(['id', 'name']) @@ -93,7 +93,7 @@ $query = (new Query)->select(['id', 'count' => $subQuery])->from('post'); // SELECT `id`, (SELECT COUNT(*) FROM `user`) AS `count` FROM `post` ``` -To select distinct rows, you may call `distinct()`, like the following: +重複行を除外して取得したい場合は、次のように、`distinct()` を呼ぶことが出来ます。 ```php $query->select('user_id')->distinct()->from('post'); @@ -101,30 +101,31 @@ $query->select('user_id')->distinct()->from('post'); ### `FROM` -To specify which table(s) to select data from, call `from()`: +どのテーブルからデータを取得するかを指定するために `from()` を呼びます。 ```php $query->select('*')->from('user'); ``` -You may specify multiple tables using a comma-separated string or an array. -Table names can contain schema prefixes (e.g. `'public.user'`) and/or table aliases (e.g. `'user u'`). -The method will automatically quote the table names unless it contains some parenthesis -(which means the table is given as a sub-query or DB expression). For example, +カンマ区切りの文字列または配列を使って、複数のテーブルを指定することが出来ます。 +テーブル名は、スキーマ接頭辞 (例えば `'public.user'`)、 および/または、テーブルエイリアス (例えば、`'user u'`) を含んでも構いません。 +テーブル名が何らかの括弧を含んでいる場合 (すなわち、テーブルがサブクエリまたは DB 式で与えられていることを意味します) を除いて、メソッドが自動的にテーブル名を引用符で囲みます。 +例えば、 ```php $query->select('u.*, p.*')->from(['user u', 'post p']); ``` -When the tables are specified as an array, you may also use the array keys as the table aliases -(if a table does not need alias, do not use a string key). For example, +テーブルが配列として指定されている場合は、配列のキーをテーブルエイリアスとして使うことも出来ます。 +(テーブルにエイリアスが必要でない場合は、文字列のキーを使わないでください。) +例えば、 ```php $query->select('u.*, p.*')->from(['u' => 'user', 'p' => 'post']); ``` -You may specify a sub-query using a `Query` object. In this case, the corresponding array key will be used -as the alias for the sub-query. +`Query` オブジェクトを使ってサブクエリを指定することが出来ます。 +この場合、対応する配列のキーがサブクエリのエイリアスとして使われます。 ```php $subQuery = (new Query())->select('id')->from('user')->where('status=1'); @@ -134,28 +135,31 @@ $query->select('*')->from(['u' => $subQuery]); ### `WHERE` -Usually data is selected based upon certain criteria. Query Builder has some useful methods to specify these, the most powerful of which being `where`. It can be used in multiple ways. +通常、データは何らかの基準に基づいて選択されます。 +クエリビルダはその基準を指定するための有用なメソッドをいくつか持っていますが、その中で最も強力なものが `where` です。 +これは多様な方法で使うことが出来ます。 -The simplest way to apply a condition is to use a string: +条件を適用するもっとも簡単な方法は文字列を使うことです。 ```php $query->where('status=:status', [':status' => $status]); ``` -When using strings, make sure you're binding the query parameters, not creating a query by string concatenation. The above approach is safe to use, the following is not: +文字列を使うときは、文字列の結合によってクエリを作るのではなく、必ずクエリパラメータをバインドするようにしてください。 +上記の手法は使っても安全ですが、下記の手法は安全ではありません。 ```php -$query->where("status=$status"); // Dangerous! +$query->where("status=$status"); // 危険! ``` -Instead of binding the status value immediately, you can do so using `params` or `addParams`: +`status` の値をただちにバインドするのでなく、`params` または `addParams` を使ってそうすることも出来ます。 ```php $query->where('status=:status'); $query->addParams([':status' => $status]); ``` -Multiple conditions can simultaneously be set in `where` using the *hash format*: +*ハッシュ形式* を使って、複数の条件を同時に `where` にセットすることが出来ます。 ```php $query->where([ @@ -165,38 +169,38 @@ $query->where([ ]); ``` -That code will generate the following SQL: +上記のコードは次の SQL を生成します。 ```sql WHERE (`status` = 10) AND (`type` = 2) AND (`id` IN (4, 8, 15, 16, 23, 42)) ``` -NULL is a special value in databases, and is handled smartly by the Query Builder. This code: +NULL はデータベースでは特別な値です。クエリビルダはこれを賢く処理します。例えば、 ```php $query->where(['status' => null]); ``` -results in this WHERE clause: +これは次の WHERE 句になります。 ```sql WHERE (`status` IS NULL) ``` -You can also create sub-queries with `Query` objects like the following, +次のように `Query` オブジェクトを使ってサブクエリを作ることも出来ます。 ```php $userQuery = (new Query)->select('id')->from('user'); $query->where(['id' => $userQuery]); ``` -which will generate the following SQL: +これは次の SQL を生成します。 ```sql WHERE `id` IN (SELECT `id` FROM `user`) ``` - +このメソッドを使うもう一つの方法は、`[演算子, オペランド1, オペランド2, ...]` という演算形式です。 Another way to use the method is the operand format which is `[operator, operand1, operand2, ...]`. Operator can be one of the following (see also [[yii\db\QueryInterface::where()]]): From 68c9cb836091ee007c9638eb6237e3b74c069091 Mon Sep 17 00:00:00 2001 From: Nobuo Kihara Date: Thu, 4 Dec 2014 20:55:17 +0900 Subject: [PATCH 4/6] =?UTF-8?q?docs/guide-ja=20-=20changed=20"=E7=A9=BA?= =?UTF-8?q?=E3=81=A3=E3=81=BD"=20to=20"=E7=A9=BA"=20[ci=20skip]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/guide-ja/runtime-routing.md | 2 +- docs/guide-ja/structure-assets.md | 2 +- docs/guide-ja/structure-models.md | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/guide-ja/runtime-routing.md b/docs/guide-ja/runtime-routing.md index 4a9d4b2761..8243361cf1 100644 --- a/docs/guide-ja/runtime-routing.md +++ b/docs/guide-ja/runtime-routing.md @@ -83,7 +83,7 @@ $url = Url::to(['post/view', 'id' => 100]); ### デフォルトルート -リクエストから解析されたルートが空っぽになった場合は、いわゆる *デフォルトルート* が代りに使用されることになります。 +リクエストから解析されたルートが空になった場合は、いわゆる *デフォルトルート* が代りに使用されることになります。 既定では、デフォルトルートは `site/index` であり、`site` コントローラの `index` アクションを指します。 デフォルトルートは、次のように、アプリケーションの構成情報の中でアプリケーションの [[yii\web\Application::defaultRoute|defaultRoute]] プロパティを構成することによって、カスタマイズすることが出来ます。 diff --git a/docs/guide-ja/structure-assets.md b/docs/guide-ja/structure-assets.md index a0d1dfb7b1..ee26b16343 100644 --- a/docs/guide-ja/structure-assets.md +++ b/docs/guide-ja/structure-assets.md @@ -450,7 +450,7 @@ HTTP リクエストの数とこれらのファイルの全体としてのダウ 3. 各グループの CSS ファイルを一つのファイルに結合/圧縮する。JavaScript ファイルに対しても同様にこれを行う。 4. 各グループに対して新しいアセットバンドルを定義する。 * [[yii\web\AssetBundle::css|css]] と [[yii\web\AssetBundle::js|js]] のプロパティに、それぞれ、結合された CSS ファイルと JavaScript ファイルをセットする。 - * 各グループに属する元のアセットバンドルをカスタマイズして、[[yii\web\AssetBundle::css|css]] と [[yii\web\AssetBundle::js|js]] のプロパティを空っぽにし、[[yii\web\AssetBundle::depends|depends]] プロパティにグループのために作られた新しいバンドルを指定する。 + * 各グループに属する元のアセットバンドルをカスタマイズして、[[yii\web\AssetBundle::css|css]] と [[yii\web\AssetBundle::js|js]] のプロパティを空にし、[[yii\web\AssetBundle::depends|depends]] プロパティにグループのために作られた新しいバンドルを指定する。 この方法を使うと、ビューでアセットバンドルを登録したときに、元のバンドルが属するグループのための新しいアセットバンドルが自動的に登録されるようになります。 そして、結果として、結合/圧縮されたアセットファイルが、元のファイルの代りに、ページにインクルードされます。 diff --git a/docs/guide-ja/structure-models.md b/docs/guide-ja/structure-models.md index 76dcffb7bb..e4470d2ef9 100644 --- a/docs/guide-ja/structure-models.md +++ b/docs/guide-ja/structure-models.md @@ -225,7 +225,7 @@ class User extends ActiveRecord ## 検証規則 モデルのデータをエンドユーザから受け取ったときは、データを検証して、それが一定の規則 (*検証規則*、あるいは、いわゆる *ビジネスルール*) を満たしていることを確認しなければなりません。 -`ContactForm` モデルを例に挙げるなら、全ての属性が空っぽではなく、`email` 属性が有効なメールアドレスを含んでいることを確認したいでしょう。 +`ContactForm` モデルを例に挙げるなら、全ての属性が空ではなく、`email` 属性が有効なメールアドレスを含んでいることを確認したいでしょう。 いずれかの属性の値が対応するビジネスルールを満たしていないときは、ユーザがエラーを訂正するのを助ける適切なエラーメッセージが表示されるべきです。 受信したデータを検証するために、[[yii\base\Model::validate()]] を呼ぶことが出来ます。 From b38c217932803ed3c64e8ef07d1c3f7e749324eb Mon Sep 17 00:00:00 2001 From: Nobuo Kihara Date: Thu, 4 Dec 2014 20:56:26 +0900 Subject: [PATCH 5/6] =?UTF-8?q?docs/guide-ja/db-dao.md=20-=20changed=20"?= =?UTF-8?q?=E3=83=97=E3=83=AA=E3=83=9A=E3=82=A2"=20to=20"=E6=BA=96?= =?UTF-8?q?=E5=82=99"=20[ci=20skip]?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docs/guide-ja/db-dao.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/guide-ja/db-dao.md b/docs/guide-ja/db-dao.md index 89297c4d9a..5018edcf0c 100644 --- a/docs/guide-ja/db-dao.md +++ b/docs/guide-ja/db-dao.md @@ -256,7 +256,7 @@ $command->bindValue(':id', $_GET['id']); $post = $command->queryOne(); ``` -プリペアドステートメントを使うもう一つの目的は (セキュリティの向上のほかに)、一度だけプリペアしたクエリを複数回実行することが出来るという点にあります。 +プリペアドステートメントを使うもう一つの目的は (セキュリティの向上のほかに)、一度だけ準備したクエリを複数回実行することが出来るという点にあります。 ```php $command = $connection->createCommand('DELETE FROM post WHERE id=:id'); From 7b0f6669a203c290f61e2f8a8f7df0c433a89f47 Mon Sep 17 00:00:00 2001 From: Nobuo Kihara Date: Thu, 4 Dec 2014 22:22:07 +0900 Subject: [PATCH 6/6] docs/guide-ja/db-query-builder.md - completed [ci skip] --- docs/guide-ja/db-query-builder.md | 202 ++++++++++++++---------------- 1 file changed, 97 insertions(+), 105 deletions(-) diff --git a/docs/guide-ja/db-query-builder.md b/docs/guide-ja/db-query-builder.md index 84b3c9e6a2..371cbf87c4 100644 --- a/docs/guide-ja/db-query-builder.md +++ b/docs/guide-ja/db-query-builder.md @@ -200,81 +200,71 @@ $query->where(['id' => $userQuery]); WHERE `id` IN (SELECT `id` FROM `user`) ``` -このメソッドを使うもう一つの方法は、`[演算子, オペランド1, オペランド2, ...]` という演算形式です。 -Another way to use the method is the operand format which is `[operator, operand1, operand2, ...]`. +このメソッドを使うもう一つの方法は、`[演算子, オペランド1, オペランド2, ...]` という形式の引数を使う方法です。 -Operator can be one of the following (see also [[yii\db\QueryInterface::where()]]): +演算子には、次のどれか一つを使うことが出来ます ([[yii\db\QueryInterface::where()]] も参照してください)。 -- `and`: the operands should be concatenated together using `AND`. For example, - `['and', 'id=1', 'id=2']` will generate `id=1 AND id=2`. If an operand is an array, - it will be converted into a string using the rules described here. For example, - `['and', 'type=1', ['or', 'id=1', 'id=2']]` will generate `type=1 AND (id=1 OR id=2)`. - The method will NOT do any quoting or escaping. +- `and`: 二つのオペランドが `AND` を使って結合されます。例えば、`['and', 'id=1', 'id=2']` は `id=1 AND id=2` を生成します。 + オペランドが配列である場合は、ここで説明されている規則に従って文字列に変換されます。 + 例えば、`['and', 'type=1', ['or', 'id=1', 'id=2']]` は `type=1 AND (id=1 OR id=2)` を生成します。 + このメソッドは、文字列を引用符で囲ったりエスケープしたりしません。 -- `or`: similar to the `and` operator except that the operands are concatenated using `OR`. +- `or`: 二つのオペランドが `OR` を使って結合されること以外は `and` 演算子と同じです。 -- `between`: operand 1 should be the column name, and operand 2 and 3 should be the - starting and ending values of the range that the column is in. - For example, `['between', 'id', 1, 10]` will generate `id BETWEEN 1 AND 10`. +- `between`: オペランド 1 はカラム名、オペランド 2 と 3 はカラムの値が属すべき範囲の開始値と終了値としなければなりません。 + 例えば、`['between', 'id', 1, 10]` は `id BETWEEN 1 AND 10` を生成します。 -- `not between`: similar to `between` except the `BETWEEN` is replaced with `NOT BETWEEN` - in the generated condition. +- `not between`: 生成される条件において `BETWEEN` が `NOT BETWEEN` に置き換えられる以外は、`between` と同じです。 -- `in`: operand 1 should be a column or DB expression. Operand 2 can be either an array or a `Query` object. - It will generate an `IN` condition. If Operand 2 is an array, it will represent the range of the values - that the column or DB expression should be; If Operand 2 is a `Query` object, a sub-query will be generated - and used as the range of the column or DB expression. For example, - `['in', 'id', [1, 2, 3]]` will generate `id IN (1, 2, 3)`. - The method will properly quote the column name and escape values in the range. - The `in` operator also supports composite columns. In this case, operand 1 should be an array of the columns, - while operand 2 should be an array of arrays or a `Query` object representing the range of the columns. +- `in`: オペランド 1 はカラム名または DB 式でなければなりません。 + オペランド 2 は、配列または `Query` オブジェクトのどちらかを取ることが出来ます。 + オペランド 2 が配列である場合は、その配列は、カラムまたは DB 式が該当すべき値域を表すものとされます。 + オペランド 2 が `Query` オブジェクトである場合は、サブクエリが生成されて、カラムまたは DB 式の値域として使われます。 + 例えば、`['in', 'id', [1, 2, 3]]` は `id IN (1, 2, 3)` を生成します。 + このメソッドは、カラム名を適切に引用符で囲み、値域の値をエスケープします。 + `in` 演算子はまた複合カラムをもサポートしています。 + その場合、オペランド 1 はカラム名の配列とし、オペランド 2 は配列の配列、または、複合カラムの値域を表す `Query` オブジェクトでなければなりません。 -- `not in`: similar to the `in` operator except that `IN` is replaced with `NOT IN` in the generated condition. +- `not in`: 生成される条件において `IN` が `NOT IN` に置き換えられる以外は、`in` と同じです。 -- `like`: operand 1 should be a column or DB expression, and operand 2 be a string or an array representing - the values that the column or DB expression should be like. - For example, `['like', 'name', 'tester']` will generate `name LIKE '%tester%'`. - When the value range is given as an array, multiple `LIKE` predicates will be generated and concatenated - using `AND`. For example, `['like', 'name', ['test', 'sample']]` will generate - `name LIKE '%test%' AND name LIKE '%sample%'`. - You may also provide an optional third operand to specify how to escape special characters in the values. - The operand should be an array of mappings from the special characters to their - escaped counterparts. If this operand is not provided, a default escape mapping will be used. - You may use `false` or an empty array to indicate the values are already escaped and no escape - should be applied. Note that when using an escape mapping (or the third operand is not provided), - the values will be automatically enclosed within a pair of percentage characters. +- `like`: オペランド 1 はカラム名または DB 式、オペランド 2 はカラムまたは DB 式がマッチすべき値を示す文字列または配列でなければなりません。 + 例えば、`['like', 'name', 'tester']` は `name LIKE '%tester%'` を生成します。 + 値域が配列として与えられた場合は、複数の `LIKE` 述語が生成されて 'AND' によって結合されます。 + 例えば、`['like', 'name', ['test', 'sample']]` は `name LIKE '%test%' AND name LIKE '%sample%'` を生成します。 + さらに、オプションである三番目のオペランドによって、値の中の特殊文字をエスケープする方法を指定することも出来ます。 + このオペランド 3 は、特殊文字とそのエスケープ結果のマッピングを示す配列でなければなりません。 + このオペランドが提供されない場合は、デフォルトのエスケープマッピングが使用されます。 + `false` または空の配列を使って、値が既にエスケープ済みであり、それ以上エスケープを適用すべきでないことを示すことが出来ます。 + エスケープマッピングを使用する場合 (または第三のオペランドが与えられない場合) は、値が自動的に一組のパーセント記号によって囲まれることに注意してください。 - > Note: When using PostgreSQL you may also use [`ilike`](http://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) - > instead of `like` for case-insensitive matching. + > Note|注意: PostgreSQL を使っている場合は、`like` の代りに、大文字と小文字を区別しない比較のための [`ilike`](http://www.postgresql.org/docs/8.3/static/functions-matching.html#FUNCTIONS-LIKE) を使うことも出来ます。 -- `or like`: similar to the `like` operator except that `OR` is used to concatenate the `LIKE` - predicates when operand 2 is an array. +- `or like`: オペランド 2 が配列である場合に `LIKE` 述語が `OR` によって結合される以外は、`like` 演算子と同じです。 -- `not like`: similar to the `like` operator except that `LIKE` is replaced with `NOT LIKE` - in the generated condition. +- `not like`: 生成される条件において `LIKE` が `NOT LIKE` に置き換えられる以外は、`like` 演算子と同じです。 -- `or not like`: similar to the `not like` operator except that `OR` is used to concatenate - the `NOT LIKE` predicates. +- `or not like`: `NOT LIKE` 述語が `OR` によって結合される以外は、`not like` 演算子と同じです。 -- `exists`: requires one operand which must be an instance of [[yii\db\Query]] representing the sub-query. - It will build a `EXISTS (sub-query)` expression. +- `exists`: 要求される一つだけのオペランドは、サブクエリを表す [[yii\db\Query]] のインスタンスでなければなりません。 + これは `EXISTS (sub-query)` という式を構築します。 -- `not exists`: similar to the `exists` operator and builds a `NOT EXISTS (sub-query)` expression. +- `not exists`: `exists` 演算子と同じで、`NOT EXISTS (sub-query)` という式を構築します。 -Additionally you can specify anything as operator: +これらに加えて、どのようなものでも演算子として指定することが出来ます。 ```php -$userQuery = (new Query)->select('id')->from('user'); -$query->where(['>=', 'id', 10]); +$query->select('id') + ->from('user') + ->where(['>=', 'id', 10]); ``` -It will result in: +これは次の結果になります。 ```sql SELECT id FROM user WHERE id >= 10; ``` -If you are building parts of condition dynamically it's very convenient to use `andWhere()` and `orWhere()`: +条件の一部を動的に構築しようとする場合は、`andWhere()` と `orWhere()` を使うのが非常に便利です。 ```php $status = 10; @@ -286,40 +276,40 @@ if (!empty($search)) { } ``` -In case `$search` isn't empty the following SQL will be generated: +`$search` が空でない場合は次の SQL が生成されます。 ```sql WHERE (`status` = 10) AND (`title` LIKE '%yii%') ``` -#### Building Filter Conditions +#### フィルタの条件を構築する -When building filter conditions based on user inputs, you usually want to specially handle "empty inputs" -by ignoring them in the filters. For example, you have an HTML form that takes username and email inputs. -If the user only enters something in the username input, you may want to build a query that only tries to -match the entered username. You may use the `filterWhere()` method achieve this goal: +ユーザの入力に基づいてフィルタの条件を構築する場合、普通は、「空の入力値」は特別扱いして、フィルタではそれを無視したいものです。 +例えば、ユーザ名とメールアドレスの入力欄を持つ HTML フォームがあるとします。 +ユーザがユーザ名の入力欄のみに何かを入力した場合は、入力されたユーザ名だけを検索条件とするクエリを作成したいでしょう。 +この目的を達するために `filterWhere()` メソッドを使うことが出来ます。 ```php -// $username and $email are from user inputs +// $username と $email はユーザの入力による $query->filterWhere([ 'username' => $username, 'email' => $email, ]); ``` -The `filterWhere()` method is very similar to `where()`. The main difference is that `filterWhere()` -will remove empty values from the provided condition. So if `$email` is "empty", the resulting query -will be `...WHERE username=:username`; and if both `$username` and `$email` are "empty", the query -will have no `WHERE` part. +`filterWhere()` メソッドは `where()` と非常によく似ています。 +主な相違点は、`filterWhere()` は与えられた条件から空の値を削除する、ということです。 +従って、`$email` が「空」である場合は、結果として生成されるクエリは `...WHERE username=:username` となります。 +そして、`$username` と `$email` が両方とも「空」である場合は、クエリは `WHERE` の部分を持ちません。 -A value is *empty* if it is null, an empty string, a string consisting of whitespaces, or an empty array. +値が *空* であるのは、null、空文字列、空白文字だけの文字列、または、空配列である場合です。 -You may also use `andFilterWhere()` and `orFilterWhere()` to append more filter conditions. +フィルタの条件を追加するために、`andFilterWhere()` と `orFilterWhere()` を使うことも出来ます。 ### `ORDER BY` -For ordering results `orderBy` and `addOrderBy` could be used: +結果を並び替えるために `orderBy` と `addOrderBy` を使うことが出来ます。 ```php $query->orderBy([ @@ -328,38 +318,38 @@ $query->orderBy([ ]); ``` -Here we are ordering by `id` ascending and then by `name` descending. +ここでは `id` の昇順、`name` の降順で並べ替えています。 -### `GROUP BY` and `HAVING` +### `GROUP BY` と `HAVING` -In order to add `GROUP BY` to generated SQL you can use the following: +生成される SQL に `GROUP BY` を追加するためには、次のようにすることが出来ます。 ```php $query->groupBy('id, status'); ``` -If you want to add another field after using `groupBy`: +`groupBy` を使った後に別のフィールドを追加したい場合は、 ```php $query->addGroupBy(['created_at', 'updated_at']); ``` -To add a `HAVING` condition the corresponding `having` method and its `andHaving` and `orHaving` can be used. Parameters -for these are similar to the ones for `where` methods group: +`HAVING` 条件を追加したい場合は、それに対応する `having` メソッドおよび `andHaving` と `orHaving` を使うことが出来ます。 +これらのメソッドのパラメータは、`where` メソッドグループのそれと同様です。 ```php $query->having(['status' => $status]); ``` -### `LIMIT` and `OFFSET` +### `LIMIT` と `OFFSET` -To limit result to 10 rows `limit` can be used: +結果を 10 行に限定したいときは、`limit` を使うことが出来ます。 ```php $query->limit(10); ``` -To skip 100 fist rows use: +最初の 100 行をスキップしたい時は、こうします。 ```php $query->offset(100); @@ -367,13 +357,13 @@ $query->offset(100); ### `JOIN` -The `JOIN` clauses are generated in the Query Builder by using the applicable join method: +適切な結合メソッドを使って、クエリビルダで `JOIN` 句を生成することが出来ます。 - `innerJoin()` - `leftJoin()` - `rightJoin()` -This left join selects data from two related tables in one query: +次の左外部結合では、二つの関連テーブルから一つのクエリでデータを取得しています。 ```php $query->select(['user.name AS author', 'post.title as title']) @@ -381,20 +371,21 @@ $query->select(['user.name AS author', 'post.title as title']) ->leftJoin('post', 'post.user_id = user.id'); ``` -In the code, the `leftJoin()` method's first parameter -specifies the table to join to. The second parameter defines the join condition. +このコードにおいて、`leftJoin()` メソッドの最初のパラメータは、結合するテーブルを指定するものです。 +第二のパラメータは、結合の条件を定義しています。 -If your database application supports other join types, you can use those via the generic `join` method: +データベース製品がその他の結合タイプをサポートしている場合は、汎用の `join` メソッドによってそれを使うことが出来ます。 ```php $query->join('FULL OUTER JOIN', 'post', 'post.user_id = user.id'); ``` -The first argument is the join type to perform. The second is the table to join to, and the third is the condition. +最初のパラメータが実行する結合タイプです。第二は結合するテーブル、第三は結合の条件です。 -Like `FROM`, you may also join with sub-queries. To do so, specify the sub-query as an array -which must contain one element. The array value must be a `Query` object representing the sub-query, -while the array key is the alias for the sub-query. For example, +`FROM` と同様に、サブクエリを結合することも出来ます。 +そのためには、一つの要素を持つ配列としてサブクエリを指定します。 +配列の値はサブクエリを表す `Query` オブジェクトとし、配列のキーはサブクエリのエイリアスとしなければなりません。 +例えば、 ```php $query->leftJoin(['u' => $subQuery], 'u.id=author_id'); @@ -403,8 +394,9 @@ $query->leftJoin(['u' => $subQuery], 'u.id=author_id'); ### `UNION` -`UNION` in SQL adds results of one query to results of another query. Columns returned by both queries should match. -In Yii in order to build it you can first form two query objects and then use `union` method: +SQL における `UNION` は、一つのクエリの結果を別のクエリの結果に追加するものです。 +両方のクエリによって返されるカラムが一致していなければなりません。 +Yii においてこれを構築するためには、最初に二つのクエリオブジェクトを作成し、次に `union` メソッドを使って連結します。 ```php $query = new Query(); @@ -417,15 +409,15 @@ $query->union($anotherQuery); ``` -Batch Query ------------ +バッチクエリ +------------ -When working with large amount of data, methods such as [[yii\db\Query::all()]] are not suitable -because they require loading all data into the memory. To keep the memory requirement low, Yii -provides the so-called batch query support. A batch query makes uses of data cursor and fetches -data in batches. +大量のデータを扱う場合は、[[yii\db\Query::all()]] のようなメソッドは適していません。 +なぜなら、それらのメソッドは、全てのデータをメモリ上に読み込むことを必要とするためです。 +必要なメモリ量を低く抑えるために、Yii はいわゆるバッチクエリのサポートを提供しています。 +バッチクエリはデータカーソルを利用して、バッチモードでデータを取得します。 -Batch query can be used like the following: +バッチクエリは次のようにして使うことが出来ます。 ```php use yii\db\Query; @@ -435,26 +427,26 @@ $query = (new Query()) ->orderBy('id'); foreach ($query->batch() as $users) { - // $users is an array of 100 or fewer rows from the user table + // $users は user テーブルから取得した 100 以下の行の配列 } -// or if you want to iterate the row one by one +// または、一行ずつ反復したい場合は foreach ($query->each() as $user) { - // $user represents one row of data from the user table + // $user は user テーブルから取得した一つの行を表す } ``` -The method [[yii\db\Query::batch()]] and [[yii\db\Query::each()]] return an [[yii\db\BatchQueryResult]] object -which implements the `Iterator` interface and thus can be used in the `foreach` construct. -During the first iteration, a SQL query is made to the database. Data are since then fetched in batches -in the iterations. By default, the batch size is 100, meaning 100 rows of data are being fetched in each batch. -You can change the batch size by passing the first parameter to the `batch()` or `each()` method. +[[yii\db\Query::batch()]] メソッドと [[yii\db\Query::each()]] メソッドは [[yii\db\BatchQueryResult]] オブジェクトを返します。 +このオブジェクトは `Iterator` インタフェイスを実装しており、従って、`foreach` 構文の中で使うことが出来ます。 +初回の反復の際に、データベースに対する SQL クエリが作成されます。データは、その後、反復のたびにバッチモードで取得されます。 +既定では、バッチサイズは 100 であり、各バッチにおいて 100 行のデータが取得されます。 +`batch()` または `each()` メソッドに最初のパラメータを渡すことによって、バッチサイズを変更することが出来ます。 -Compared to the [[yii\db\Query::all()]], the batch query only loads 100 rows of data at a time into the memory. -If you process the data and then discard it right away, the batch query can help keep the memory usage under a limit. +[[yii\db\Query::all()]] とは対照的に、バッチクエリは一度に 100 行のデータしかメモリに読み込みません。 +データを処理した後、すぐにデータを破棄するようにすれば、バッチクエリの助けを借りてメモリ消費量を限度以下に抑えることが出来ます。 -If you specify the query result to be indexed by some column via [[yii\db\Query::indexBy()]], the batch query -will still keep the proper index. For example, +[[yii\db\Query::indexBy()]] によってクエリ結果をあるカラムでインデックスするように指定している場合でも、バッチクエリは正しいインデックスを保持します。 +例えば、 ```php use yii\db\Query; @@ -464,7 +456,7 @@ $query = (new Query()) ->indexBy('username'); foreach ($query->batch() as $users) { - // $users is indexed by the "username" column + // $users は "username" カラムでインデックスされている } foreach ($query->each() as $username => $user) {