自定义表单设计的目标是不编写代码,由设计人员在界面设计表单配置,用户就能使用具体的功能模块了,对于这个目标,首先要解决的就是数据存储以及数据库与表单之间的映射问题。
平时如果使用过代码生成工具,应该对大体的过程有些认识。要么从数据库读取已经定义好的表结构,工具生成实体部分代码,或者是与框架强相关的不同层次的服务代码;要么从配置文件,再反向生成数据库代码或者业务相关代码;还有可能先定义实体类,再生成其他部分代码。生成代码之后,再拷贝到具体的代码目录。
这里设计的实体模型与代码生成工具有部分思路还是相同的,但自定义表单赋予了他更多的功能与职责,首先,他需要面向使用者,用户、开发人员和设计人员可以在界面上随时修改实体数据,系统动态同步数据库与实体模型之间的映射(如果系统已经在运行,实体模型对应的数据库表数据量比较大,则通过系统自动修改表结构可能会存在问题,需要DBA把数据库表修改好,再同步实体模型);其次,运行时CRUD等与数据存储相关操作,需要依赖此实体模型,比如自动生成Id、自动添加审计日志、动态生成各种Sql语句、自动方法验证等;再者,可以定义与实体模型相关的动态方法执行,比如执行各种基础的增册改查以及分页获取数据等,或者执行自定义的Sql语句,还可以执行反射或者微服务调用定义等。总之,这里的实体模型做为自定义表单的基础,承担了更多的职责。
下面介绍数据库设计
与实体对象模型对应的数据库设计有三张表,SpriteObject,主要管理数据库表信息,并与动态生成的实体数据库表一一对应;ObjectProperty,主要管理数据库表字段信息,并与运行时动态生成的数据库表字段一一对应;ObjectMethods,主要管理运行时方法的调用(自定义表单将大多数常规的数据库表操作的Sql语句脚本执行都提供了默认的方法实现,提供给表单或者视图规则使用,大多数常规的CRUD操作不需要另外再单独定义方法,但对于特殊的业务还是需要自定义Sql脚本执行或者写代码完成,但都是通过ObjectMethods管理,并提供给表单规则引擎使用)。ObjectMaps(废弃),定义实体与实体也就是数据库表与表之前的关联关系,但同步维护这个关系会大大增加系统的复杂程度,这里废弃了,通过后面介绍的规则引擎来管理,CommonParams,方法参数管理,主要管理方法调用的参数,参数设计到实体嵌套,也会大大增加系统的复杂度,这部分也交给规则执行引擎来控制。
核心字段介绍:
SpriteObject,实体对象
- Name,定义实体名称,与数据库表名一一对应。
- ApplicationCode,系统Code,可以按照不同微服务管理各个功能模块。
- Version,版本号,每次修改之后,重新生成版本号,SpriteObject使用非常平凡,需要将SpriteObject相关的数据存储到缓存中,依赖他的地方需要判断版本号。
- KeyType,定义主键类型,创建数据库或者添加运行时数据时,根据此字段动态生成Id以及Id值。
- PropertyJsons,属性数据Json存储,为了提高系统整体性能,将属性相关数据序列化到此字段,读取与访问实体字段时,不再需要读取ObjectProperty表数据。
- IsTree,是否为树,系统自动生成PId、Path、Code、Title等值,并在运行时自动管理
- CreateAudit,自动添加创建CreatorId和CreationTime审计日志及字段,并在运行时自动管理
ObjectProperty对象属性管理
- Name,字段名称,与数据库字段一一对应
- 其他字段都比较好理解
ObjectMethods方法管理
常规的Sql方法已经内置到了系统中,比如增删改查获取列表获取分页数据等,直接使用方法名称即可,常规功能模块,大多数情况这些内置的Sql语句都能够满足,这里只是定义常规Sql操作不能满足的情况,比如各种统计分析等。
- MethodExeType 方法执行类型,可以是Sql语句,反射执行,微服务调用
- MethodExeContent方法执行内容,Sql语句时,执行的是Sql命令(多条时,用";"号隔开);反射时,传递程序集以方法,通过反射执行;微服务为微服务名称
这篇文章主要是介绍实体模型的整体设计思想,后续文章会结合代码,介绍实体模型与数据库表之间一一对应关系的实现以及自定义表单核心之一的运行时动态方法执行。