# 数据源

# 数据源

数据源是一个组件的灵魂,通过设置数据源,使各组件得以填充数据。

Meper的组件中的数据都是自加载的,这个是Meper数据源设计的基础,时刻牢记

数据源是以组件为单位的,不同的组件可以设置不同的数据源,同一种组件也可以设置不同的数据源。在页面初始化的时候,进行数据的加载。

datasource-description

一般情况下,会将Layout类型的组件中,设置一个数据源来源,然后在其具体的子对象中,设置具体的取值方法。 比如,可以设定一个表格从用户对象中取值,而具体的某一个栏位可以指定从系统User对象的某一个方法中取值;或者设定表格从SQL语句中取值,而栏位可以从SQL返回的众多栏位中的其中 一个进行数据绑定。 再比如,一个FormLayout中,包含一个TextField,可以设定FormLayout组件及其子对象的值来源于User对象,而TextField的值来源于User 对象的 getUserName()方法

system-object

如上图所示,一般情况下,数据源分为五个元素:

  • 数据源类型 根据数据源的数据来源不同,分为诸如系统对象,自定义表等,后面章节会详细介绍

  • 数据源对象 数据源类型选定后,会选择在来源下,具体的数据源对象是什么。比如,如果设定数据源是系统对象,那么数据源对象可以使用户对象,角色对象等,如果设定数据源 是自定义表,那么数据源对象就是自定义表的名称

  • 取值方法 数据源对象确定后,需要确定取值的方法。针对系统对象,一般为常用的get方法,针对自定义对象,一般为栏位的名称即可

为了将取值显示内容规范化,所有的取值方法都会采用类似于开发方法的展示形式:

形式为: #返回类型 get属性()# 如: String getUserName(),即为返回用户名。 同时也支持扩展属性,扩展属性为 Object getCEF($栏位名称)。当用户选择扩展属性时,系统会跳出选择框,供用户选择具体哪个属性

  • 设值方法 数据源对象确定后,需要确定设值的方法。针对系统对象,一般为常用的set方法,针对自定义对象,一般为栏位的名称即可

为了将取值显示内容规范化,所有的取值方法都会采用类似于开发方法的展示形式:

形式为: #void set属性(参数类型)# 如: void setUserName(String) 同时也支持扩展属性,扩展属性为 Object setCEF($栏位名称,Object)。当用户选择扩展属性时,系统会跳出选择框,供用户选择具体哪个属性

  • 过滤条件 一旦用户定义好数据源和数据类型,就可以设定其过滤条件。过滤条件限定了需要从数据源中检索哪些符合条件的对象。比如找出用户名为 “张 三”的用户。

如上图所示,检索条件会根据所选择的数据源对象,来罗列出所有该对象所支持的过滤条件,用户选择一个后,可以点击 “+” 按钮,加入一个检索条件。 对于添加的检索条件,支持两种设值方式:

User Defined

这个值用户可以随便输入,但是不能动态改变,一旦输入后就确定下来

Component

拿到的是当前页面下某一个组件的值。

filter-condition-component1

说明该检索条件的值来源于页面控件,可以根据页面中该控件的值,来动态的取值,从而达到动态过滤数据的目的。

这里有个典型应用,在各种报表中,有各种检索条件,可以通过表格设置数据源和检索条件,然后将检索条件和页面控件绑定的方法来实现

一般情况下,数据源类型和数据源对象会设置在Layout,表格等父对象上。而“取值方法”、“设值方法”会设置在子对象上。 比如,表格中设置数据来自于系统对象的User对象,子对象的栏位设置取值方法为getUserName

数据源根据数据来源不同,分为以下几种:

# System_Object

system-object

系统对象,是指有Lumos平台原生提供的对象,如用户,角色,权限,用户组,产线,工艺,物料,bom等系统对象。

Meper根据如下接口来具体系统的对象,但是会过滤掉中间的对象。所有该接口的实现都会作为系统对象来处理。

public interface IObjectType {
    String getName();

    default String getNameKey() {
        return "objecttype." + this.getName();
    }

    Class<?> getClazz();

    default Class<?> getDomainClazz() {
        return null;
    }

    default String getTableName() {
        Class<?> clazz = this.getClazz();
        Table annotation = (Table)clazz.getAnnotation(Table.class);
        return annotation != null ? annotation.name() : this.getName();
    }
}

# Customized_Object

datasource-cust1

自定义对象,指的是自定义表对象。

上图数据源对象的值直接来源于自定义表对象,会将自定义表全部罗列出。

自定义表字段获取有两种方式,一是编辑子项目弹出框中展示所有自定义表字段,勾选所需要的自定义表字段在文本框中输入字段栏位名称(或者选择文本ID);二是选中表格列,数据源字段获取器下拉框选择自定义表字段。

datasource-cust2 datasource-cust3

# SQL

