データベースについて
SymfonyではDoctrine ORM(Object-Relational Mapping)を利用
- https://fadocodecamp.com/running-a-mysql-database-with-docker-compose-a-beginners-guide/
- ORMでありSQL不要
- オブジェクトのメソッドでDB操作
- オブジェクトとRDBを対応付け(マッピング)
Docker
コンテナ型のアプリケーション実行環境
- 仮想環境を作成・配布・実行するプラットフォーム
- アプリケーション管理・デプロイを容易に
- ハードの環境やOSに関係無く開発可能
- 環境のインストール等が不要
コンテナ型
- OSが一つのみ存在しており,OSの中にアプリケーション実行するための領域が複数存在
- 不要になったイメージ(コンテナ)をシステム等やOSに影響を与えず削除できる
- 最小限のLinux環境で動作している
- 複数バージョンを切り替えたりできる
Dockerはアプリケーションを分離して実行できるようにする
- イメージ
- MySQLやPostgresなど(クラスのようなもの)
- コンテナ
- イメージを使用してコンテナを作成(インスタンスのようなもの)
Docker Compose
- マルチコンテナのDockerアプリケーションを実行するツール
- Yamlファイルでアプリケーション作成・管理
SQLサーバを実行・DB作成
composer require symfony/orm-packを実行
- No を選択しないとエラーになった
- service "database" has neither an image nor a build context specified: invalid compose project
docker-compose.yamlを記述し
$docker compose up
実行後,localhost:8080にアクセスできるようになる
- Docker Desktopを起動している必要あり
.envを編集
- DATABASE_URL="mysql://root:root@127.0.0.1:3306/symf6-handson?serverVersion=mariadb-10.8.3&charset=utf8mb4"
- {service}://{user}:{password}@127.0.0.1:{port}(docker-compose.yml)/{server-name}?serverVersion={version}(docker-compose.yml)&charset={charset}
- https://symfony.com/doc/current/doctrine.html#configuring-the-database
config/packages/doctrine.yamlを編集
- server_version: '10.8.3'
symfony console list doctrine
- 一覧表示
DB作成
- symfony console doctrine:database:create
- localhost:8080に追加されているか確認
エンティティ作成
symfony console list make
symfony console make:entity
- エンティティ名を入力しEntity・Repositoryを作成
- カラム名,データタイプ,文字数,Nullable等も入力していく
- ?でヘルプ
Main Types
* string
* text
* boolean
* integer (or smallint, bigint)
* float
Relationships/Associations
* relation (a wizard 🧙 will help you build the relation)
* ManyToOne
* OneToMany
* ManyToMany
* OneToOne
Array/Object Types
* array (or simple_array)
* json
* object
* binary
* blob
Date/Time Types
* datetime (or datetime_immutable)
* datetimetz (or datetimetz_immutable)
* date (or date_immutable)
* time (or time_immutable)
* dateinterval
Other Types
* ascii_string
* decimal
* guid
Entity Class
アノテーションする必要あり
- リポジトリを指定
カラム列
- private定義
- ゲッタ・セッタ定義
ID(主キー)
- #[ORM/Id]
Migration
symfony console make:migration
Next: Review the new migration "migrations/Version20230514045349.php"
Then: Run the migration with php bin/console doctrine:migrations:migrate
See https://symfony.com/doc/current/bundles/DoctrineMigrationsBundle/index.html
Versionxxxx.php
- AbstractMigrationを拡張
- getDescription()
- 行った操作を記述:Ex. Create the micro_post table
- up()
- テーブル作成
- down()
- テーブル破棄
なぜMigrationを行うのか
- DB変更やテーブル追加等した後,アプリがサーバにデプロイする前に,DB変更を適用する
- SQLを手動で実行してログインする必要が発生
- Migrationがなければ,ローカル上で動作していてもサーバ上で手動でプルしたりしないと動作しない
doctorin_migrations.yaml
Migration実行
- symfony console doctrine:migrations:status
- 現在のMigrationの状態が閲覧可能
- symfony console doctrine:migration:migrate
- この状態でhttp://localhost:8080/で確認するとテーブルが反映されている
- doctrine_migration_versionsも作成
- どのMigrationが実行されたか確認
- doctrine_migration_versionsも作成
Migrationを戻すことも可能
- symfony console doctrine:migrations:migrate --help
- symfony console doctrine:migrations:migrate prev で戻す
Repository Class
Fixtures
- データ追加したり任意の箇所にテスト用のデータ作成
- テスト用データやダミーデータ作成に便利
Fixtures 使い方
- composer require --dev orm-fixturesでインストール
- src/DataFixturesの中ののFixturesファイル
- ロードメソッドで作成,新しくEntityを作成しDB保存
- FixturesBundleは特定コマンド実行時に以下のようなコード処理を行うことで新しいダミーデータ作成してDB保存等を行える
- symfony console doctrine:fixtures:load
- また,これは編集済みのデータをリセットも可能
class AppFixtures extends Fixture
{
public function load(ObjectManager $manager): void
{
// Entityインスタンス作成
$product = new Product();
// Entityでのクエリ実行宣言
$product = setItemName('sample');
$manager->persist($product);
// クエリ実行
$manager->flush();
}
}
Doctrineでデータを扱う場合は
- Entity ManagerでPersist Flush
- でDBへ反映
リポジトリ
- データ取得のためのクエリ作成
- DBからデータをフェッチする方法を抽象化
- すでに追加・削除は存在(add(save)/delete)
- 複雑なクエリ例も存在
リポジトリ代表的メソッド
- findAll すべてのレコード取得
- find(1) ID=1のレコード取得
- findOneBy(['title' => 'xxx']) 条件合致レコードを一つ取得
- findBy(['title' => 'xxx']) 条件合致レコードをすべて取得
- 呼び出すとクエリとしてProfilerに記録されるので見てみると良い
- クエリタイムも同様
Auto Fetching Entity
https://symfony.com/doc/current/doctrine.html#fetch-automatically
composer require sensio/framework-extra-bundle
- 単一のEntityをフェッチする,paramコンバーターで可能
#[Route('/micro-post/{post}', name: 'app_micro_post_show')]
public function showOne(MicroPost $post): Response {
dd($post);
}