EzJDBCのSQL自動生成機能の弱点と克服方法!
本日は、EzJDBCのSQL自動生成機能の弱点について説明したいと思います。
その弱点とはSQL自動生成機能はSQLのカスタマイズが出来ない事にあります。
例えば、以下の関係の2テーブルが存在したとします。
【テーブル】
1.CUSTOMERテーブル
2.ORDERテーブル【テーブル関係】
1.CUSTOMERテーブル : ORDERテーブル = 1:n【テーブルのレコード数】
1.CUSTOMERテーブル :10万件
2.ORDERテーブル :15万件
この様なテーブル関係で以下の条件にあるデータの照会を行ったとします。
【抽出条件】
1.お客様名(CUSTOMER.NAME)が「TAKAHASHI」で始まるデータのみ抽出【照会内容】
1.お客様名(CUSTOMER.NAME)
2.注文番号(ORDER.NO)
照会する標準的なEzJDBCコードは以下の通りです。
CUSTOMER CS = new CUSTOMER("CS");
Listlist = EzJDBC.selects(CS.name,CS.OD.no).from(CS.OD)
.where(CS.name.like("TAKAHASHI%")).find(Customer.class);
上記コードにより発行されるSQLは以下の通りです。
SELECT
CS.NAME,OD.NO
FROM
CUSTOMER as CS left join ORDER as OD on (CS.ID = OD.CUSTOMER_ID)
WHERE
(CS.NAME like 'TAKAHASHI%')
見て分かる通り非効率です><
【非効率な理由】
上記SQLでは、以下の順番で処理が行われます。
1.CUSTOMERは10件レコードとORDERは15万レコードの結合を行います。
2.結合した結果から対象となるデータを抽出します。
本来であれば、以下の様にSQLをカスタマイズいたくなります(レスポンスが良くなるため)。
SELECT
CS.NAME,OD.NO
FROM
(SELECT
CUSTOMER.NAME
FROM
CUSTOMER
WHERE(CS.NAME like 'TAKAHASHI%')) as CS
left join ORDER as OD on (CS.ID = OD.CUSTOMER_ID)
EzJDBCのSQL自動生成機能には、上記SQLを作成するための機能がありません。
ということで、EzJDBCでは弱点を克服するために以下の対応を追加します。
【対応方法】
抽出条件が指定されたテーブルは、結合前に抽出条件を設定しデータを絞りこんだ後に全体の結合を行うようにする。
と思ったのですが、これだと利用者の考えたとおりSQLが作成されなくなり、混乱を招きかねません。
よって、利用者がEzJDBCに明示的に指定できる方法にしました。
上記カスタマイズを行うSAMPLE CODE
CUSTOMER CS = new CUSTOMER("CS").where(CS.name.like("TAKAHASHI%"));
Listlist = EzJDBC.selects(CS.name,CS.OD.no).from(CS.OD)
.find(Customer.class);
これでEzJDBCのSQL自動生成機能でもSQLレベルのカスタマイズが可能になります。
実装はこれからですが…(^^;)
このネタは、id:dkfjさんが下記のエントリをEzJDBCに置き換えて対応方法を考えてみました
S2JDBCのSQL自動生成で、結合条件を変えたい - プログラマでありたい
S2JDBCのSQL自動生成機能は、基本的に素晴らしいです。はるか昔にHibernateを使った時のもどかしさは、ほとんどありません。ただ、たまーに結合のチューニングしたいなぁと思うことがあります。
中略...