深度分页问题优化方案

问题原因

Mysql使用select * from table limit offset, rows分页在深度分页的情况下, 性能急剧下降。

例如:select * 的情况下直接⽤limit 600000,10 扫描的是约60万条数据,并且是需要回表 60W次,也就是说⼤部分性能都耗在随机访问上,到头来只⽤到10条数据(总共取600010条数据只留10条记录)

优化方案

前端方案:业务层面限制跨度比较大的跳页

提供2种风格分页器供用户选择

  1. 标准分页器,展示最后一页和跳转指定页输入框
    image.png
  2. 简单分页器
    image.png

参考
百度方案: 不展示最后一页和直接跳转指定分页的输入框
image.png
Google方案:只展示查看下一页的按钮
image.png

界面设计器选表格/画廊的属性面板提供分页器风格的属性下拉选择

image.png

xml示例
<!-- 表格使用的标准分页器 --> <view type="TABLE" paginationStyle="SIMPLE"> <!-- fields --> </view> <!-- 画廊使用默认的标准分页器 --> <view type="GALLERY" paginationStyle="STANDARD"> <!-- fields --> </view>

后端方案

  1. 使用索引:确保数据库表中的相关字段上创建了适当的索引。索引可以加快查询速度,特别是在处理大数据量时。

  2. 分批查询:将大数据分成多个较小的批次进行查询,而不是一次性查询全部数据。可以通过限制每次查询的数据量和使用合适的偏移量来实现分批查询,例如使用LIMIT和OFFSET子句。

  3. 基于游标的分页:使用基于游标的分页技术,而不是传统的偏移分页。游标分页是通过记录上一次查询的游标位置,在下一次查询时从该位置开始获取新的数据,避免了大偏移量的影响。这可以通过数据库自身的功能(例如MySQL的CURSOR)或使用第三方库来实现。

  4. 缓存数据:如果数据变化较少,可以考虑将查询结果缓存到内存中,以避免频繁地查询数据库。这样可以提高页面相应速度,并减轻数据库负担。缓存的数据应该根据业务需要及时更新。

  5. 数据预处理:如果查询结果经常需要进行复杂的计算或处理,可以考虑提前对数据进行预处理并缓存结果,以减少每次查询的计算负担。

  6. 数据库优化:针对具体数据库系统,可以根据实际情况进行数据库调优。例如,合理设置数据库连接池大小、调整数据库参数等。

  7. 分布式存储和计算:对于非关系型数据库或分布式存储系统,可以考虑使用分布式存储和计算方案,将数据分散存储在多个节点上,并通过计算节点并行处理查询请求,以提高性能和可伸缩性。

参考链接

MySQL深分页场景下的性能优化

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

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

(0)
的头像
上一篇 2023年6月20日 pm4:07
下一篇 2023年11月2日 pm1:58