系统支持直接通过SQL语句来获取数据。

  • 图中 1 所示,用户可以输入准备好的SQL语句。(目前仅支持较简单的SQL,对于存储过程等,暂时不支持)
  • 图中 2 所示,根据用户输入的SQL语句,系统会自动进行解析出所返回的栏位,用户可以根据栏位来设置过滤条件。

datasource-def datasource-def

目前仅支持较简单的SQL,对于存储过程等,暂时不支持

# vo

待续

# DTO

Meper支持自定义GRID分页的数据源,如图所示:

file

  • 查询器:Query对象,用于组装查询,系统中纯代码的分页GRID也是使用的这个

  • 返回值类型:表示这个GRID的数据源对象

  • 查询条件:就是我们的查询条件(一般是QO)

使用方法需要在代码中注册,注册方式如下:

public enum DeviceQueryType implements IPagingQueryType {

    EQUIPMENT_PAGE_QUERY(EquipmentPageQuery.class, Equipment.class, EquipmentQO.class);


    private Class queryClazz;
    private Class queryGenericClazz;
    private Class queryConditionClass;

    DeviceQueryType(Class queryClazz, Class queryGenericClazz, Class queryConditionClass) {
        this.queryClazz = queryClazz;
        this.queryGenericClazz = queryGenericClazz;
        this.queryConditionClass = queryConditionClass;
    }


    @Override
    public Class getQueryClazz() {
        return this.queryClazz;
    }

    @Override
    public Class getQueryGenericClazz() {
        return this.queryGenericClazz;
    }

    @Override
    public Class getQueryConditionClass() {
        return this.queryConditionClass;
    }

    @Override
    public String getName() {
        return getQueryClazz().getSimpleName();
    }
}

注册完成之后,即可在我们的页面上获取到指定DTO的查询数据源。

# Component

datasource-component

该数据源表示数据并不是来源于数据库,代码,用户预定义等,而是在运行期来源于控件的值。

Data Source Object的值为页面中的所有ID,用户可以选择想要取值的组件。

datasource-component-illus

一旦在某个Layout类型的组件上面指定了该数据源,且指定了数据源对象,也就意味着该数据源对象所代表的控件上面的数据源,就做为该Layout的数据源了 ,后续在该Layout中加入的其他组件,如Text Field,在为子组件设置数据源的时候,getter或者setter将会从数据源对象所指定的控件上面的数据源指定的类型去获取。

常见的可供取值的组件有:

  • 所有Input 类型的控件,如Text Field、Integer Field、Combo Box、Datatime Picker等等
  • Grid + 取值为选中的行,如果没有,则取值为空
  • Pagination Grid + 取值为选中的行,如果没有,则取值为空

值得注意的是,系统中有多处取值为COMPONENT的情况,含义均如上所述,并无不同

# API

对于复杂的逻辑,不属于页面逻辑可以解决的部分,需要借助于调用后台的API进行处理。 一般用于调用后台API的场景主要有:

  • 核心逻辑在于后台处理,如产品在站位开始处理(startAtRouteStep)、产品在站位结束处理(completeAtRouteStep)等
  • 对于对象之间的关系绑定。如用户与角色的绑定、用于与权限的绑定

datasource-component-illus

上图即为API Action的定义界面:

  • Service
    罗列出系统中的所有服务
  • Method
    列出选中服务中所有的可以调用的方法 (#只列出操作类型的方法,取值类型的方法并不列出,关于如何取值请参考<>#)
  • 参数定义
    一旦选中Method后,该方法所需要的参数将会全部现在下面的表格中,用户需要定义各个参数需要从哪里获取值,一共有三种取值方法

USER DEFINED
如果参数是一个常量,需要用户直接输入,可以使用该方法

COMPONENT
如果参数需要从页面元素中取值,一旦用户确定使用该方法取值,在 “值” 这一列将会列出当前页面中的所有的ID。

Expression
待续

# User Defined

用户自定义(在string类型下)该数据源比较简单,一般使用在列表项的定义,比如Combo Box的下拉框,List Box的列表中。 用户可以根据自己实施的需要,手动输入需要显示的值。

datasource-def

# Enum

Enum定义 datasource-enum1

运行期 datasource-enum-run

该数据源比较简单,一般使用在列表项的定义,比如Combo Box的下拉框,List Box的列表中。

这个的使用场景,主要是一些诸如状态的定义,不如用户的状态,过站WIP的状态等,系统定义了一些Enum常量来表示这些状态,而这些状态常常作为输入 参数。为了使用户可以在界面上可以选择这些状态,系统提供了Enum进行支持。

需要通过二次开发API手册,填写 Enum 的全路径

# Data Dictionary

数据字典数据源定义 datasource-dict

运行期 datasource-dict-run

数据字典数据源,会根据用户选中的数据源,来显示数据源的值。

例如Combo Box中,会将选中的数据源的所有value值全部显示出来,供用户选择。

进行到这里,再来思考最开始的一段话,“Meper里面的组件的数据都是自加载的”。 其实也就是说,每个控件指定自己的数据源,指定过滤条件,在某种情况下,触发控件刷新数据即可。