2012-11-20 66 views
3

我已經看過How to store data with dynamic number of attributes in a database,但它沒有完全回答我的問題。我正在執行的系統相當龐大,所以我會堅持我關心的對象:Item和Category。項目具有可變數量的屬性,具體取決於它所屬的類別。例如,屬於「T恤」類別的項目將具有尺寸屬性,而屬於「車輛」類別的項目將具有用於模型的屬性。有人以管理員身份登錄系統可以創建具有全新屬性的新類別。在我的Java代碼和數據庫中構造這兩者的最佳方法是什麼?如何存儲具有可變數量屬性的java對象

如果類別不是動態創建的,我會使用繼承,這樣我就可以擁有一個TShirtItem對象,並填充了它的特定屬性。但是由於它是動態的,所以我很困惑。我看到一個類似的問題,建議使用地圖數據結構,但我不知道如何工作...

我在頂部提到的問題將建議在數據庫端,我會有一個類別表,屬性表和關係表,鏈接哪些屬性與哪些類別。這是有道理的。但是在思考Item對象時我又被絆倒了。我可以將唯一的Category_ID存儲在Item表中,但我將在哪裏存儲每個Item的屬性?

回答

2

這是一個簡單的java方法來做到這一點。在設計大型系統時,我總是建議看看更大的圖景。這裏的問題是動態改變屬性。這並不容易,但是它很有趣。

您的項目類的結構必須是這樣的:

class Item{ 
    private String itemName; // I assume all items will have a name. 
    private Map<ItemAttibuteName , Object> attributeMap ; // this will be a dynamic map. 

    public Map<ItemAttibuteName, Object> getAttributeMap(){//getter for attribute map 
     if(null == attributeMap) 
      return new HashMap<String, Object>(); 
     return attributeMap ; 

    } 
    // you can synchronize this if needed 
    public void setAttribute(ItemAttibuteName name, Object value){ 
     attributeMap.put(name, value); 
    } 

    public Object getAttribute(ItemAttibuteName name){ 
     return attributeMap.get(name); 
    } 
} 

public enum ItemAttibuteName{ 
    SIZE, 
    COLOUR   
} 

這種做法符合您需求,進一步可以使用工廠模式來實例化取決於類別的項目,使之成爲優雅碼。

如果您還有疑問,請回復。

編輯: 現在會有一個複雜的方式來獲得一個元素的所有屬性的代碼,而編程,因爲你沒有爲屬性的getter和setter方法。那麼,如果您可以在Item類中維護添加到Item的一組屬性,或者您可以查詢item類的attributeMap屬性的keySet,則該方法將有所幫助。

private Set<ItemAttibuteName> attributes; 

attributeMap.keySet(); 

樂意幫助

Dharam

+0

超好玩!感謝Gene的回答,我將會有一個Attribute對象。每個類別都有一個私有迭代器,其中包含與其對應的所有Attribute對象。當實例化代理Item對象時,我將創建一個hashmap並使用Attribute name作爲關鍵字,並將其值作爲值。我將有一個getAttribute(String)方法,它使用提供的字符串值(屬性名稱)來獲取特定屬性的值。還有一個setAttribute(String,Value)。我認爲這會起作用! – sunrize920

+0

太棒了!你可以進一步簡化它通過使用所有可能的屬性名稱的枚舉:) – dharam

3

如果你被限制使用一個SQL數據庫,你需要做的高效型感知(不只是字符串)查詢屬性(例如列出所有具有大小在4到8之間的襯衫類型的項目),那麼數據庫的結構就是難題。 Java將隨之而來。如果我理解正確的話,你就需要這樣的事情:

categories: 
    id : integer (pk) 
    name : varchar 

attributes: 
    id : integer (pk) 
    of_category : integer (fk -> categories.id) 
    name : varchar 
    type : char(1) // 'N' for number, 'S' for string, etc. 

items: 
    id : integer (pk) 
    of_category : integer (fk -> categories.id) 

number_values: 
    value : number 
    of_item : integer (pk, fk -> items.id) 
    of_attribute : integer (pk, fk -> attributes.id) 

string_values: 
    value : varchar 
    of_item : integer (pk, fk -> items.id) 
    of_attribute : integer (pk, fk -> attributes.id) 

... additional table for each attribute type 

現在對於查詢實例:

select * from categories c, items i, attributes a, number_values v 
where c.name = 'shirt' and 
     a.of_category = c.id and 
     a.name = 'size' and 
     a.id = v.of_attribute and 
     i.id = v.of_item and 
     v.value between 4 and 8 

