背景:随着用户对对象属性的不断丰富,原来基于固定编码的类模型已经不能满足用户的需求,现在尝试编写一个动态字段的系统来实现模型属性的任意定制,并在此基础上不断扩展。
目标:用户可以用自定义的方式动态的为表单添加字段,并对字段进行查询,编辑,导入,导出等与普通固定类模型一致的操作。
实现:动态字段的实现方法很多,包括关联表,预定义字段,使用文档数据库等。本文就讨论一种基于关联表的实现方式。
预定义字段有字段上限和字段对应的缺点,文档型数据库需要我们学习新的思维模型。关联表模型是关系型数据库模式下
动态字段的一个合理有效的解决方案。
基本的思路是实现自己的
类(MyClass):类中包含定义的属性即字段
类的属性(MyProperty):属性包含字段的名称,类型,是否显示,排序等
实例化的对象(MyObject):对象包含具体是哪个类,通过类索引到具体有哪些字段,还包含他所关联的属性及值(Item)
属性的值:(Item):包含属性的名称及其对应的值
直接上代码:
@QClass(name = "自定义类")
@Entity
@Table(name = "b_my_class")
public class MyClass extends BaseEntity {
@Column(name = "name", columnDefinition = "varchar(100) COMMENT '名称'")
private String name;
@OneToMany(mappedBy = "myClass", cascade = CascadeType.ALL)
@JsonManagedReference
private List properties;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List getProperties() {
return properties;
}
public void setProperties(List properties) {
this.properties = properties;
}
}
@QClass(name = "自定义属性")
@Entity
@Table(name = "b_my_property")
public class MyProperty extends BaseEntity {
@QField(name = "名称", actions = {Action.edit, Action.show}, queryType = QFieldQueryType.like, nullable = false)
@Column(name = "name", columnDefinition = "varchar(100) COMMENT '名称'")
private String name;//名称
@QField(name = "字段", actions = {Action.edit, Action.show}, queryType = QFieldQueryType.like)
@Column(name = "field", columnDefinition = "varchar(100) COMMENT '字段'")
private String field;//字段
@QField(name = "类型", actions = {Action.edit, Action.show}, queryType = QFieldQueryType.like)
@Column(name = "field_type", columnDefinition = "varchar(50) COMMENT '类型'")
@Enumerated(EnumType.STRING)
private FieldType fieldType;//类型
@QField(name = "是否显示", actions = {Action.show}, queryType = QFieldQueryType.like)
@Column(name = "if_show")
private Boolean ifShow;//是否显示
@Column(name = "seq")
private Integer seq;
@ManyToOne
@JoinColumn(name = "my_class_id")
@JsonBackReference
private MyClass myClass;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getField() {
return field;
}
public void setField(String field) {
this.field = field;
}
public FieldType getFieldType() {
return fieldType;
}
public void setFieldType(FieldType fieldType) {
this.fieldType = fieldType;
}
public Boolean getIfShow() {
return ifShow;
}
public void setIfShow(Boolean ifShow) {
this.ifShow = ifShow;
}
public Integer getSeq() {
return seq;
}
public void setSeq(Integer seq) {
this.seq = seq;
}
public MyClass getMyClass() {
return myClass;
}
public void setMyClass(MyClass myClass) {
this.myClass = myClass;
}
}
@QClass(name = "动态实体")
@Entity
@Table(name = "b_my_object")
public class MyObject extends BaseEntity {
@ManyToOne
@JoinColumn(name = "my_class_id")
private MyClass myClass;
@OneToMany(mappedBy = "myObject", cascade = CascadeType.ALL)
@JsonManagedReference
private List- items;
public MyClass getMyClass() {
return myClass;
}
public void setMyClass(MyClass myClass) {
this.myClass = myClass;
}
public List
- getItems() {
return items;
}
public void setItems(List
- items) {
this.items = items;
}
}
最终实现的效果图:
这是基本的实现,后续将增加查询,编辑,导入,导出等所有固定字段模型实现的所有功能,即这是一个万能表单,用户能够
动态的定制字段,然后动态的将他转化为菜单,然后动态的使用。
最新源码获取地址