|
|
@ -5,8 +5,8 @@ Built on top of [PDO](http://www.php.net/manual/en/book.pdo.php), Yii DAO (Datab |
|
|
|
object-oriented API for accessing relational databases. It is the foundation for other more advanced database |
|
|
|
object-oriented API for accessing relational databases. It is the foundation for other more advanced database |
|
|
|
access methods, including [query builder](db-query-builder.md) and [active record](db-active-record.md). |
|
|
|
access methods, including [query builder](db-query-builder.md) and [active record](db-active-record.md). |
|
|
|
|
|
|
|
|
|
|
|
When using Yii DAO, you mainly need to deal with plain SQLs and PHP arrays. As a result, it is the most efficient |
|
|
|
When using Yii DAO, you mainly need to deal with plain SQLs and PHP arrays. As a result, it is the most efficient |
|
|
|
way to access databases. However, because SQL syntax may vary for different databases, using Yii DAO also means |
|
|
|
way to access databases. However, because SQL syntax may vary for different databases, using Yii DAO also means |
|
|
|
you have to take extra effort to create a database-agnostic application. |
|
|
|
you have to take extra effort to create a database-agnostic application. |
|
|
|
|
|
|
|
|
|
|
|
Yii DAO supports the following databases out of box: |
|
|
|
Yii DAO supports the following databases out of box: |
|
|
@ -59,10 +59,10 @@ You can then access the DB connection via the expression `Yii::$app->db`. |
|
|
|
|
|
|
|
|
|
|
|
> Tip: You can configure multiple DB application components if your application needs to access multiple databases. |
|
|
|
> Tip: You can configure multiple DB application components if your application needs to access multiple databases. |
|
|
|
|
|
|
|
|
|
|
|
When configuring a DB connection, you should always specify its Data Source Name (DSN) via the [[yii\db\Connection::dsn|dsn]] |
|
|
|
When configuring a DB connection, you should always specify its Data Source Name (DSN) via the [[yii\db\Connection::dsn|dsn]] |
|
|
|
property. The format of DSN varies for different databases. Please refer to the [PHP manual](http://www.php.net/manual/en/function.PDO-construct.php) |
|
|
|
property. The format of DSN varies for different databases. Please refer to the [PHP manual](http://www.php.net/manual/en/function.PDO-construct.php) |
|
|
|
for more details. Below are some examples: |
|
|
|
for more details. Below are some examples: |
|
|
|
|
|
|
|
|
|
|
|
* MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase` |
|
|
|
* MySQL, MariaDB: `mysql:host=localhost;dbname=mydatabase` |
|
|
|
* SQLite: `sqlite:/path/to/database/file` |
|
|
|
* SQLite: `sqlite:/path/to/database/file` |
|
|
|
* PostgreSQL: `pgsql:host=localhost;port=5432;dbname=mydatabase` |
|
|
|
* PostgreSQL: `pgsql:host=localhost;port=5432;dbname=mydatabase` |
|
|
@ -71,6 +71,21 @@ for more details. Below are some examples: |
|
|
|
* MS SQL Server (via mssql driver): `mssql:host=localhost;dbname=mydatabase` |
|
|
|
* MS SQL Server (via mssql driver): `mssql:host=localhost;dbname=mydatabase` |
|
|
|
* Oracle: `oci:dbname=//localhost:1521/mydatabase` |
|
|
|
* Oracle: `oci:dbname=//localhost:1521/mydatabase` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
You can set the [[yii\db\Connection::dsn|dsn]] via configuration array. For example, |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
```php |
|
|
|
|
|
|
|
'db' => [ |
|
|
|
|
|
|
|
'__class' => yii\db\Connection::class, |
|
|
|
|
|
|
|
'dsn' => [ |
|
|
|
|
|
|
|
'driver' => 'mysql', |
|
|
|
|
|
|
|
'host' => 'localhost', |
|
|
|
|
|
|
|
'dbname' => 'example', |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
'username' => 'root', |
|
|
|
|
|
|
|
'password' => '', |
|
|
|
|
|
|
|
], |
|
|
|
|
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
Note that if you are connecting with a database via ODBC, you should configure the [[yii\db\Connection::driverName]] |
|
|
|
Note that if you are connecting with a database via ODBC, you should configure the [[yii\db\Connection::driverName]] |
|
|
|
property so that Yii can know the actual database type. For example, |
|
|
|
property so that Yii can know the actual database type. For example, |
|
|
|
|
|
|
|
|
|
|
@ -85,7 +100,7 @@ property so that Yii can know the actual database type. For example, |
|
|
|
``` |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
Besides the [[yii\db\Connection::dsn|dsn]] property, you often need to configure [[yii\db\Connection::username|username]] |
|
|
|
Besides the [[yii\db\Connection::dsn|dsn]] property, you often need to configure [[yii\db\Connection::username|username]] |
|
|
|
and [[yii\db\Connection::password|password]]. Please refer to [[yii\db\Connection]] for the full list of configurable properties. |
|
|
|
and [[yii\db\Connection::password|password]]. Please refer to [[yii\db\Connection]] for the full list of configurable properties. |
|
|
|
|
|
|
|
|
|
|
|
> Info: When you create a DB connection instance, the actual connection to the database is not established until |
|
|
|
> Info: When you create a DB connection instance, the actual connection to the database is not established until |
|
|
|
you execute the first SQL or you call the [[yii\db\Connection::open()|open()]] method explicitly. |
|
|
|
you execute the first SQL or you call the [[yii\db\Connection::open()|open()]] method explicitly. |
|
|
@ -94,7 +109,7 @@ and [[yii\db\Connection::password|password]]. Please refer to [[yii\db\Connectio |
|
|
|
> some environment variables (e.g., to set the timezone or character set). You can do so by registering an event handler |
|
|
|
> some environment variables (e.g., to set the timezone or character set). You can do so by registering an event handler |
|
|
|
> for the [[yii\db\Connection::EVENT_AFTER_OPEN|afterOpen]] event |
|
|
|
> for the [[yii\db\Connection::EVENT_AFTER_OPEN|afterOpen]] event |
|
|
|
> of the database connection. You may register the handler directly in the application configuration like so: |
|
|
|
> of the database connection. You may register the handler directly in the application configuration like so: |
|
|
|
> |
|
|
|
> |
|
|
|
> ```php |
|
|
|
> ```php |
|
|
|
> 'db' => [ |
|
|
|
> 'db' => [ |
|
|
|
> // ... |
|
|
|
> // ... |
|
|
@ -109,13 +124,13 @@ and [[yii\db\Connection::password|password]]. Please refer to [[yii\db\Connectio |
|
|
|
## Executing SQL Queries <span id="executing-sql-queries"></span> |
|
|
|
## Executing SQL Queries <span id="executing-sql-queries"></span> |
|
|
|
|
|
|
|
|
|
|
|
Once you have a database connection instance, you can execute a SQL query by taking the following steps: |
|
|
|
Once you have a database connection instance, you can execute a SQL query by taking the following steps: |
|
|
|
|
|
|
|
|
|
|
|
1. Create a [[yii\db\Command]] with a plain SQL query; |
|
|
|
1. Create a [[yii\db\Command]] with a plain SQL query; |
|
|
|
2. Bind parameters (optional); |
|
|
|
2. Bind parameters (optional); |
|
|
|
3. Call one of the SQL execution methods in [[yii\db\Command]]. |
|
|
|
3. Call one of the SQL execution methods in [[yii\db\Command]]. |
|
|
|
|
|
|
|
|
|
|
|
The following example shows various ways of fetching data from a database: |
|
|
|
The following example shows various ways of fetching data from a database: |
|
|
|
|
|
|
|
|
|
|
|
```php |
|
|
|
```php |
|
|
|
// return a set of rows. each row is an associative array of column names and values. |
|
|
|
// return a set of rows. each row is an associative array of column names and values. |
|
|
|
// an empty array is returned if the query returned no results |
|
|
|
// an empty array is returned if the query returned no results |
|
|
@ -158,7 +173,7 @@ In the SQL statement, you can embed one or multiple parameter placeholders (e.g. |
|
|
|
placeholder should be a string starting with a colon. You may then call one of the following parameter binding methods |
|
|
|
placeholder should be a string starting with a colon. You may then call one of the following parameter binding methods |
|
|
|
to bind the parameter values: |
|
|
|
to bind the parameter values: |
|
|
|
|
|
|
|
|
|
|
|
* [[yii\db\Command::bindValue()|bindValue()]]: bind a single parameter value |
|
|
|
* [[yii\db\Command::bindValue()|bindValue()]]: bind a single parameter value |
|
|
|
* [[yii\db\Command::bindValues()|bindValues()]]: bind multiple parameter values in one call |
|
|
|
* [[yii\db\Command::bindValues()|bindValues()]]: bind multiple parameter values in one call |
|
|
|
* [[yii\db\Command::bindParam()|bindParam()]]: similar to [[yii\db\Command::bindValue()|bindValue()]] but also |
|
|
|
* [[yii\db\Command::bindParam()|bindParam()]]: similar to [[yii\db\Command::bindValue()|bindValue()]] but also |
|
|
|
support binding parameter references. |
|
|
|
support binding parameter references. |
|
|
@ -171,7 +186,7 @@ $params = [':id' => $_GET['id'], ':status' => 1]; |
|
|
|
$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status') |
|
|
|
$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status') |
|
|
|
->bindValues($params) |
|
|
|
->bindValues($params) |
|
|
|
->queryOne(); |
|
|
|
->queryOne(); |
|
|
|
|
|
|
|
|
|
|
|
$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status', $params) |
|
|
|
$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status', $params) |
|
|
|
->queryOne(); |
|
|
|
->queryOne(); |
|
|
|
``` |
|
|
|
``` |
|
|
@ -203,9 +218,9 @@ $post2 = $command->queryOne(); |
|
|
|
// ... |
|
|
|
// ... |
|
|
|
``` |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
Notice that you bind the placeholder to the `$id` variable before the execution, and then change the value of that variable |
|
|
|
Notice that you bind the placeholder to the `$id` variable before the execution, and then change the value of that variable |
|
|
|
before each subsequent execution (this is often done with loops). Executing queries in this manner can be vastly |
|
|
|
before each subsequent execution (this is often done with loops). Executing queries in this manner can be vastly |
|
|
|
more efficient than running a new query for every different parameter value. |
|
|
|
more efficient than running a new query for every different parameter value. |
|
|
|
|
|
|
|
|
|
|
|
> Info: Parameter binding is only used in places where values need to be inserted into strings that contain plain SQL. |
|
|
|
> Info: Parameter binding is only used in places where values need to be inserted into strings that contain plain SQL. |
|
|
|
> In many places in higher abstraction layers like [query builder](db-query-builder.md) and [active record](db-active-record.md) |
|
|
|
> In many places in higher abstraction layers like [query builder](db-query-builder.md) and [active record](db-active-record.md) |
|
|
@ -280,7 +295,7 @@ When writing database-agnostic code, properly quoting table and column names is |
|
|
|
different databases have different name quoting rules. To overcome this problem, you may use the following |
|
|
|
different databases have different name quoting rules. To overcome this problem, you may use the following |
|
|
|
quoting syntax introduced by Yii: |
|
|
|
quoting syntax introduced by Yii: |
|
|
|
|
|
|
|
|
|
|
|
* `[[column name]]`: enclose a column name to be quoted in double square brackets; |
|
|
|
* `[[column name]]`: enclose a column name to be quoted in double square brackets; |
|
|
|
* `{{table name}}`: enclose a table name to be quoted in double curly brackets. |
|
|
|
* `{{table name}}`: enclose a table name to be quoted in double curly brackets. |
|
|
|
|
|
|
|
|
|
|
|
Yii DAO will automatically convert such constructs into the corresponding quoted column or table names using the |
|
|
|
Yii DAO will automatically convert such constructs into the corresponding quoted column or table names using the |
|
|
@ -330,7 +345,7 @@ $count = Yii::$app->db->createCommand("SELECT COUNT([[id]]) FROM {{%employee}}") |
|
|
|
When running multiple related queries in a sequence, you may need to wrap them in a transaction to ensure the integrity |
|
|
|
When running multiple related queries in a sequence, you may need to wrap them in a transaction to ensure the integrity |
|
|
|
and consistency of your database. If any of the queries fails, the database will be rolled back to the state as if |
|
|
|
and consistency of your database. If any of the queries fails, the database will be rolled back to the state as if |
|
|
|
none of these queries were executed. |
|
|
|
none of these queries were executed. |
|
|
|
|
|
|
|
|
|
|
|
The following code shows a typical way of using transactions: |
|
|
|
The following code shows a typical way of using transactions: |
|
|
|
|
|
|
|
|
|
|
|
```php |
|
|
|
```php |
|
|
@ -350,7 +365,7 @@ try { |
|
|
|
$db->createCommand($sql1)->execute(); |
|
|
|
$db->createCommand($sql1)->execute(); |
|
|
|
$db->createCommand($sql2)->execute(); |
|
|
|
$db->createCommand($sql2)->execute(); |
|
|
|
// ... executing other SQL statements ... |
|
|
|
// ... executing other SQL statements ... |
|
|
|
|
|
|
|
|
|
|
|
$transaction->commit(); |
|
|
|
$transaction->commit(); |
|
|
|
} catch(\Exception $e) { |
|
|
|
} catch(\Exception $e) { |
|
|
|
$transaction->rollBack(); |
|
|
|
$transaction->rollBack(); |
|
|
@ -369,7 +384,7 @@ will be triggered and caught, the [[yii\db\Transaction::rollBack()|rollBack()]] |
|
|
|
the changes made by the queries prior to that failed query in the transaction. `throw $e` will then re-throw the |
|
|
|
the changes made by the queries prior to that failed query in the transaction. `throw $e` will then re-throw the |
|
|
|
exception as if we had not caught it, so the normal error handling process will take care of it. |
|
|
|
exception as if we had not caught it, so the normal error handling process will take care of it. |
|
|
|
|
|
|
|
|
|
|
|
> Note: in the above code we have two catch-blocks for compatibility |
|
|
|
> Note: in the above code we have two catch-blocks for compatibility |
|
|
|
> with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](http://php.net/manual/en/class.throwable.php) |
|
|
|
> with PHP 5.x and PHP 7.x. `\Exception` implements the [`\Throwable` interface](http://php.net/manual/en/class.throwable.php) |
|
|
|
> since PHP 7.0, so you can skip the part with `\Exception` if your app uses only PHP 7.0 and higher. |
|
|
|
> since PHP 7.0, so you can skip the part with `\Exception` if your app uses only PHP 7.0 and higher. |
|
|
|
|
|
|
|
|
|
|
@ -385,7 +400,7 @@ $isolationLevel = \yii\db\Transaction::REPEATABLE_READ; |
|
|
|
Yii::$app->db->transaction(function ($db) { |
|
|
|
Yii::$app->db->transaction(function ($db) { |
|
|
|
.... |
|
|
|
.... |
|
|
|
}, $isolationLevel); |
|
|
|
}, $isolationLevel); |
|
|
|
|
|
|
|
|
|
|
|
// or alternatively |
|
|
|
// or alternatively |
|
|
|
|
|
|
|
|
|
|
|
$transaction = Yii::$app->db->beginTransaction($isolationLevel); |
|
|
|
$transaction = Yii::$app->db->beginTransaction($isolationLevel); |
|
|
@ -423,7 +438,7 @@ If your DBMS supports Savepoint, you may nest multiple transactions like the fol |
|
|
|
```php |
|
|
|
```php |
|
|
|
Yii::$app->db->transaction(function ($db) { |
|
|
|
Yii::$app->db->transaction(function ($db) { |
|
|
|
// outer transaction |
|
|
|
// outer transaction |
|
|
|
|
|
|
|
|
|
|
|
$db->transaction(function ($db) { |
|
|
|
$db->transaction(function ($db) { |
|
|
|
// inner transaction |
|
|
|
// inner transaction |
|
|
|
}); |
|
|
|
}); |
|
|
@ -575,7 +590,7 @@ You can also configure multiple masters with multiple slaves. For example, |
|
|
|
``` |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
The above configuration specifies two masters and four slaves. The `Connection` component also supports |
|
|
|
The above configuration specifies two masters and four slaves. The `Connection` component also supports |
|
|
|
load balancing and failover between masters just as it does between slaves. A difference is that when none |
|
|
|
load balancing and failover between masters just as it does between slaves. A difference is that when none |
|
|
|
of the masters are available an exception will be thrown. |
|
|
|
of the masters are available an exception will be thrown. |
|
|
|
|
|
|
|
|
|
|
|
> Note: When you use the [[yii\db\Connection::masters|masters]] property to configure one or multiple |
|
|
|
> Note: When you use the [[yii\db\Connection::masters|masters]] property to configure one or multiple |
|
|
@ -668,5 +683,5 @@ $table = Yii::$app->db->getTableSchema('post'); |
|
|
|
``` |
|
|
|
``` |
|
|
|
|
|
|
|
|
|
|
|
The method returns a [[yii\db\TableSchema]] object which contains the information about the table's columns, |
|
|
|
The method returns a [[yii\db\TableSchema]] object which contains the information about the table's columns, |
|
|
|
primary keys, foreign keys, etc. All these information are mainly utilized by [query builder](db-query-builder.md) |
|
|
|
primary keys, foreign keys, etc. All these information are mainly utilized by [query builder](db-query-builder.md) |
|
|
|
and [active record](db-active-record.md) to help you write database-agnostic code. |
|
|
|
and [active record](db-active-record.md) to help you write database-agnostic code. |
|
|
|