ホームページ  >  記事  >  バックエンド開発  >  DoctrineExpression を使用して異なるデータベース エンジンでカスタム S/DQL クエリを処理する方法

DoctrineExpression を使用して異なるデータベース エンジンでカスタム S/DQL クエリを処理する方法

Mary-Kate Olsen
Mary-Kate Olsenオリジナル
2024-10-28 08:45:02601ブラウズ

How To Handle Custom S/DQL Queries On Different Database Engine with DoctrineExpression

堅牢な Symfony プロジェクトを構築する過程では、findBy() のような単純な Entity Repository メソッドでは十分ではなくなることがよくあります。私にとってその時点に到達し、より複雑なデータ取得のニーズに対処するためにカスタム DQL クエリの力に到達しました。当時、私はデフォルトのデータベースとして MySQL を使用していました。プロジェクトをコンテナ化し、パフォーマンスと機能の柔軟性を確保するために PostgreSQL に切り替えることにするまでは、すべてが完璧に機能していました。

でも、いやいや!私の DQL クエリはすぐにエラーをスローし始めました ?‍?。何が間違っていたのでしょうか?私のカスタム DQL 構文は、MySQL の癖や機能に合わせて完璧に作成されていましたが、PostgreSQL とは互換性がありませんでした。選択は 2 つの困難な道の間で行われました:

オプション 1: MySQL に戻して安全を確保します。

しかし、PostgreSQL を好む開発者とプロジェクトを共有したい場合はどうすればよいでしょうか?

オプション 2: PostgreSQL をサポートするように DQL を書き換えます。

しかし、後で MySQL に戻す必要がある場合はどうすればよいでしょうか?あるいは、MySQL のみをサポートするツールを使用したらどうなるでしょうか?

これらのいずれかを選択するのは簡単ではありませんでした。両方のオプションを選択すると、私は単一のデータベース環境に閉じ込められ、将来の技術選択の柔軟性が制限される可能性があります。そこで、私は別のアプローチを取ることにし、クリーンで再利用可能な方法でデータベース固有のクエリを動的に処理するソリューションを作成しました。


DoctrineExpression の紹介

DoctrineExpression は、Symfony または Doctrine を利用するプロジェクトで、クロスプラットフォームでデータベースに依存しない DQL および SQL クエリを有効にするように設計された PHP ライブラリです。 DoctrineExpression を使用すると、各データベース プラットフォーム (MySQL、PostgreSQL、SQLite など) のカスタム構文を定義でき、現在のデータベース ドライバーに基づいて正しい式が選択されます。次のように動作します:

  1. 複数の式を定義: 各データベース ドライバーに異なる構文を記述し、各プラットフォームの機能と特性に一致する一意のクエリを指定します。
  2. 自動ドライバー検出: DoctrineExpression は、使用中の Doctrine プラットフォームをチェックし、MySQL、PostgreSQL、またはその他のサポートされているデータベースに正しい構文を自動的に適用します。
  3. 将来性のある柔軟性: DoctrineExpression はデータベースを簡単に切り替えることができるため、コードの将来性も確保し、大規模な書き換えを行わずに複数のデータベースをサポートできるようにします。

DoctrineExpression を使用すると、MySQL または PostgreSQL (または SQLite) を柔軟に使用できるようになり、コードをクリーンで保守しやすく保つことができます。すべてのカスタム クエリのリファクタリングを心配することなく、プロジェクトの要件、チームの好み、パフォーマンスの考慮事項に基づいてプラットフォームを切り替えることができます。

DoctrineExpression が問題を解決する方法

過去 24 時間以内に登録したユーザーを取得する必要がある簡単な例を見てみましょう。これは、MySQL と PostgreSQL では異なる方法で処理されることがよくあります。


DoctrineExpression なし

  1. MySQL: DATE_SUB(NOW(), INTERVAL 1 DAY) を使用して、過去 24 時間以内のレコードを検索します。
  2. PostgreSQL: 同じクエリに対して NOW() - INTERVAL '1 day' を使用します。

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 を使用する

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 サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。