4.1.5 模型之持久层配置

一、批量操作

批量操作包括批量创建与批量更新。批量操作的提交类型系统默认值为batchCommit。

批量提交类型:

  • useAffectRows,循环单次单条脚本提交,返回实际影响行数
  • useAndJudgeAffectRows,循环单次单条脚本提交,返回实际影响行数,若实际影响行数与输入不一致,抛出异常
  • collectionCommit,将多个单条更新脚本拼接成一个脚本提交,不能返回实际影响行数
  • batchCommit,使用单条更新脚本批量提交,不能返回实际影响行数。

全局配置

pamirs:
    mapper:
    batch: batchCommit

图4-1-5-1 全局配置

运行时配置

非乐观锁模型系统默认采用batchCommit提交更新操作;乐观锁模型默认采用useAndJudgeAffectRows提交更新操作。也可以使用以下方式在运行时改变批量提交方式。

Spider.getDefaultExtension(BatchApi.class).run(() -> {
    更新逻辑
}, 批量提交类型枚举);

图4-1-5-2 运行时配置

运行时校正

如果模型配置了数据库自增主键,而批量新增的批量提交类型为batchCommit,则系统将批量提交类型变更为collectionCommit(如果使用batchCommit,则需要单条提交以获得正确的主键返回值,性能有所损失)。

如果模型配置了乐观锁,而批量更新的批量提交类型为collectionCommit或者batchCommit,则系统将批量提交类型变更为useAndJudgeAffectRows。也可以失效乐观锁,让系统不做批量提交类型变更处理。

二、乐观锁(举例)

在一些会碰到并发修改的数据,往往需要进行并发控制,一般数据库层面有两种一种是悲观锁、一种是乐观锁。oinone对乐观锁进行了良好支持

定义方式

乐观锁的两种定义方式:

  • 通过快捷继承VersionModel,构建带有乐观锁,唯一编码code且主键为id的模型。

  • 可以在字段上使用@Field.Version注解来标识该模型更新数据时使用乐观锁

如果更新的实际影响行数与入参数量不一致,则会抛出异常,错误码为10150024。如果是批量更新数据,为了返回准确的实际影响行数,批量更新由批量提交改为循环单条数据提交更新,性能有所损失。

失效乐观锁

一个模型在某些场景下需要使用乐观锁来更新数据,而另一些场景不需要使用乐观锁来更新数据,则可以使用以下方式在一些场景下失效乐观锁。更多元位指令用法详见4.1.9【函数之元位指令】一文。

PamirsSession.directive().disableOptimisticLocker();
try{
    更新逻辑
} finally {
    PamirsSession.directive().enableOptimisticLocker();
}

图4-1-5-3 失效乐观锁

不抛乐观锁异常

将批量提交类型设置为useAffectRows即可,这样可改由外层逻辑对返回的实际影响行数进行自主判断。

Spider.getDefaultExtension(BatchApi.class).run(() -> {
    更新逻辑,返回实际影响行数
}, BatchCommitTypeEnum.useAffectRows);

图4-1-5-4 将批量提交类型设置为useAffectRows

构建第一个VersionModel

Step1 新建PetItemInventroy模型,继承快捷模型VersionModel

package pro.shushi.pamirs.demo.api.model;

import pro.shushi.pamirs.meta.annotation.Field;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.base.common.VersionModel;

import java.math.BigDecimal;

@Model.model(PetItemInventroy.MODEL_MODEL)
@Model(displayName = "宠物商品库存",summary="宠物商品库存",labelFields = {"itemName"})
public class PetItemInventroy extends VersionModel {
    public static final String MODEL_MODEL="demo.PetItemInventroy";

    @Field(displayName = "商品名称")
    private String itemName;

    @Field(displayName = "库存数量")
    private BigDecimal quantity;

}

图4-1-5-5 新建PetItemInventroy模型

Step2 修改DemoMenu,增加访问入口

@UxMenu("商品库存")@UxRoute(PetItemInventroy.MODEL_MODEL) class PetItemInventroyMenu{}

图4-1-5-6 修改DemoMenu

Step3 重启看效果

体验一:页面上新增、修改数据库字段中的opt_version会自动加一

image.png

图4-1-5-7 示例效果一

image.png

图4-1-5-8 示例效果二

image.png

图4-1-5-9 示例效果三

image.png

图4-1-5-10 示例效果四

体验二:同时打两个页面,依次点击,您会发现一个改成功,一个没有改成功。但页面都没有报错,只是update返回影响行数一个为1,另一个为0而已。

image.png

图4-1-5-11 编辑宠物商品库存

image.png

图4-1-5-12 宠物商品库存列表

注:增加了乐观锁,我们在写代码的时候一定要注意,单记录更新操作的时候要去判断返回结果(影响行数),不然没改成功,程序是不会抛错的。不像batch接口默认会报错

