最近在做一个电子商务网站( http://www.legendesign.net/ ),暂时叫 LegendShop吧,网站支持多个商家发布产品,类似 于淘宝等商城,不同点在于 LegendShop的整个界面内容是可以自定义的,没有任何植入式的主网站的广告。
产品有一些固定属性,但是每个商家所销售的产品是不一样的,例如卖家具的有大小,颜色等,卖家电的有大小,品牌等。因此要为每个产品增加动态属性,商家在 建立产品的时候可以自定义该产品的属性。
思路是每个产品对应 0..n个动态属性,每个属性有 0..n个选项。
为了满足需求上要求,有些属性要求客户是直接填写的,有些是多选项,有些是要单选的。因此设计了 4中属性类型 Select(选择框) , Text(文本框) , Radio(单选框) , CheckBox(多选框)。
方法一:可以将以上实体定义为一个数据库表,每次读取产品的时候再装载动态属性,需要做表关联。此方法需要增加 2张表,但方便于采用 SQL做数据统计。 但每个产品都建立一次动态属性显然是没有必要而且很麻烦,因为相关的产品的动态属性是一致的,没有必要重复创建。 为了用户更容易增加动态属性,最好增加一个动态属性的模板,每次新建产品的时候直接指定采用那一个属性模板,但是模板一旦使用则不能轻易删除,否则动态属性就不见了。另外客户在订购的时候将填写或者选择这些动态属性,并将结果存入产品订购表。
方法二:采用对象数据库的方式,将动态属性以对象形式存到产品表中。此法不需要新建产品属性表和属性选项表,查询产品的时候可以直接把动态属性查询出来,但需要自己动手将对象和页面功能对应起来。 该字段可以直接存放 Java的对象,或者将对象转化为 JSON对象或者 XML再行存放。 如果采用 Oracle的话,那需要采用 BLOB的字段来存放对象,或者采用 CLOB来存放 JSON和 XML。下面用代码来展示如何实现方法二的。
属性类型定义:
public enum ModelType {
Select , Text , Radio , CheckBox ;
}
属性定义:
public class Model implements Serializable {
private String id ;
/**
* may by select text radio checkbox
*/
private ModelType type ;
private Item[] items ; // 属性选项
选项定义:
public class Item implements Serializable {
private boolean nullEnabled = false ;
private boolean selected = false ;
private String key = null ; // 后台定义的选项关键字
private String value = null ; // 用户输入的属性值
界面说明:后台可以自定义上面提到的 4种属性类型。点击提交的时候通过 JSON将属性数组保存为产品表中的属性。当客户浏览产品的时候可以看到后台动态属性的定义,当然客户是不知道这些属性是动态增加的还是固定的。他们订购的时候选择对应的选项再提交,如果需要对选项做 validate的话,那在 Item中增加 needValidate属性,再页面中再行判断。
提交之后以 JSON方式交给 DWR处理,直接得到 Model[]数组。或者采用 DOM的方式得到 XML传到后台的 controller进行处理。下面的例子是采用 JSON的方式实现的。具体看附件。
DWR的配置文件,否则不能通过 DWR来传输对象。
< dwr:configuration >
< dwr:init >
< dwr:converter id = "date" class = "bingo.vasms.bizstreet.dwr.CalendarConverter" />
</ dwr:init >
< dwr:convert type = "date" class = "java.util.Calendar" ></ dwr:convert >
< dwr:convert type = "bean" class = "com.done.entity.Model" ></ dwr:convert >
< dwr:convert type = "bean" class = "com.done.entity.Item" ></ dwr:convert >
< dwr:convert type = "enum" class = "com.done.entity.ModelType" ></ dwr:convert >
</ dwr:configuration >