よく、原稿用紙に書いたら、何枚にもわたるであろう、SQLを書く人がいる。
このようなSQLは、サーバ側の処理を圧迫するし、メモリもいっぱい使う。
*メモリもいっぱい使う理由:複雑なSQLは、作業用のメモリを消費するほか、
その後も結果を保持しておくので=同じSQLが来たとき、早くレスポンスするため)。
なので、こういうSQLはやめて、
・テーブルのDAOは、
(1)テーブルデータそのもの(例:SELECT * FROM 受注データ;)
(2)ないしは、テーブル間でとても結びつきの強いものだけ(受注と受注明細の連結)
(3)上記(1)、(2)に対し、インデックスを張った項目のWHERE句のみ
・SQLは、SQL1つを1クラスとし、そのクラスが、上記DAOを読み込んで実現する
とする。とくに、これに、デザインパターンのVisitorパターンを利用する。
つまり、
●DAOについて
・各DAOは、INSERT,SELECT,UPDATE,DELETEのメソッドを持っている。
ただし、SELECTに関しては、WHERE句しか、対応しない
(あらかじめ関連の強いものは、そのDAOを持っておく。それ以外のJOINは、ここでは許さない。
SUMとかも、ここではしない)
・各DAOは、Acceptorのacceptを実装しておく
acceptの書く内容は、「visitor.visit(this);」だけ
●SQLに該当するもの
・抽象クラスとして、Visitorを用意する
→じつは、こうすると、SQLごとに用意しないといけなくなるので、めんどっちいい。
本当のVisitorパターンは、こうするのかもしれないけれど、普通のクラスでVisitorを
用意しておき、そのクラスでは、
public void visit (各DAOクラス acceptor1 ) { // なにもしない };
というように、何もしないクラスを、DAO分、用意しておく
・SQL1つに対して、実装したVisitorクラスを1つ用意する。以下のような感じ
public class SQL1 extends Visitor { // DAOその1で取ってきたSELECTデータ ResultSet dao1; // DAOその2で取ってきたSELECTデータ ResultSet dao2; : : public SQL1() { DAO1 d1 = new DAO1(); visit(d1); DAO2 d2 = new DAO2(); visit(d2); : : } public void visit ( From句で書かれるDAOその1 acceptor1 ) { //そのDAOのデータを取ってきて、 dao1 = acceptor1.select(); } public void visit ( From句で書かれるDAOその2 acceptor2 ) { //そのDAOのデータを取ってきて、 dao2 = acceptor2.select(); } : : public ResultSet query ( ) { // 上記DAOをもとに、SQLで書きたいような内容を処理して、 // 結果を返す } }
●呼び出すとき
SQL1 sql1= new SQL1();
で、データを読み込むので、あとは、
ResultSet ret=sql1.query();
で結果が返ってくる。
こうやるメリット(NoSQLでも対応できる)とか、
細かな話(トランザクションの実現、条件値をどのように渡すか)
などについては、今時間がないので、別の機会にかきます。