私は過去に似たようなことを数回しました。いくつかの大きなことが頭に浮かびます..
- where 句は、正しく理解するのが最も困難です。私が「式」と「述語」と呼ぶものに分ければ、簡単になります。
- 式 - 列参照、パラメーター、リテラル、関数、集計 (カウント/合計)
- 述語 - like、between、in、is null の比較 (述語には式が子として含まれます。たとえば、expr1 = expr2 です。次に、and/or/not などの複合語もあります。
- ご想像のとおり、where 句全体は、ルートに述語があり、その下におそらくサブ述語があり、最終的に葉の式で終了するツリーです。
- HQL を構築するには、モデルをウォークします (通常は最初に深さ)。他の理由でモデルをウォークする必要があるため、ビジターを使用しましたが、複数の目的がない場合は、レンダリング コードをモデルに直接組み込むことができます。
たとえば、あなたが持っていた場合
"where upper(column1) = :param1 AND ( column2 is null OR column3 between :param2 and param3)"
すると木は
根
- と
- 同等
- 機能(上)
- 列参照 (列 1)
- パラメータ(param1)
- また
- 無効です
- 列参照 (列 2)
- 間
- 列参照 (列 3)
- パラメータ(param2)
- パラメータ(param3)
次に、最初にツリーの深さをたどり、途中でレンダリングされた HQL のビットをマージします。たとえば、上の関数は、子 HQL の 1 つの部分がレンダリングされることを期待し、それを生成します。
"upper( " + childHql + " )"
それを親に渡します。Between のようなものは、3 つの子 HQL ピースを想定しています。
その後、select/group by/order by 句で式モデルを再利用できます。
必要に応じて、select を保存するだけでグループの保存をスキップし、集計のクエリ構築スキャンをスキップできます。1 つ以上ある場合は、すべての非集計選択式を group by にコピーします。
From 句は、テーブル参照 + ゼロ個以上の結合句の単なるリストです。各結合句には、タイプ (内部/左/右) とテーブル参照があります。テーブル参照は、テーブル名 + オプションのエイリアスです。
さらに、クエリ言語 (または実際には何か) を解析したい場合は、ANTLRを強くお勧めします。学習曲線はかなり急ですが、見るべき文法例がたくさんあります。
HTH。