堅牢な Symfony プロジェクトを構築する過程では、findBy() のような単純な Entity Repository メソッドでは十分ではなくなることがよくあります。私にとってその時点に到達し、より複雑なデータ取得のニーズに対処するためにカスタム DQL クエリの力に到達しました。当時、私はデフォルトのデータベースとして MySQL を使用していました。プロジェクトをコンテナ化し、パフォーマンスと機能の柔軟性を確保するために PostgreSQL に切り替えることにするまでは、すべてが完璧に機能していました。
でも、いやいや!私の DQL クエリはすぐにエラーをスローし始めました ??。何が間違っていたのでしょうか?私のカスタム DQL 構文は、MySQL の癖や機能に合わせて完璧に作成されていましたが、PostgreSQL とは互換性がありませんでした。選択は 2 つの困難な道の間で行われました:
オプション 1: MySQL に戻して安全を確保します。
しかし、PostgreSQL を好む開発者とプロジェクトを共有したい場合はどうすればよいでしょうか?
オプション 2: PostgreSQL をサポートするように DQL を書き換えます。
しかし、後で MySQL に戻す必要がある場合はどうすればよいでしょうか?あるいは、MySQL のみをサポートするツールを使用したらどうなるでしょうか?
これらのいずれかを選択するのは簡単ではありませんでした。両方のオプションを選択すると、私は単一のデータベース環境に閉じ込められ、将来の技術選択の柔軟性が制限される可能性があります。そこで、私は別のアプローチを取ることにし、クリーンで再利用可能な方法でデータベース固有のクエリを動的に処理するソリューションを作成しました。
DoctrineExpression は、Symfony または Doctrine を利用するプロジェクトで、クロスプラットフォームでデータベースに依存しない DQL および SQL クエリを有効にするように設計された PHP ライブラリです。 DoctrineExpression を使用すると、各データベース プラットフォーム (MySQL、PostgreSQL、SQLite など) のカスタム構文を定義でき、現在のデータベース ドライバーに基づいて正しい式が選択されます。次のように動作します:
DoctrineExpression を使用すると、MySQL または PostgreSQL (または SQLite) を柔軟に使用できるようになり、コードをクリーンで保守しやすく保つことができます。すべてのカスタム クエリのリファクタリングを心配することなく、プロジェクトの要件、チームの好み、パフォーマンスの考慮事項に基づいてプラットフォームを切り替えることができます。
過去 24 時間以内に登録したユーザーを取得する必要がある簡単な例を見てみましょう。これは、MySQL と PostgreSQL では異なる方法で処理されることがよくあります。
DoctrineExpression を使用せずにこれらを個別に記述する方法は次のとおりです:
// MySQL Query $mysqlQuery = $entityManager->createQuery( "SELECT u FROM App\Entity\User u WHERE u.registeredAt > DATE_SUB(NOW(), INTERVAL 1 DAY)" );
PostgreSQL を使用している場合は、次の形式で記述します。
// PostgreSQL Query $postgresQuery = $entityManager->createQuery( "SELECT u FROM App\Entity\User u WHERE u.registeredAt > NOW() - INTERVAL '1 day'" );
データベースを切り替える場合は、このコードを変更する必要がありますが、不便でエラーが発生しやすくなります。
DoctrineExpression を使用すると、両方の構文を定義し、残りはライブラリに処理させます。
use Ucscode\DoctrineExpression\DoctrineExpression; use Ucscode\DoctrineExpression\DriverEnum; // Create an expression instance with an EntityManager argument $expression = new DoctrineExpression($entityManager); // Registration S/DQL for varying database $expression ->defineQuery(DriverEnum::PDO_MYSQL, function($entityManager) { return $entityManager->createQuery( "SELECT u FROM App\Entity\User u WHERE u.registeredAt > DATE_SUB(NOW(), INTERVAL 1 DAY)" ); }) ->defineQuery(DriverEnum::PDO_PGSQL, function($entityManager) { return $entityManager->createQuery( "SELECT u FROM App\Entity\User u WHERE u.registeredAt > NOW() - INTERVAL '1 day'" ); }); // Fet any of the defined query based on the active doctine driver being used $query = $expression->getCompatibleResult();
DoctrineExpression は使用中のデータベース プラットフォームをチェックし、現在の環境に合わせた正しい構文を動的に挿入します。 MySQL か PostgreSQL を使用しているかはもう問題ではありません。正しい式が選択されるため、プラットフォームを切り替えるたびにクエリを変更する必要がなくなり、if-else を繰り返し使用する定型文も削除されます
DoctrineExpression を使用すると、クエリを書き直さずにさまざまなデータベースを使用できるため、時間と労力を節約できます。これは、カスタム構文を使用する必要があるものの、展開のニーズやチームの慣れに応じてデータベースの設定が変わる可能性がある、コンテナ化されたプロジェクトや複数環境のプロジェクトで特に役立ちます。試してみて、どのように機能するか教えてください!
GitHub で DoctrineExpression をチェックしてください
コーディングを楽しんでください!
以上がDoctrineExpression を使用して異なるデータベース エンジンでカスタム S/DQL クエリを処理する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。