Step4 预留任务:重写PetItemInventroy的update函数

留个任务,请各位小伙伴自行测试玩玩,这样会更有体感

package pro.shushi.pamirs.demo.core.action;

import org.springframework.stereotype.Component;
import pro.shushi.pamirs.demo.api.enumeration.DemoExpEnumerate;
import pro.shushi.pamirs.demo.api.model.PetItemInventroy;
import pro.shushi.pamirs.demo.api.model.PetTalent;
import pro.shushi.pamirs.meta.annotation.Function;
import pro.shushi.pamirs.meta.annotation.Model;
import pro.shushi.pamirs.meta.common.exception.PamirsException;
import pro.shushi.pamirs.meta.constant.FunctionConstants;
import pro.shushi.pamirs.meta.enmu.FunctionOpenEnum;
import pro.shushi.pamirs.meta.enmu.FunctionTypeEnum;

import java.util.ArrayList;
import java.util.List;

@Model.model(PetItemInventroy.MODEL_MODEL)
@Component
public class PetItemInventroyAction {

    @Function.Advanced(type= FunctionTypeEnum.UPDATE)
    @Function.fun(FunctionConstants.update)
    @Function(openLevel = {FunctionOpenEnum.API})
    public PetItemInventroy update(PetItemInventroy data){
        List<PetItemInventroy> inventroys = new ArrayList<>();
        inventroys.add(data);
        //批量更新会,自动抛错
        int i = data.updateBatch(inventroys);
        //单记录更新,不自动抛售需要自行判断
//        int i = data.updateById();
//        if(i!=1){
//            throw PamirsException.construct(DemoExpEnumerate.PET_ITEM_INVENTROY_UPDATE_VERSION_ERROR).errThrow();
//        }
        return data;
    }

}

图4-1-5-13 重写PetItemInventroy的update函数

注意事项:

如果是自定义页面需要把optVersion字段配置到视图的xml中去,可以配置为隐藏 。例子中因为默认页面已经自动带上了optVersion,所以容易被人忽视掉。

Oinone社区 作者:史, 昂原创文章,如若转载,请注明出处:https://doc.oinone.top/oio4/9280.html

访问Oinone官网:https://www.oinone.top获取数式Oinone低代码应用平台体验

Like (0)
史, 昂's avatar史, 昂数式管理员
Previous 2024年5月23日 am8:58
Next 2024年5月23日

