2012-11-20 62 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 

相关问题