最近工作上遇到了这样一个问题,就是关于系统用户可对系统预置管理对象进行属性的自定义。在数据库中的体现就是用户可以追加字段。
为此看了不少相关的资料,发现遇到这一问题的人不在少数,但可供参考的解决方案却不是很多。其实包括很多比我资深的师兄师长们都对这一需求是抵触的,认为这是一个不可接受需求,认为能有这样的需求,完全是在需求的分析上做的不够彻底。他们这样的一些看法我本人也是赞同的。但有时我们也不得不承认这样的需求在某种情况下的存在是有其理由的。就拿我们公司的情况来说,一个系统的后台管理,比如说注册用户的管理,你可以尽量地为用户考虑周全,预置很多的属性,但怎么做,也不可以满足所有用户的需求,有的用户需要手机号,有的需要工作证件号码,有的是多个邮箱等等。所以在这增加一个用户自定义的功能是很必要的。
对于这个问题的解决,我在看过相关资料后,发现主要有以下三种方案:
1)系统的数据库操作使用JDBC的方式,在POJO中,用一个MAP来对增加的字段进行操作。在这个思路的基础上,可以考虑整个POJO的对象里,只有一个MAP,它来保存所有字段名称和值。
2)上面那种是不采用ORM的方式,采用ORM的好处我想不必多说,而我最看重的就是它对跨数据库的良好支持。我这里只说说HIBERNATE,HIBERNATE已经有了动态加裁新增字段的功能。缺点是实现起来比较麻烦,还有就是它是通过MAP得到新增字段的值的,在考虑到与页面显示,与STRUTS的结合并不好实现。
3)就是预留一个TEXT的字段,然后,用"符号"区分,将区分的内容,和列名:值写出来,最后显示的时候用Split进行分开。
我最后是采用了第三次方式,其实在这也只是大概的提一下,给正遇到该问题的人提供一些参考,具体的实现在这就不提了。哪位大侠有更好的方案,欢迎赐教!
你的方案明显有问题,用户要做统计怎么办?
我也曾经做过一个这样的系统,当时我也是用key-value表来实现的。
基本结构是:
DynProp表:
dynPropId | parentId | dynPropType | dynPropValue
动态属性ID | 主表记录ID | 动态属性类型 | 动态属性值
在Hibernate中设置一个一对多Set,关联parentId提取DynProp对象。
这种性能上其实没有问题,和主表关联有索引支持,按值搜索首先用有索引dynPropType作为条件过滤掉其他类型,再搜索value,性能基本没有太大问题。
这种方式下可以进行统计,缺点是效率会降低,因为要做关联。而且dynPropValue只能是弱类型,必须由系统进行类型转换。
KEY-Value表是值得推荐使用的
我一般还是不让用户这样自定义字段,之前做过一个项目也是采用用第三种方式
这个问题之前也遇到过,当时对商品表进行表设计时,认为属性基本差不多够了,但是客户还是会提出要加商品属性,一开始是直接改表结构,结果改两次之后就相当崩溃,为了不改表结构动态增加属性,查了一些资料,也是用的楼上的这种方式,主表是预建属性表,从表是动态属性表,这样对商品增加属性不再动表结构了,一个明显的问题就是属性值字段是弱类型的,至于对性能的影响,该牺牲就牺牲了,不能两次都占啊.