元数据

每个实体及其属性都反映在应用程序元数据中,框架通过一种机制使用这些元数据来获取有关数据模型的全面信息。例如,如果某属性在元数据中被标记为只读,相应的 UI 组件将被禁用。

元数据是框架的内部机制,应用程序的业务代码中很少使用。

元数据 API 的主要入口是 Metadata bean。支持以 MetaClassMetaProperty 对象的形式访问实体的有关信息。

在下面的示例中,我们打印出 Order 实体属性的详细信息:

@Autowired
private Metadata metadata;

public void printOrderProperties() {
    MetaClass metaClass = metadata.getClass(Order.class); (1)
    for (MetaProperty metaProperty : metaClass.getProperties()) { (2)

        String propertyName = metaProperty.getName(); (3)
        MetaProperty.Type propertyType = metaProperty.getType(); (4)
        Class<?> javaType = metaProperty.getJavaType(); (5)
        Range propertyRange = metaProperty.getRange(); (6)

        String info = "name: " + propertyName +
                "\n type: " + propertyType +
                "\n Java type: " + javaType +
                "\n range: " + propertyRange;

        if (propertyRange.isClass()) { (7)
            MetaClass refMetaClass = propertyRange.asClass(); (8)
            Range.Cardinality cardinality = propertyRange.getCardinality(); (9)
            info += "\n reference to: " + refMetaClass;
            info += "\n cardinality: " + cardinality;

        } else if (propertyRange.isEnum()) { (10)
            Enumeration<?> enumeration = propertyRange.asEnumeration(); (11)
            info += "\n enum: " + enumeration;

        } else if (propertyRange.isDatatype()) { (12)
            Datatype<Object> propertyDatatype = propertyRange.asDatatype(); (13)
            info += "\n data type: " + propertyDatatype;
        }

        System.out.println(info);
    }
}
1 Metadata.getClass(javaClass) 方法返回一个对应于实体Java类的 MetaClass 对象。
2 MetaClass.getProperties() 方法返回所有实体属性对应的 MetaProperty 对象的集合。
3 MetaProperty.getName() 方法返回实体属性名称。
4 MetaProperty.getType() 方法返回属性类型:DATATYPEENUMASSOCIATIONCOMPOSITION
5 MetaProperty.getJavaType() 方法返回实体属性的 Java 类。
6 MetaProperty.getRange() 方法返回描述实体属性目标类型的 Range 对象。
7 如果实体属性是引用,则 Range.isClass() 方法返回 true。
8 可以使用 Range.asClass() 方法获取引用的实体的 meta 类。
9 Range.getCardinality() 方法返回引用的关系:ONE_TO_ONEMANY_TO_ONEONE_TO_MANYMANY_TO_MANY。你还可以使用 Range.getCardinality().isMany() 来确定属性是否为一个集合。
10 如果实体属性是枚举,则 Range.isEnum() 方法返回 true
11 Range.asEnumeration() 方法返回 Enumeration 对象,该对象可用于遍历所有枚举常量。
12 如果实体属性不是引用也不是枚举,则 Range.isDatatype() 方法返回 true
13 Range.asDatatype() 方法返回实体属性的 数据类型。可以用于格式化和解析属性值。