相关推荐

  • 6.4 国际化之多语言

    多语言是国际化中大家最常面对的问题,我们需要对应用的页面结构元素进行翻译,也需要对系统内容进行翻译比如:菜单、数据字典等,甚至还会业务数据进行翻译。但不管什么翻译需求,我们在实现上基本可以归类为前端翻译和后端翻译。前端翻译顾名思义是在前端根据用户选择语言对内容进行翻译,反之就是后端翻译。本文会带着大家了解oinone的前端翻译与后端翻译 准备工作 pamirs-demo-boot的pom文件中引入pamirs-translate包依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-translate</artifactId> </dependency> pamirs-demo-boot的application-dev.yml文件中增加配置pamirs.boot.modules增加translate,即在启动模块中增加translate模块 pamirs: boot: modules: – translate 后端翻译(使用) 这里通过对菜单的翻译来带大家了解翻译模块 Step1 新增翻译记录 切换应用到translate模块,点击新增翻译。 选择新增翻译生效模块 选择翻译的模型为:菜单模型 源语言选择中文,目标选择English 添加翻译项目: 源术语为:商店 翻译值为:shop 状态为:激活 Step2 查看效果 应用切换到Demo模块,在右上角切换语言至英语 后端翻译(自定义模型的翻译) 在前面菜单的翻译中,似乎我们什么都没做就可以正常通过翻译模块完成多语言的切换了。是不是真如我们想象的一样,当然不是。是因为Menu模型的displayName字段加上@Field(translate = true)注解。 Step1 为PetType模型的name字段增加翻译注解 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.IdModel; @Model.MultiTable(typeField = "kind") @Model.model(PetType.MODEL_MODEL) @Model(displayName="品种",labelFields = {"name"}) public class PetType extends IdModel { public static final String MODEL_MODEL="demo.PetType"; @Field(displayName = "品种名" , translate = true) private String name; @Field(displayName = "宠物分类") private String kind; } Step2 重启应用查看效果 切换应用到translate模块,点击新增翻译 切换应用到Demo模块,切换中英文,查看效果 前端翻译 还记得我们前端第一个自定义动作吗?会弹出“oinone第一个自定义Action,啥也没干”,我们要对它进行翻译。 Step1 修改前端DoNothingActionWidget.ts import translateValueByKey 提示语用translateValueByKey加上翻译 const confirmRs = executeConfirm(translateValueByKey(\’oinone第一个自定义Action,啥也没干\’)||\’oinone第一个自定义Action,啥也没干\’); 前端更多翻译工具请见前端高级特性-框架之翻译工具 import { Action, ActionContextType, ActionWidget, executeConfirm, IClientAction, SPI, ViewType, Widget, translateValueByKey } from '@kunlun/dependencies'; @SPI.ClassFactory(ActionWidget.Token({ name: 'demo.doNothing' })) export class DoNothingActionWidget extends ActionWidget { @Widget.Method() public async clickAction() { const confirmRs = executeConfirm(translateValueByKey('oinone第一个自定义Action,啥也没干')||'oinone第一个自定义Action,啥也没干'); } } //定义动作元数据 Action.registerAction('*', { displayName: '啥也没干', name: 'demo.doNothing', id: 'demo.doNothing', contextType: ActionContextType.ContextFree, bindingType: [ViewType.Table] } as IClientAction); Step2 新增翻译记录 前端翻译的翻译记录对应的模型可以随意找一个放。但要注意几点: 不要找有字读配置translate = true的模型,因为会影响后端翻译性能。 最好统一到一个模型中,便于后续管理。这里大家可以自定义一个无有业务访问且本身无需要翻译的模型来挂载,避免性能损失 Step3 刷新远程资源生成前端语言文件 Step4 新增或修改.env 前端在项目根目录下新增或修改.env,可以参考.env.example文件。通过.env文件为前端配置oss文件路径,针对I18N_OSS_URL配置项。真实前端访问翻译语言文件的路径规则为:http://bucket.downloadUrl/mainDir/租户/translate/模块/语言文件。 yaml文件中oss配置的文件路径:http://pamirs.oss-cn-hangzhou.aliyuncs.com/upload/demo/ 租户/translate/模块/语言文件 前端会自动根据上下文组织 # 后端api配置 # API_BASE_URL=http://127.0.0.1:8090 # 下面是国际化语言的cdn配置,默认用当前请求链接下的路径: /pamirs/translate/${module}/i18n_${lang}.js I18N_OSS_URL=http://pamirs.oss-cn-hangzhou.aliyuncs.com/upload/demo Step5 重启前端应用看效果 对语言进行中英文切换,进入宠狗达人页面,点击【第一个自定义Action】,查看前端翻译效果

    2024年5月23日
    1.8K20
  • SSO单点登录(5.3.x — 6.2.x)

    SSO相关 1、SSO服务端:在应用中找到【单点登录】,创建一个应用标识2、SSO登录认证,选择grant_type=password,后面带上用户名和密码。参考下面的链接(POST请求):http://127.0.0.1:8190/pamirs/sso/authorize?redirect_uri=http://127.0.0.1:8193/page;module=ysps;model=ysps.notify.ProjectPosting;action=homepage;scene=homepage;target=OPEN_WINDOW;path=/ysps/homepage&response_type=code&client_id=替换为已创建的应用唯一标识&grant_type=password&username=admin&password=admin 其中: redirect_uri是认证通过后的跳转,目前的场景可忽略 client_id替换为在单点登录也上创建的应用唯一标识 认证方式grant_type=password固定,后面是实际的用户名和密码 操作步骤: 请求服务端工程SSO登录认证,会返回token信息,拿着这个信息去客户端工程访问即可。 请求服务端工程返回token信息: curl –location –request POST ‘http://127.0.0.1:8190/pamirs/sso/authorize’ \ –header ‘User-Agent: Apifox/1.0.0 (https://apifox.com)’ \ –header ‘Accept: */*’ \ –header ‘Host: 127.0.0.1:8190’ \ –header ‘Connection: keep-alive’ \ –header ‘Content-Type: application/x-www-form-urlencoded’ \ –header ‘Cookie: pamirs_uc_session_id=88fd2459446a4a20ab0a505bdaf78ebe’ \ –data-urlencode ‘appkey=1d2195bac42e44e895ea8e030aaa4e52’ \ –data-urlencode ‘appSecret=JNEyibFBIb2N3tdLmW/M9bnpf120/I6fFMMf86OQlP/wlL5qhJCF3KdAKHlJT0jECmXmJRfTCSlnmB5cWHRsenNGND+TMoXObzDPK7umxazCnaZYiW7JDeuZUOzqskhBPkEJSURAZR5xu1c6UYv542BlHAPsEi+ujnKeCYcKiFHyw7fIB1aijNyCz8d9teUEGYYTtYTXoNp/4Ts8AIJn8xkTjvEq6V9uYOExDEuYGxMgN76ZaiwpbT5387eZy4XCDIy0XWfZo/kv7X+s+rjwlsxWA7jp1w5dDaRmSd4rPO2GSEcL64Pje/Ct5xznhNwH6T5KDd2BLfbZikonh624nqW4hdlVxx/EQUpYp6Yc4Wet6b/DkggCVIZPpcO9pSuRJoC2jGPMrGHM3vYR0YtfFqCJ2/x3m/lQr2v+bP4pGzcRuuCy2tyOZA1uurA23xlssehz4geGiJArkpAUKKUkcafx+dLWODHOcgBKBz6wY38PAcbLkgn6gK6lmmR7cUiDmzmEEor6pYb64YG6tPmpm4AQeBoQYrsyCorA4Ds08nAiPFWUCXcHQCVUbHPTOwHHChFO1lXH/VjkfDv0OI1CD8mZI7ZeK794aIBZdvQGCI+ayQU+5CD1asDNg/M01nnNdWKB7rS9rMvbUOlSNguboAgRbiz3pEAxGJrZUPvkDHM=’ { “access_token”: “eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3NDQyNTk2MTcsInN1YiI6IntcImNsaWVudElkXCI6XCJwYW1pcnNfMjc5YjcwMDBlNDE3NDMxMmFmNDAyMDM0YjhlZjFhOWRcIixcInJhbmRvbUFrSWRcIjpcIjM0MDBiYzY0Njk1MzQzODA4ZTlhNmZhNWRmZjU0MTc2XCIsXCJvcGVuSWRcIjpcIjEwMDAxXCJ9In0.iJ-meyxAGW189Y3aK9Z2rMbf9_MsTKVTfnf3XsDR4iq6qvCGYkiq5197r4A54wwdKAzPZ-iDgkQOjWDh8AYu4A”, “token_type”: null, “refresh_token”: “eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3NDQ4NTcyMTcsInN1YiI6IntcImRhdGVUaW1lXCI6XCIxNzQ0MjUyNDE3NDc3XCIsXCJjbGllbnRJZFwiOlwicGFtaXJzXzI3OWI3MDAwZTQxNzQzMTJhZjQwMjAzNGI4ZWYxYTlkXCIsXCJvcGVuSWRcIjpcIjEwMDAxXCJ9In0.TZaK8OuPKudd3YX6AF23m7aplJF7OQlBEDkj0AnPkQdw7aja2WhS7q-VwjPfhqSmfAp-oaaUIcN7Zlune9VLTA”, “expires_in”: 7200, “refresh_token_expiresIn”: 604800 } 发起客户端工程请求。 注意:请求Headers中需携带token参数信息,token为服务端工程返回token信息,且请求时Authorization参数需加上标识 Bearer+空格 –header 'loginType: OAUTH' –header 'Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3NDQyMDYwNjUsInN1YiI6IntcImNsaWVudElkXCI6XCJwYW1pcnNfMjc5YjcwMDBlNDE3NDMxMmFmNDAyMDM0YjhlZjFhOWRcIixcInJhbmRvbUFrSWRcIjpcImEzZWZkNjZkMDNlNjQ5MDY4OGU4Y2FhYmIwNjZmZGU4XCIsXCJvcGVuSWRcIjpcIjEwMDAxXCJ9In0.gapCpvM8PCit1oSHv-zJ2tATkCuVQBzqWGebvBcUX2O0bqP9aAhVqQxdNLM19vCqP5s3CXoNk-xzMUu-mo-hSg' curl –location –request POST ‘http://127.0.0.1:8092/pamirs/base’ \ –header ‘loginType: OAUTH’ \ –header ‘Authorization: Bearer eyJhbGciOiJIUzUxMiJ9.eyJleHAiOjE3NDQyMDYwNjUsInN1YiI6IntcImNsaWVudElkXCI6XCJwYW1pcnNfMjc5YjcwMDBlNDE3NDMxMmFmNDAyMDM0YjhlZjFhOWRcIixcInJhbmRvbUFrSWRcIjpcImEzZWZkNjZkMDNlNjQ5MDY4OGU4Y2FhYmIwNjZmZGU4XCIsXCJvcGVuSWRcIjpcIjEwMDAxXCJ9In0.gapCpvM8PCit1oSHv-zJ2tATkCuVQBzqWGebvBcUX2O0bqP9aAhVqQxdNLM19vCqP5s3CXoNk-xzMUu-mo-hSg’ \ –header ‘User-Agent: Apifox/1.0.0 (https://apifox.com)’ \ –header ‘Content-Type: application/json’ \ –data-raw ‘{“query”:”mutation {\n teacherMutation {\n queryTea(\n data: {id: 672564120180166836, teacherName: \”““`\”, readStatus: NO_READ, createDate: \”2024-11-05 11:30:36\”, writeDate: \”2024-11-05 11:30:36\”, createUid: 10001, writeUid: 10001}\n ) {\n id\n teacherName\n enumType\n petStoreId\n professionalId\n professional {\n professionalName\n id\n }\n readStatus\n nonStoredField\n createDate\n writeDate\n createUid\n writeUid\n }\n }\n}\n”,”variables”:{}}’ SSO服务端工程(5.3.X以上版本支持) 1、服务端工程依赖 1.1 pom依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-sso-oauth2-server</artifactId> </dependency> 1.2 application.yml配置文件里面添加sso启动模块。 pamirs: boot: modules: – sso SSO客户端工程(5.3.X以上版本支持) 1、客户端工程依赖 客户端工程即需要加入SSO的应用 1.1 pom依赖 <dependency> <groupId>pro.shushi.pamirs.core</groupId> <artifactId>pamirs-sso-oauth2-client</artifactId> </dependency> 1.2 application.yml配置 pamirs: sso: enabled: true client: # SSO服务端提供 client-id: pamirs_1fb51c50acbb4842b36844c5fbdc8d25 # SSO服务端提供 client-secret: B3ySNQEJdD8kZXuwmtaUtbWTo1vlIevmd0t4MIqRHfuM8VXzkMcs6YOox6cPPIESAL3yd2xQa+SCBNbLwYchQYSJonGPpvAmqapc5ZdskPicNENc8T2vTAMkc/YgvgUUK4U+/OuP5PrtRKC536nNXIZy1VHdf+whi44qOgd4RQYN0sIrog70CXsDQP3/2CHkcXWVRCqvZa/4mFmL1SBhQ+TLAIQg0jXlWr4lThUdL/X9M0YFXBaLJPKTlKi9l7K/8kTdJL2IgvSpByU0kGXjk0O/jZRBq1bHd/ZsC3Rw4kjiygIdxfL7Q/lw1/WAZ5XXibc5dlylUsnSJBZ9I4ZeCWq7lEZj//ctR7WZJCCeqi8rmCu+N2FQvye7kgiFIoZTFMNSRhW7ZMBBrsoJuf6DGWGvXvBE9w3P/IVFJMDmsopNbbFYTRcmY5e5tc775OCGMQDrW6j8IitTrOdRYzie0S2Jj9+Xw+Va1sEQLXWj0tBNQ9Tzv7fnRr5D6EBNtXra1TntKrvH/quBI5ujncBZXZ2cfEoMjFSw38edoTA8WPJv10WUA5EZsvfxqJLEiXFriJ9nleUBbCvL3Zuggn64CW4cH8mxGk7qvHQvXmwmp8phKyoKa8UDfDD2x7eNW3oNcQUMz+gdGNF5dNXt4iArpYK5/xktpLxdCM5Yz7SpHoc= # login-url和login-url根据实际情况修改 login-url: http://test1.oinone.top:9095/login logout-url: https://test1.oinone.top:9095/pamirs/sso/logout expires:…

    2025年4月25日
    57700
  • 4.1.18 框架之网关协议-Variables变量

    我们在应用开发过程有一种特殊情况在后端逻辑编写的时候需要知道请求的发起入口,平台利用GQL协议中的Variables属性来传递信息,本文就介绍如何获取。 一、前端附带额外变量 属性名 类型 说明 scene String 菜单入口 表4-1-18-1 前端附带额外变量 图4-1-18-1 variables信息中的scene 二、后端如何接收variables信息 通过PamirsSession.getRequestVariables()可以得到PamirsRequestVariables对象。 三、第一个variable(举例) Step1 修改PetTalentAction,获取得到前端传递的Variables package pro.shushi.pamirs.demo.core.action; ……类引用 @Model.model(PetTalent.MODEL_MODEL) @Component public class PetTalentAction { ……其他代码 @Function.Advanced(type= FunctionTypeEnum.QUERY) @Function.fun(FunctionConstants.queryPage) @Function(openLevel = {FunctionOpenEnum.API}) public Pagination<PetTalent> queryPage(Pagination<PetTalent> page, IWrapper<PetTalent> queryWrapper){ String scene = (String)PamirsSession.getRequestVariables().getVariables().get("scene"); System.out.println("scene: "+ scene); ……其他代码 } ……其他代码 } 图4-1-18-2 修改PetTalentAction Step2 重启验证 点击宠物达人不同菜单入口,查看效果 图4-1-18-3 示例效果(一) 图4-1-18-4 示例效果(二)

    2024年5月23日
    1.2K00
  • 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会自动加一 图4-1-5-7 示例效果一 图4-1-5-8 示例效果二 图4-1-5-9 示例效果三 图4-1-5-10 示例效果四 体验二:同时打两个页面,依次点击,您会发现一个改成功,一个没有改成功。但页面都没有报错,只是update返回影响行数一个为1,另一个为0而已。 图4-1-5-11 编辑宠物商品库存 图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 =…

    2024年5月23日
    1.3K00
  • 如何使用源码的方式配置表达式

    自定义占位符定义表达式 数据权限定义表达式: ${thisTeacherName} 界面设计器查询条件定义:$#{thisTeacherName}需要加上#号 以上配置都可以通过查看queryWrapper里面的originRsql查看占位符是否被正确替换。 显隐、过滤条件表达式定义 显隐、过滤都可以加载字段注解里以及xml定义里 显隐: invisible="$!{activeRecord.deadline}" / invisible = true @Field.String @Field(displayName = "视图/页面", invisible = true) private String viewName; 过滤。 domain = " code == ${activeRecord.id} " / domain = "code == '111' " @Field.one2many @Field(displayName = "子订单列表", summary = "子订单列表") @Field.Relation(relationFields = {"code"}, referenceFields = {"code"}, domain = "code != '1234'") private List<ChildOrder> orderList; 更多获取视图数据的写法参考文章上下文在字段和动作中的应用 rsql表达式定义 参考:oinone的rsql与传统sql语法对照表

    2025年3月13日
    85400

Leave a Reply

登录后才能评论