2009-06-30 5 views
0

もし私がリンゴを持つツリーを持っていれば、リンゴがツリーによって所有されているという事実をどのようにモデリングすべきですか? tree、apple、tree_applesの3つのデータベーステーブルがあるとします。ツリーにリンゴがあるという事実を維持する

Treeが複数のAppleDecoratorを持ち、tree_applesへの関連付けを行うためにそれぞれを呼び出すために - > save()を呼び出せるように、AppleDecoratorクラスが存在するようです。 AppleはTreeによって所有されていることを知りません。

TreeクラスがTreeクラスから参照を行うのは間違っているようですが、Treeクラスはそれが持つオブジェクトの種類ごとに1つのテーブルを参照しているためですそれは1つ持っている)。 Idを取得することさえイテレータのようなものに負担をかけることができます。

オブジェクトがN個の他のオブジェクトを所有しているという事実をアプリケーションが保存する必要がある状況はどうでしょうか? (この場合、私のクラスは5種類のオブジェクトの関連付けを格納する必要があります)。

答えて

2

リンゴをツリーのリストまたはセットに入れます。

O/Rマッパーを使用している場合、tree_appesテーブルをジョインテーブルとして使用して、リストがリンゴの1対多であることを注釈付ける方法または指示する方法があります。結合は、リンゴのリストのカスケード保存を使用して(ツリー内に)保存できます。

+0

ORMなしではどうですか? – Dewayne

+0

ORMがなければそれはあまり変わらないとは思いません。オブジェクトを保存すると、ツリーを永続化した後で、すべてのリンゴをリストに残します。私は、すべての言語がこの時点で何らかのORMを持っていると思います。本当に簡単です。 – stevedbrown

+0

はい、ここでの全体的な質問は、リスト内のオブジェクトを持続するコードをどこに置いてテーブルtree_applesにしますか? – Dewayne

1

私はこれを行うために全く別の構造を持っているでしょう:

public interface ITreeSaver { 

    public void save(Tree t); 
    public Tree load(String treeId); 

} 

あなたは、あなたが好きなように、この(プリミティブDAO)を実装することができます。 Hibernateを使用して、MySQLドライバ、XStream、またはその他のものへの生の呼び出し。

ツリー、アップル、または他のモデルオブジェクトが、どのように保存またはロードされるかを知っている/理解する必要はありません。

は、次のようなものを取るストレートSQLの呼び出しでこれを実装するには:私はちょうどポイントを説明しようとしているので、

public class SQLTreeSaver implements ITreeSaver { 

    public void save(Tree t) { 

     String id = t.getId(); 
     if(id == null || id.isEmpty()) { 
      id = /*generate Id here*/; 
     } 

     SQL.execute("delete from TREES where id="+id); 
     SQL.execute("insert into TREES values (id, prop1, prop2) ("+id+",'"+t.getProp2()+"','"+t.getProp3()+"'"); 

     SQL.execute("delete from APPLES where treeId="+id); 

     for(Apple a : t.getApples()) { 
      String appleId = a.getId(); 
      if(appleId == null || appleId.isEmpty()) { 
       appleId = /*generate Id here*/; 
      }   
      SQL.execute("insert into APPLES values (id, tree, prop1) ("+appleId+","+id+",'"+a.getProp1()+"'"); 
     } 

    } 

    public Tree load(String id) { 

     Tree t = new Tree(); 

     if(id == null || id.isEmpty()) return t; 

     ResultSet treeSet = SQL.execute("select top 1 * from TREES where id="+id); 

     while(treeSet.hasNext()) { 
      t.setId(treeSet.getString("id")); 
      t.setProp1(treeSet.getString("prop1")); 
      t.setProp2(treeSet.getString("prop2")); 

      ResultSet appleSet = SQL.execute("select * from APPLES where tree="+id); 

      ArrayList<Apple> appleList = new ArrayList<Apple>(); 

      while(appleSet.hasNext()) { 
       Apple a = new Apple(); 
       a.setId(appleSet.getString("id"); 
       /* omit the following if your apples have no idea who they belong to */ 
       a.setTree(id); 
       a.setProp1(appleSet.getString("prop1")); 

       appleList.add(a); 
      } 

      if(appleList.size() > 0) { 
       treeSet.setApples(appleList); 
      } 

     } 

     return t; 
    } 

} 

悪いSQL呼び出しを許しなさい。あなたが抽象化したのは、オブジェクトが保存/読み込みインターフェイスからどのように保存されるのかということです。あなたは簡単にいくつかの休止状態に入ることができます。

public class HibernateTreeSaver implements ITreeSaver { 

    public void save(Tree t) { 
     HibernateHelper.getSession().save(t); 
    } 

    public Tree load(String id) { 
     Tree t = (Tree)HibernateHelper.getSession.load(id); 
     return t; 
    } 

} 

今、私は何が起こっているか見ることができます。あなたは、使用するITreeSaverの実装を選択するためのいくつかの並べ替えの方法を入れ、次にいくつかの柔軟性や適応性を持っています。クライアントがHibernateでサポートされていないデータベースを使用している場合はどうなりますか?フラットファイルを使用する場合はどうなりますか?ちょっとした努力のために、懸念事項と、システム上の新しい状況やニーズに容易に対応したり変更したりする能力がかなり優れていると感じています。

+0

なぜ私はこれについて投票していないのか分からない。私は、このためにデコレータパターンを使用しないことを指摘していました。あなたは、ApplesやTreeに保存/読み込みの責任を追加するのではなく、ある他のオブジェクトに完全に追加する必要はありません。 質問をしている人には、SQLスキーマと中間結合テーブルについての知識があることは明らかです。 Robert Paulsonが指摘したように、これはm:nの関係のように見えます。 (彼をエコーするには、ひどい隠喩に過ぎないかもしれません。)いずれにしても、私は自分の反応をより適切に編集しました。 –

5

tree_applesは、リンゴが複数のツリーに属している場合にのみ有効です。 (m:nの関係)

悪いメタファーの場合もありますが、1つのツリーには多くのリンゴがあります。リレーショナルデータベースでは、通常、リンゴは元のツリーへの参照を格納します。データのインメモリモデルで

Tree 
    TreeId 
    TreeName 

Apple 
    AppleId 
    IsRotten 
    TreeId (foreign key) 

(すなわち、オブジェクト指向の)あなたがまたはツリーにアップルからのバックポインタを持っていない可能性があります。つまり、通常はツリーがあります。アップルはAppleオブジェクトのコレクションのいくつかの並べ替えですが、 はしばしば apple.Treeを持っていません。

+0

あなたはそうです、それは最高の比喩ではありません。私が求めている質問は、ツリーがtree_applesのテーブルに持つリンゴを保存するコードをどこに置くのですか? – Dewayne

+0

@Dewayneは、ツリーアップルの関係がm:nではなく、TreeAppleの結合テーブルを必要としないため、m:nの何かを探しています(これは無視されます)。 –

+0

しかし、私は "Patterns of Enterprise Architecture"(Fowler)という本をお勧めします。これは、あなたが参加表を使って助けが必要かどうかわからないからです。データの読み込みと保存のトピック(Data Mapperなど)にはかなり多くのことがありますが、 –

関連する問題