- PR -

DBの検索結果を親子関係にして取得したいです・・・

投稿者投稿内容
ヒロポン
会議室デビュー日: 2004/03/02
投稿数: 6
投稿日時: 2004-03-30 10:29

こんにちわ。今、web開発を行っています。
そこで、どうしてもつまずいていまして投稿させて
もらいました・・・。

DBからの検索結果を、while(rs.next())の中で
親子関係のオブジェクトで取得したいのです。

DBの項目でコードという項目が4種類あります。
firstCode、secondCode、thirdCode、fourthCodeです。
いずれも桁数は2桁になっています。
SQLのselect文では、order by firstCode、secondCode、thirdCode、fourthCodeで
ソートをかけています。

親子関係というのは、コードに対しての親子関係です。
SQLの検索結果では、コードの順番が必ず下記のようになります。

00000000 ----->1(全てのコードの親(root))
01000000 ----->2(3と7の親)
01010000 ----->3(4の親)
01010100 ----->4(5と6の親)
01010101 ----->5(4の子供)
01000002 ----->6(4の子供)
01020000 ----->7(8の親)
01020100 ----->8(9と10の親)
01020101 ----->9(8の子供)
01020101 ----->10(8の子供)

わかりずらいかと思いますが、
1番目のrootは全てのコードを子供として参照でき、全ての
子供を参照できます。
2番目のコードは3と7を子供として参照でき、3と7以下の
子供を全て参照できます。
逆に3と7は2番目のコードを親として参照できるような
かたちで取得したいのです。

親子関係はこんな感じです。

root 1階層 2階層 3階層 4階層
↓ ↓ ↓ ↓ ↓
1 ---- 2 ----- 3 ----- 4 ----- 5
| |
| ------- 6
|
------- 7 ----- 8 ----- 9
|
------- 10

このような親子関係で検索結果を取得したいです・・・。

仮にrootから全ての子供を取得したい時はgetChildren()というメソッド
でListで取得できるようにはしてあります。

私の考えでwhile(rs.next)の中で4重ループすれば
いいのかな?って思いましたがいまいち書き方がわかりません。

----------------------------------------------------
stmt = context.getPreparedStatement(sql);

Object root = new Object();
Object first = new Object();

/** SQLを実行 */
rs = stmt.executeQuery();