毛多個連接是要付出的代價運行時定義attrbutes。

一旦你的表權,造型它們作爲Java的地圖很簡單。上面的結構中有冗餘:例如屬性行中的字符「type」字段。考慮觸發器進行一致性檢查。

+0

謝謝!我選擇dharam作爲正確的答案,只是因爲他先提交了答案。我希望我可以選擇兩個,因爲我問了兩個部分的問題,你的答案是現貨。您能否詳細說明「考慮觸發器進行一致性檢查」的含義? – sunrize920

+0

啊,好吧。花了幾分鐘纔算出數據庫表格的正常形式。我很樂意提供幫助。觸發器是一種SQL功能,允許在發生INSERT,UPDATE和DELETE操作(以及其他一些情況)時運行代碼。您可以在此代碼中執行一致性檢查。例如,您可以檢查數字表中的值是否實際引用類型字段爲'N'的屬性。所有這些都以數據完整性的名義。觸發器代碼通常在存儲過程中實現。谷歌將展示道路。 – Gene

0

而不是Java它是更多的設計水平問題。你必須弄清楚定義數據庫表的方式,這將有助於你在尋找Java對象...

讓我們從類別開始......一個類別可以包含很多項目,並且項目將只屬於一個類別(儘管我的實際情況並不是一個正確的假設)。

所以在DATABASE中你有一個名爲Category的表。如果您想要根據類別定義屬性,則可以使用另一個名爲Category_attribute的表,該表將保留屬性的默認值。

現在讓我們移動到一個項目。一個項目屬於一個類別,因此項目表將具有category_key以具有項目n類別的映射...項目將具有存儲在ITEM_Attribute表格中的其屬性...

簡單形式的DB對象必須有點像下面

Category 
C_Id 
Name 


Category_Attribute 
CA_ID 
Name 
Default_value 
Category_Id(FK) 


Item 
I_ID 
Name 
C_ID(FK) 


Item_attribute 
IA_ID 
Ca_ID(FK from category_attribute table) 
I_ID(FK from item table) 
Value 

提到所以每當你創建一個目錄,你會問用戶定義相關屬性的類別。

在創建項目的時候,你把它映射到種類和相關類別的屬性都以默認值複製,並映射到項目,以及...

所以,你將能夠創建Java對象很容易...

0

我想你可以通過這樣的方式來構建你的數據,你可以定義表 中的所有對象類型,然後使用下面的方法。

U可以定義像表:

  • OBJECT_TYPE

  • OBJECTS

  • OBJ_PROPERTY_DEF

  • OBJ_PROP_VALUES

例如。
在OBJECT_TYPE 定義這裏的所有對象類型

object_type_code(PK)obj_name

4        car 
5        t-shirt 

在OBJECTS

obj_code(PK)object_type_code(FK)obj_name


1   4  BMW 
2   4  Maruti 
3   4  Honda 

4   5  levis 
5   5  polo 
6   5  reebock 

在OBJ_PROPERTY_DE中F

定義與此表中的對象相對應的所有屬性。

注意:使用常量文件來定義屬性類型會避免另一個表。 希望能早點知道數據類型。

obj_prop_code(PK)obj_code(FK)房產類型PROPERTY_NAME

------------- -------- ----------- - -------------

12   6  8 (Integer)  size 
13   6  9 (String)  color 
14   6  10 (float)  weight 
15   6  11 (Boolean)  is_coloured 
16   6  9 (String)  comments 

17   3  9 (String)  model 
18   3  8 (Integer)  version 
19   3  9 (String)  color 
20   3  9 (String)  comments 

在OBJ_PROP_VALUES U可以inser的值在上述特定屬性

obj_prop_val_code(PK)obj_prop_code(FK)obj_prop_value(VARCHAR )prop_value_sufix

----------------- ------------- -------------- ----- ------------

101    12   30    - 
102    13   green   - 
103    14   126   gms 
104    15   0    - 
105    16   looks cool  - 

106    17   c532   - 
107    18   3.22   - 
108    19   black   - 
109    20   awesome car  - 

註冊的Java歸類:

定義的所有類與相應的屬性。 例如:

  • ObjectTypeData

  • 目標數據

  • ObjectPropertyDefData

  • ObjectPropertyValuesData

在ObjectData.java

private ObjectTypeData   objType;//specifies the type 
private List<ObjectPropertyValueData> listProps; //will have all property values 

//setter & getters and other req props 

相關問題