相关推荐

  • 4.5 研发辅助

    这里都是一些提升研发效率的小工具

    Oinone 7天入门到精通 2024年5月23日
    1.6K00
  • 4.1.6 模型之元数据详解

    介绍Model相关元数据,以及对应代码注解方式。大家还是可以通读并练习每种不同的使用方式,这个是oinone的设计精华所在。当您不知道如何配置模型、字段、模型间的关系、以及枚举都可以到这里找到。 一、模型元数据 安装与更新 使用@Model.model来配置模型的不可变更编码。模型一旦安装,无法在对该模型编码值进行修改,之后的模型配置更新会依据该编码进行查找并更新;如果仍然修改该注解的配置值,则系统会将该模型识别为新模型,存储模型会创建新的数据库表,而原表将会rename为废弃表。 如果模型配置了@Base注解,表明在studio中该模型配置不可变更;如果字段配置了@Base注解,表明在studio中该字段配置不可变更。 注解配置 模型类必需使用@Model注解来标识当前类为模型类。 可以使用@Model.model、@Fun注解模型的模型编码(也表示命名空间),先取@Model.model注解值,若为空则取@Fun注解值,若皆为空则取全限定类名。 模型元信息 模型的priority,当展示模型定义列表时,使用priority配置来对模型进行排序。 模型的ordering,使用ordering属性来配置该模型的数据列表的默认排序。 模型元信息继承形式: 不继承(N) 同编码以子模型为准(C) 同编码以父模型为准(P) 父子需保持一致,子模型可缺省(P=C) 注意:模型上配置的索引和唯一索引不会继承,所以需要在子模型重新定义。数据表的表名、表备注和表编码最终以父模型配置为准;扩展继承父子模型字段编码一致时,数据表字段定义以父模型配置为准。 名称 描述 抽象继承 同表继承 代理继承 多表继承 基本信息 displayName 显示名称 N N N N summary 描述摘要 N N N N label 数据标题 N N N N check 模型校验方法 N N N N rule 模型校验表达式 N N N N 模型编码 model 模型编码 N N N N 高级特性 name 技术名称 N N N N table 逻辑数据表名 N P=C P=C N type 模型类型 N N N N chain 是否是链式模型 N N N N index 索引 N N N N unique 唯一索引 N N N N managed 需要数据管理器 N N N N priority 优先级,默认100 N N N N ordering 模型查询数据排序 N N N N relationship 是否是多对多关系模型 N N N N inherited 多重继承 N N N N unInheritedFields 不从父类继承的字段 N N N N unInheritedFunctions 不从父类继承的函数 N N N N 高级特性-数据源 dsKey 数据源 N P=C P=C N 高级特性-持久化 logicDelete 是否逻辑删除 P P P N logicDeleteColumn 逻辑删除字段 P P P N logicDeleteValue 逻辑删除状态值 P P P N logicNotDeleteValue 非逻辑删除状态值 P P P N underCamel 字段是否驼峰下划线映射 P P P N capitalMode 字段是否大小写映射…

    2024年5月23日
    1.7K00
  • 4.1.24 框架之分库分表

    随着数据库技术的发展如分区设计、分布式数据库等,业务层的分库分表的技术终将成老一辈程序员的回忆,谈笑间扯扯蛋既羡慕又自吹地说到“现在的研发真简单,连分库分表都不需要考虑了”。竟然这样为什么要写这篇文章呢?因为现今的数据库虽能解决大部分场景的数据量问题,但涉及核心业务数据真到过亿数据后性能加速降低,能给的方案都还有一定的局限性,或者说性价比不高。相对性价比比较高的分库分表,也会是现阶段一种不错的补充。言归正传oinone的分库分表方案是基于Sharding-JDBC的整合方案,所以大家得先具备一点Sharding-JDBC的知识。 一、分表(举例) 做分库分表前,大家要有一个明确注意的点就是分表字段的选择,它是非常重要的,与业务场景非常相关。在明确了分库分表字段以后,甚至在功能上都要做一些妥协。比如分库分表字段在查询管理中做为查询条件是必须带上的,不然效率只会更低。 Step1 新建ShardingModel模型 ShardingModel模型是用于分表测试的模型,我们选定userId作为分表字段。分表字段不允许更新,所以这里更新策略设置类永不更新,并在设置了在页面修改的时候为readonly package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.boot.base.ux.annotation.field.UxWidget; import pro.shushi.pamirs.boot.base.ux.annotation.view.UxForm; import pro.shushi.pamirs.meta.annotation.Field; import pro.shushi.pamirs.meta.annotation.Model; import pro.shushi.pamirs.meta.enmu.FieldStrategyEnum; @Model.model(ShardingModel.MODEL_MODEL) @Model(displayName = "分表模型",summary="分表模型",labelFields ={"name"} ) public class ShardingModel extends AbstractDemoIdModel { public static final String MODEL_MODEL="demo.ShardingModel"; @Field(displayName = "名称") private String name; @Field(displayName = "用户id",summary = "分表字段",immutable=true/* 不可修改 **/) @UxForm.FieldWidget(@UxWidget(readonly = "scene == 'redirectUpdatePage'"/* 在编辑页面只读 **/ )) @Field.Advanced(updateStrategy = FieldStrategyEnum.NEVER) private Long userId; } 图4-1-24-1 新建ShardingModel模型 Step2 配置分表策略 配置ShardingModel模型走分库分表的数据源pamirsSharding 为pamirsSharding配置数据源以及sharding规则 a. pamirs.sharding.define用于oinone的数据库表创建用 b. pamirs.sharding.rule用于分表规则配置 pamirs: load: sessionMode: true framework: system: system-ds-key: base system-models: – base.WorkerNode data: default-ds-key: pamirs ds-map: base: base modelDsMap: "[demo.ShardingModel]": pamirsSharding #配置模型对应的库 图4-1-24-2 指定模型对应数据源 pamirs: sharding: define: data-sources: ds: pamirs pamirsSharding: pamirs #申明pamirsSharding库对应的pamirs数据源 models: "[trigger.PamirsSchedule]": tables: 0..13 "[demo.ShardingModel]": tables: 0..7 table-separator: _ rule: pamirsSharding: #配置pamirsSharding库的分库分表规则 actual-ds: – pamirs #申明pamirsSharding库对应的pamirs数据源 sharding-rules: # Configure sharding rule ,以下配置跟sharding-jdbc配置一致 – tables: demo_core_sharding_model: #demo_core_sharding_model表规则配置 actualDataNodes: pamirs.demo_core_sharding_model_${0..7} tableStrategy: standard: shardingColumn: user_id shardingAlgorithmName: table_inline shardingAlgorithms: table_inline: type: INLINE props: algorithm-expression: demo_core_sharding_model_${(Long.valueOf(user_id) % 8)} props: sql.show: true 图4-1-24-3 分库分表规则配置 Step3 配置测试入口 修改DemoMenus类增加一行代码,为测试提供入口 @UxMenu("分表模型")@UxRoute(ShardingModel.MODEL_MODEL) class ShardingModelMenu{} 图4-1-24-4 配置测试入口 Step4 重启看效果 自行尝试增删改查 观察数据库表与数据分布 图4-1-24-5 自行尝试增删改查 图4-1-24-6 观察数据库表与数据分布 二、分库分表(举例) Step1 新建ShardingModel2模型 ShardingModel2模型是用于分库分表测试的模型,我们选定userId作为分表字段。分库分表字段不允许更新,所以这里更新策略设置类永不更新,并在设置了在页面修改的时候为readonly package pro.shushi.pamirs.demo.api.model; import pro.shushi.pamirs.boot.base.ux.annotation.field.UxWidget; import pro.shushi.pamirs.boot.base.ux.annotation.view.UxForm; import…

    2024年5月23日
    1.6K00
  • 2.1 数字化时代软件业的另一个本质变化

    随着企业从信息化向数字化转变,软件公司提供的产品也由传统的企业管理软件向企业商业支撑软件发展。这一变化带来了许多技术上的挑战和机遇。在之前的章节中,我们提到企业的视角已经从内部管理转向业务在线和生态在线协同,这也带来了一系列新的需求。但是,我们常常会忽视这一变化所带来的对系统要求的变化。在本章中,我们将探讨这些技术上的变化,以及这些变化所带来的机遇和挑战。 图2-1 从信息化到数字化软件本质变化 在信息化时代,企业的业务围绕着内部管理效率展开,借鉴国外优秀的管理经验,企业将其管理流程固化下来,典型的例子是ERP项目。这类项目上线后往往长期稳定,不轻易更改,因此信息化时代软件的技术流派侧重于通过模型对业务进行全面支持。例如,SAP具有丰富的配置能力,将已有企业管理思想抽象到极致。其功能基本上可以通过配置来实现,因此其模型设计特别复杂。但是,我们也应该清楚地了解到,配置是面向已知问题的。在数字化时代,创新和业务迭代速度非常快,这种方法可能就不太适合了。我们知道,模型抽象是在设计时具有前瞻性的,一旦不适合,修改起来就会异常困难。 随着数字化时代的到来,企业主的关注点已经从单一企业内部管理转变为了围绕企业上下游价值链的协同展开。这种变化给企业信息化系统提出了更高的要求,例如业务需求的响应速度、系统性能和用户体验等方面。现在,企业对软件不仅是管理需求的承载,更是业务在线化的承载。传统的重模型设计软件模式已经不再适用,因为业务本身不断创新和变化。因此,数字化时代需要新的软件技术流派,这种流派必须是轻模型加上低代码技术的结合体。通过模型抽象80%的通用场景,剩余的20%个性化需求可以通过技术手段来完成。这样的设计可以让每家企业的研发人员轻松理解模型,而不像ERP模型那样异常复杂,无法进行修改。此外,配合低代码技术可以快速研发和上线。如果说配置化是面向已知问题的,那么低代码就是面向未知问题设计的。虽然低代码的概念可以追溯到上个世纪80年代,当时是为了满足企业内部部门之间有协同需求,但又没有专业软件支撑,定制化开发又不划算的辅助场景。但现在它的核心原因是企业数字化的核心场景不稳定,变化很快,每家企业都有强烈的个性化需求。因此,低代码成为解决这些问题的核心手段,数字化时代的低代码需要具备处理复杂场景的能力,而不仅仅是围绕着内部管理展开。 企业在数字化转型的过程中需要考虑到不仅是成熟的全链路业务解决方案,还要应对数字化场景的快速变化和持续创新的需求。为此,Oinone打造了一站式低代码商业支撑平台,从业务与技术两个维度来帮助企业建立开放、链接、安全的数字化平台。这将在水平和垂直两个维度上全面推动企业数字化转型。 另外,低代码的另一个好处是完成了软件本身的数字化建设。通过基于元数据设计,元数据成为软件中数据、逻辑和交互的数据,软件结合AI可以有更多的创造可能。想象一下,AI了解软件的元数据后可以自我运作,人在极少情况下才需要参与,人机交互也会发生大的改变。未来的软件交互不再需要研发提前预设,而是能够实现用户所需即所呈现的效果。作为一家帮助企业进行数字化转型的软件公司,请问您的数字化转型是否已经完成呢?

    2024年5月23日
    1.6K00
  • 登录日志

    1. 登录日志 登录日志:记录企业成员/用户登录平台的历史明细,包括登录时间、位置、IP、登录设备、登录平台等信息,登录平台包括:PC Web、小程序、H5、APP。登录日志不需要通过审计规则订阅,平台会记录每位用户的登录日志。 操作支持导出、查看详情。

    2024年6月20日
    1.6K00

Leave a Reply

Please Login to Comment