データベースにデータをポストするプログラムを作成しているときに、よく知っているパターンに遭遇しました。列挙型として機能する、最も可能性が高い(可能性が高い)固定値の短いテーブルです。したがって、Status
という名前の次のテーブルがあるとします。
ステータス ID説明 -------------- 0未処理 1保留中 2処理済み 3エラー
私のプログラムでは、別のテーブルのステータスIDを確認するか、新しいステータスIDでレコードを更新する必要があります。
EnumのステータスIDをハードコードして、誰もデータベースを変更しないことを望みます。または、説明に基づいて値をプリフェッチすることもできます(そのため、代わりにハードコーディングthat)。
Enumとtableの2つを同期させるための正しいアプローチは何でしょうか?
これらのさまざまなステータスがプログラムのロジックに影響を与えると思われるため、プログラム内で列挙型をハードコードします。新しいステータスがある場合、プログラムはこの新しいステータスにどのように反応するはずですか?
データベースはアプリケーションの一部なので、他の人に相談せずにデータベースに影響を与えることは意味がないと思います。
通常、アプリケーションの起動時に、このデータを静的キャッシュ(通常はHashMapなど)に読み込みます。列挙型が何らかの方法で変更されたからといって、再コンパイルする必要がなくなります。
これらはステータスであるため、DBの変更によってプログラムが(少なくとも簡単に)破損しないように、アプリケーションにハードコードする必要があります。追加する必要があるすべてのステータスは、単純にDBに追加するのではなく、最初にコード化する必要があるため、これは重要です。
たとえば、レポートをプルする必要がある場合に備えて、これらのステータス値を正しい説明とともにDBに書き込む必要があります。
通常、DBに接続する小さなコードスニペットがあり、特定のテーブルにリストされているステータスがすべて、メモリにハードコードしたものと同じid/name値を持っていることを確認します。それらが一致しない場合、ソフトウェアの実行を中止します。
必要に応じて、わずかに異なる動作を実装することもできますが、全体的には、これらのステータスをハードコードすることをお勧めします。
私のプロジェクトにも同様の問題があります(レガシーコード、フレイ!)主な問題は、「列挙テーブルは変更されず、コードが壊れるまで変更されない」ということです。私が徐々に移行していることを軽減するための2つの戦略があります。
まず、そして最善のことは、可能な限りこれらの値への直接参照を排除することです。 「なぜenum値を直接使用する必要があるのですか?」多くの場合、これは、コードにハードコードされた仮定が多すぎるか、データに対して過度の操作を実行しようとしていることを示しています。データベースの関係を改善したり、操作されているものを処理するためのより柔軟なコードを作成したりできないかどうかを確認します。
それがうまくいかないときは、プランB:コード生成に行きます。テーブルはめったに変更されず、新しいビルドは定期的に公開されるため、コードジェネレーターは列挙型テーブルを読み取り、列挙型コードを書き込むことができます。この動的に生成されたライブラリは、プロジェクトで使用されます。 DBが変更された場合、次のビルドはコンパイルされません。これは、不可解なランタイムエラーが発生するよりもはるかに優れています。