- PR -

DB検索結果をJavaBeans等に取り込む手法

1
投稿者投稿内容
smym
会議室デビュー日: 2003/04/15
投稿数: 5
投稿日時: 2003-04-15 01:49
はじめまして。
 現在、Javaで小さな業務アプリをいくつか作っています。
その中でも頻繁に作るのが、

 1.DB検索
 2.結果をJSPに転送し、表示

 というパターンのものなのですが、DBの検索結果を保持するとき、
皆さんはどうされていますか? 私の場合は下記のように、ListやMapを
メンバ変数に加えておき、DBの検索結果をResultSetから取り出すたびに
自分自身のクラスのインスタンスをNewし、ListやMapに追加しています。

pubilc Test {

String zipcode;
String address;

ArrayList TestList = new ArrayList();

public query(){
....//DB接続&結果セット取得
while(rset.next()){
Test tt = new Test(); //自分自身と同じクラスをnew
tt.setZipcode(rset.getString("zipcode"));
tt.setAddress(rset.getString("address"));
TestList.add(tt); //リストにadd
}
}
}

 DBの検索結果を表示するという処理が、あまりにも当たり前すぎるためか、
最近の雑誌などではあまり見かけません。 周りにJavaを使っている人もいないため、
ずーっと、上記の方法でお手軽に(?)やっているのですが、実際のところ
Javaのベテランの皆さんはどのように検索結果を保持されているのでしょうか?
よりスマートで自然なやり方がありましたら、ご教授ください。


へげもん
ベテラン
会議室デビュー日: 2002/04/14
投稿数: 87
お住まい・勤務地: 埼玉県
投稿日時: 2003-04-15 08:30
まず最低限、
コード:
    ArrayList TestList = new ArrayList(); 


はまずいと思います。

コード:
    ArrayList TestList = null;
    public void query() {
        ...
        TestList = new ArrayList(); 
        ...
    }


にしましょう。ArrayListは結構大きいので、無駄にメモリを消費してしまいます。

また、私なら下記のようにします。
コード:
public class Test {
    public class Row {
        String zipcode; 
        String address; 
        public void setZipcode(String value) { zipCode = value; }
        public void setAddress(String value) { address = value; }
    }
    List rows = new ArrayList();
    public List query() {
        ...
        while ( rset.next() ) {
            Row r = new Row(); 
            r.setZipcode(rset.getString("zipcode")); 
            r.setAddress(rset.getString("address")); 
            rows.add(r);
        }
        return rows;
    }
}

smym
会議室デビュー日: 2003/04/15
投稿数: 5
投稿日時: 2003-04-15 11:01
ご返答ありがとうございます!

 なるほど、そもそもオブジェクトの中に溜め込むというより、メソッド実行時に
返してあげる・・・という形なのですね。
 私はてっきり、オブジェクトの中に溜めてからJSPに送らなければならないとばかり
思っていました。

ありがとうございました!
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2003-04-15 11:27
smymさんのソースを見た瞬間、何をやっているのか理解できず???でした・・・

(1) DB検索という処理を行うクラス。
(2) 一件のデータ(DBのテーブルの1行)を表現するクラス。
(3) 検索結果=(2)の集まり、を表現するクラス。

の3つの役割を一つのクラスに持たせておられるようですが、
(1)と(3)を兼務させるのはまだしも、
(2)と(3)という本来別物のデータを同じクラス表現してしまうのは、
かなりマズイ設計というべきかと。

素直に考えると、
(1) DB検索という処理を行うクラスを作成する。
(2) 一件のデータを表現するクラスを、(1)とは別個に作成する。
(3) 検索結果は、(2)のクラスのListで表現する。
ということで、へげもんさんの後の例のようになるでしょう。

ただし、
(a) public class Row は public static class Row とすべきでは?
(b) List rows は、queryの呼出し毎に新たに作成するようにすべき。
でないと、次回のqueryを呼び出した時点で前回のqueryの結果が書き換えられて
しまって、呼び出し側から見ると不可解な挙動になる。
# DBにアクセスする処理の重さにに比べれば、ArrayListを作成する負担は無視できる。
smym
会議室デビュー日: 2003/04/15
投稿数: 5
投稿日時: 2003-04-15 13:09
引用:

coasmさんの書き込み (2003-04-15 11:27) より:
(2)と(3)という本来別物のデータを同じクラス表現してしまうのは、
かなりマズイ設計というべきかと。



 私も最初はcoasmさんの仰られる通り素直にやってたんです。
 でも、使っていくうちに途中から、「属性値を持ったコンポジットパターンもどき」の
ようなものだと自分勝手に納得して^^;使っていました。
#やはり我流はダメですね。。
 

[ メッセージ編集済み 編集者: smym 編集日時 2003-04-15 13:25 ]
Kensaku
常連さん
会議室デビュー日: 2003/02/16
投稿数: 22
投稿日時: 2003-04-15 23:47
個人的にはListなどのコレクションクラスに値を入れて返すのは、中に何が入っているのかわからないので嫌いなのですが、皆さんはどうですか?
私だったら return (Row[]) rows.toArray(new Row[rows.size()]) でRow[]を返すようにしたいです。
へげもん
ベテラン
会議室デビュー日: 2002/04/14
投稿数: 87
お住まい・勤務地: 埼玉県
投稿日時: 2003-04-16 11:26
coasmさん
引用:

(a) public class Row は public static class Row とすべきでは?
(b) List rows は、queryの呼出し毎に新たに作成するようにすべき。


確かに、(a) に関しては、Rowを親から完全に切り離して使うのならstaticにすべきですね。
一方、(b)に関しては、rowsの寿命次第だと思います。
TestというJavaBeanが単発の検索しか行わないのなら、上書きをしないようにrows==nullでなければ例外を投げるべきでしょうし、複数の検索を行うのなら毎回新規に作成すべきでしょう。

Kensakuさん
引用:
私だったら return (Row[]) rows.toArray(new Row[rows.size()]) でRow[]を返すようにしたいです。


それも一理あると思います。
一方、どんな型でも返せる、というのもメリットになります。たとえば、与えたパラメータに応じて、query()が異なるBeanの入ったListを返してきて、表示側ではリフレクションで属性名と値を取り出す、などの使い方が考えられます。
coasm
大ベテラン
会議室デビュー日: 2001/11/26
投稿数: 237
投稿日時: 2003-04-16 11:39
確かに、C++のList<Rows>のように型の制限が出来ず、Objectなら
何でも入れてしまえるというのはJavaのコレクションAPIの最大の
欠点かも知れません。でもまあ、今のところは問題を意識しつつも
そのまま使う、というのが妥当な線かと考えています。

# C++のように、List<Rows> とか List<String>とか書く毎に新たな
# クラスが出来て、コードサイズが増えていくのも嬉しくない。

こういう話 http://objectclub.esm.co.jp/JavaGenerics
はありますが、「標準」になるまでは手を出したくないし。
1

スキルアップ/キャリアアップ(JOB@IT)