2017-03-31 00:49 (by daianji)

プログラム中で、SQLをゴリゴリと文字列に組み込んでしまうと、ちょっとした改造をかけたりした場合に作業範囲の見通しが悪くなるので、ある程度自動的に処理ができるように工夫をしたいと思い、簡単なラッパーを作っています。

たとえば、

 Select A.ID, A.SOMETHING From A inner join B on A.ID = B.ID where B.Name like 'HOGE%' 

なんて感じのSQLはよく出てくると思いますが、テーブルの構造やカラムの名前を変えてしまった時など、一つ一つ探して直すのが大変だったりします。

そこで、テーブル定義の作成をするときに、文字列でCreate文を作るんじゃなくて、

public class A extends Table {

 public Column<Integer> Id;

 public Column<String> Something;

 @Override

public defineColumns(){
this.Id.addRelationWidth(B.class, this.Id);
}

}

public class B extends Table {

public Column<Integer> Id;
public Column<String> Name;
@Override
public defineColumns(){
this.Id.addRelationWith(A.class, this.Id);
}

}

こんな感じであらかじめテーブル定義をクラス化しておいて、テーブルを作成するときは

A a = new A();

B b = new B();

a.create();

b.create();

とやればサーバー上に生成してくれ、 また、必要に応じて

java.sql.ResultSet rs = A.select(

A.Id.setSelection(true),
A.Something.setSelection(true),
B.Name.like("HOGE%")

);

と呼び出したら、内部でシステムが

select A.ID, A.SOMETHING from A inner join B on A.ID = B.ID where B.Name like 'HOGE%';

のような文を生成してSQLを発行し、結果セットを返してくれたららくちんだなと思って始めました。 また、クラスをリファクタリングするだけで名称変更やカラムの型、サイズなどの変更ができるので、中に書いたSQLを追いかける手間が省けます。 そのうえ、Tableの派生クラスにはテーブル生成に必要な情報だけを書くので、クラスをテーブル定義としてそのまま流用できます。

今回の実装では、Javaの流儀を捻じ曲げてpublicな変数を使ったりしていますが(だってカプセル化するといろいろと内部実装が冗長なんだもん)、 つい先日、単純なSQLの自動生成ができるようになったので、ユーザーの権限回りをこの仕組みに入れ替えたりしています。

本システムは、H2DBのみをターゲットとしているので、ほかのRDBのことは考えずにやっています。(たぶんほかでもある程度は動くんじゃないかとは思います。)

でも、こっちに気を取られると本質的に進める必要のある機能実装がおろそかになってしまうでござる。

だれか手伝って~。

Clearfy Business project news list