Nette Database
Nette Databaseは、シンプルさとスマートな機能に重点を置いた、PHP向けの強力でエレガントなデータベース層です。データベースを操作する2つの方法を提供します – アプリケーションの迅速な開発のためのExplorer、またはクエリを直接操作するためのSQLアクセス。
SQLアクセス
- 安全なパラメータ化クエリ
- SQLクエリの形式に対する正確な制御
- 高度な機能を持つ複雑なクエリを作成する場合
- 特定のSQL機能を使用してパフォーマンスを最適化する場合
Explorer
- SQLを書かずに迅速に開発
- テーブル間のリレーションを直感的に操作
- クエリの自動最適化を評価
- データベースを迅速かつ快適に操作するのに適しています
インストール
ライブラリはComposerツールを使用してダウンロードおよびインストールします:
composer require nette/database
サポートされているデータベース
Nette Databaseは以下のデータベースをサポートしています:
データベースサーバ | DSN名 | Explorerでのサポート |
---|---|---|
MySQL (>= 5.1) | mysql | はい |
PostgreSQL (>= 9.0) | pgsql | はい |
Sqlite 3 (>= 3.8) | sqlite | はい |
Oracle | oci | – |
MS SQL (PDO_SQLSRV) | sqlsrv | はい |
MS SQL (PDO_DBLIB) | mssql | – |
ODBC | odbc | – |
データベースへの2つのアプローチ
Nette Databaseは選択肢を提供します:SQLクエリを直接記述する(SQLアクセス)か、自動的に生成させる(Explorer)かです。両方のアプローチが同じタスクをどのように解決するかを見てみましょう:
SQLアクセス – SQLクエリ
// レコードの挿入
$database->query('INSERT INTO books', [
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// レコードの取得: 本の著者
$result = $database->query('
SELECT authors.*, COUNT(books.id) AS books_count
FROM authors
LEFT JOIN books ON authors.id = books.author_id
WHERE authors.active = 1
GROUP BY authors.id
');
// 出力 (最適ではない、N個の追加クエリを生成する)
foreach ($result as $author) {
$books = $database->query('
SELECT * FROM books
WHERE author_id = ?
ORDER BY published_at DESC
', $author->id);
echo "著者 $author->name は $author->books_count 冊の本を書きました:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
Explorerアクセス – SQLの自動生成
// レコードの挿入
$database->table('books')->insert([
'author_id' => $authorId,
'title' => $bookData->title,
'published_at' => new DateTime,
]);
// レコードの取得: 本の著者
$authors = $database->table('authors')
->where('active', 1);
// 出力 (自動的に最適化された2つのクエリのみを生成)
foreach ($authors as $author) {
$books = $author->related('books')
->order('published_at DESC');
echo "著者 $author->name は {$books->count()} 冊の本を書きました:\n";
foreach ($books as $book) {
echo "- $book->title\n";
}
}
ExplorerアクセスはSQLクエリを自動的に生成および最適化します。上記の例では、SQLアクセスはN+1個のクエリ(著者用に1つ、各著者の本用に1つ)を生成しますが、Explorerはクエリを自動的に最適化し、2つだけ実行します – 著者用に1つ、すべての本用に1つです。
両方のアプローチは、必要に応じてアプリケーション内で自由に組み合わせることができます。
接続と設定
データベースに接続するには、Nette\Database\Connectionクラスのインスタンスを作成するだけです:
$database = new Nette\Database\Connection($dsn, $user, $password);
パラメータ $dsn
(データソース名)は、PDOが使用するものと同じです。例:host=127.0.0.1;dbname=test
。失敗した場合、Nette\Database\ConnectionException
例外をスローします。
ただし、より便利な方法はアプリケーション設定を使用することです。ここにdatabase
セクションを追加するだけで、必要なオブジェクトとTracyバーのデータベースパネルが作成されます。
database:
dsn: 'mysql:host=127.0.0.1;dbname=test'
user: root
password: password
その後、接続オブジェクトをDIコンテナからサービスとして取得します。例:
class Model
{
public function __construct(
// または Nette\Database\Explorer
private Nette\Database\Connection $database,
) {
}
}
データベース設定の詳細については、こちらをご覧ください。
Explorerの手動作成
Nette
DIコンテナを使用しない場合は、Nette\Database\Explorer
インスタンスを手動で作成できます:
// データベースへの接続
$connection = new Nette\Database\Connection('mysql:host=127.0.0.1;dbname=mydatabase', 'user', 'password');
// キャッシュ用ストレージ、Nette\Caching\Storage を実装、例:
$storage = new Nette\Caching\Storages\FileStorage('/path/to/temp/dir');
// データベース構造のリフレクションを担当
$structure = new Nette\Database\Structure($connection, $storage);
// テーブル名、カラム名、外部キーのマッピングルールを定義
$conventions = new Nette\Database\Conventions\DiscoveredConventions($structure);
$explorer = new Nette\Database\Explorer($connection, $structure, $conventions, $storage);
接続管理
Connection
オブジェクトを作成すると、接続が自動的に確立されます。接続を遅延させたい場合は、遅延モードを使用します –
これは設定でlazy
を設定するか、次のようにして有効にします:
$database = new Nette\Database\Connection($dsn, $user, $password, ['lazy' => true]);
接続を管理するには、connect()
、disconnect()
、reconnect()
メソッドを使用します。
connect()
は、まだ存在しない場合に接続を作成し、Nette\Database\ConnectionException
例外をスローする可能性があります。disconnect()
は、現在のデータベース接続を切断します。reconnect()
は、データベースへの切断と再接続を実行します。このメソッドもNette\Database\ConnectionException
例外をスローする可能性があります。
さらに、onConnect
イベントを使用して接続に関連するイベントを監視できます。これは、データベースとの接続が確立された後に呼び出されるコールバックの配列です。
// データベースへの接続後に実行されます
$database->onConnect[] = function($database) {
echo "データベースに接続しました";
};
Tracyデバッグバー
Tracyを使用している場合、デバッグバーにデータベースパネルが自動的にアクティブになり、実行されたすべてのクエリ、そのパラメータ、実行時間、およびコード内で呼び出された場所が表示されます。