/**要素の個数分繰り返す**/
while(rs.next()){

if(rs.getString("firstCode").equals("00") && rs.getString("secondCode").equals("00") && rs.getString("thirdCode").equals("00") && rs.getString("fourthCode").equals("00")) {

root = (WorkClassification) construct(rs, 0); <----- constructというメソッドで検索結果をsetして、その返り値(検索結果)がrootにはいります。
WorkClassificationlist.add(root); <----- listに最初のデータを加えます。

} else if(rs.getString("firstCode").equals("01") && rs.getString("secondCode").equals("00") && rs.getString("thirdCode").equals("00") && rs.getString("fourthCode").equals("00")){

first1 = (WorkClassification) construct(rs, 0); <---- 上記と同様
root.addChild(first1); <--- rootの子供がfirst1になるようにlistの形でset。
}

非常にわかりずらくて申し訳ないですが、おわかりになる方が
いらっしゃれば、ご教授頂きたいと思います。
宜しくお願いします。





顔爺
ベテラン
会議室デビュー日: 2003/10/03
投稿数: 52
投稿日時: 2004-03-30 10:44
データ構造を Composite パターンを使って実装するのが妥当だと思います。
http://www.google.co.jp/search?hl=ja&ie=UTF-8&oe=UTF-8&q=Composite+%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3&btnG=%E6%A4%9C%E7%B4%A2&lr=lang_ja
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2004-03-30 11:37
説明が要領を得ないと感じましたが、そもそもサンプルデータ自体が間違っていませんか?
以下、コード間をカンマで区切り、書籍の章立てと対比して説明します。

00,00,00,00 -> root
01,00,00,00 -> 1章
01,01,00,00 -> 1.1 節
01,01,01,00 -> 1.1.1 節
01,01,01,01 -> 1.1.1.1 節
01,01,01,02 -> 1.1.1.2 節
01,02,00,00 -> 1.2 節
01,02,01,00 -> 1.2.1 節
01,02,01,01 -> 1.2.1.1 節
01,02,01,02 -> 1.2.1.2 節

データ構造は普通の多進木ですね。
処理としては、各章・節ノードを保持しておき、節番号が変わる時に対応するノードオブジェクトを生成し、親ノードに対して子として登録する方法でできると思います。
段数が可変などの拡張性を考えているならば、顔爺さんの書かれた通り、GoF Composite パターンを使って実装することを、私もお勧めします。
簡単な再帰処理を使うことになるかもしれませんが、ループは while(rs.next()) {...} の 1 重で充分です。

4 段固定で拡張は今後絶対にないというのであれば、再帰も必要ないでしょう。
(コードの見通しは悪くなるかもしれませんが)
CHN
ぬし
会議室デビュー日: 2002/03/07
投稿数: 382
投稿日時: 2004-03-30 11:59
こんにちは。
私もGioさんと同じ意見です。
データ構造を見直した方がいいように思いました。
どうしても、提示されたようなデータでやりたいなら
SQL自体で架空の列を作ったりして、やるのが普通かな?
コードでやるのはあまりスマートではないような気がします。
_________________
ヒロポン
会議室デビュー日: 2004/03/02
投稿数: 6
投稿日時: 2004-03-30 13:00
CHNさん、Gioさん、顔爺さん

ご回答ありがとうございました!

ループは1重で大丈夫ということですが、
10種類のコードがあるので、オブジェクトも
10個作ったほうがいいのでしょうか??

仕様上の問題で、コードで行わなければならないので。

また、while(rs.next()){・・・・}の
書き方をどのようにしていいのか、具体的に
教えて頂けると、幸いです。

勝手で申し訳ないですが簡単なサンプルコードなど、
教えて頂けるとうれしいです。


CHN
ぬし
会議室デビュー日: 2002/03/07
投稿数: 382
投稿日時: 2004-03-30 15:55
引用:

また、while(rs.next()){・・・・}の
書き方をどのようにしていいのか、具体的に
教えて頂けると、幸いです。

勝手で申し訳ないですが簡単なサンプルコードなど、
教えて頂けるとうれしいです。


きもちはわかりますが、行き詰ったところを自分で
やってのけたことがとても自信になります。
最初はむりやりでもいいです、2、3回で賢くなりますよ。
あと、正直サンプルは面倒です。

#俺なんかすっげー頭悪いです。
#それでもむりやりやってまっせ。
#頑張りましょう!
_________________
世界平和を願う!
http://park8.wakwak.com/~chin/

[ メッセージ編集済み 編集者: CHN 編集日時 2004-03-30 16:05 ]
Gio
ぬし
会議室デビュー日: 2003/11/28
投稿数: 350
お住まい・勤務地: 都内から横浜の間に少量発生中
投稿日時: 2004-03-30 16:17
まずサンプルデータに誤りがないのか答えていただけますか。
よんどさんが示されたデータでは、6番の第2コードと第3コードが0になっている点、および、9番と10番のデータが完全に同じになっている点が非常に不自然で一貫性がありません。

コードが 10 種類あるということですが、それではますますコードを別個のデータとして扱うと非常にクレイジーなプログラムになります。子ノードのリストと親ノードへのリンクを持つクラスを設け、すべてのコードはそのクラスのオブジェクトして扱うべきでしょう。
(というのを具体的にどういう形で表現するかということが GoF Composite パターンに書いてあります。示された情報はきちんと調べて読んでくださいね。)

あと、サンプルコードを示して欲しいというのは、私から見ると非常に身勝手に感じます。
顔爺さんや CHN さんが適切な情報を示してくださっていますし、私の回答でも「多進木」というキーワードを示しています。ご自分で検索してデータ構造設計やアルゴリズム記述を調べてください。

# どうしてもというのならプライベートメッセージでお受けしますが、私も設計開発を生業とするプロです。
# サンプルどころか完璧な設計書、プログラム、ドキュメントを納品しますが、外注費として 6〜7 桁の金額を請求させていただきますよ(笑)
Wata
ぬし
会議室デビュー日: 2003/05/17
投稿数: 279
投稿日時: 2004-03-30 16:52
よんどさんが最終的に手にしたいものがいまいち見えてこないです。
Javaプログラム上で、親から子への参照ができるデータ構造が欲しいのでしょうか?

ところで、提示されたコードの中にWorkClassificationというクラスが登場しますが、
このクラスの定義は既にできているのでしょうか?
解法としては、このクラスでCompositeパターンを実装するのが通常でしょう。
場合によっては、第1〜4コードをキーにしたComparableとして実装して、
まとめてTreeMapに突っ込んでしまうのもありだと思います。

# 文章が日本語としてへんなので修正。


[ メッセージ編集済み 編集者: Wata 編集日時 2004-03-30 16:54 ]

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