java動態字段的萬能表單系統的構建

背景:隨着用戶對對象屬性的不斷豐富,原來基於固定編碼的類模型已經不能滿足用戶的需求,現在嘗試編寫一個動態字段的系統來實現模型屬性的任意定製,並在此基礎上不斷擴展。

目標:用戶可以用自定義的方式動態的爲表單添加字段,並對字段進行查詢,編輯,導入,導出等與普通固定類模型一致的操作。

實現:動態字段的實現方法很多,包括關聯表,預定義字段,使用文檔數據庫等。本文就討論一種基於關聯表的實現方式。

預定義字段有字段上限和字段對應的缺點,文檔型數據庫需要我們學習新的思維模型。關聯表模型是關係型數據庫模式下

動態字段的一個合理有效的解決方案。

基本的思路是實現自己的

類(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<MyProperty> properties;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<MyProperty> getProperties() {
        return properties;
    }

    public void setProperties(List<MyProperty> 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<Item> items;

    public MyClass getMyClass() {
        return myClass;
    }

    public void setMyClass(MyClass myClass) {
        this.myClass = myClass;
    }

    public List<Item> getItems() {
        return items;
    }

    public void setItems(List<Item> items) {
        this.items = items;
    }
}

最終實現的效果圖:

這是基本的實現,後續將增加查詢,編輯,導入,導出等所有固定字段模型實現的所有功能,即這是一個萬能表單,用戶能夠

動態的定製字段,然後動態的將他轉化爲菜單,然後動態的使用。

最新源碼獲取地址

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章