• 首页
  • 产品中心
    • 数式Oinone四大产品

      低代码开发平台无代码开发平台集成开发平台AI大模型开发
    • 数式Oinone体系能力

      用户与组织权限管理文件管理消息中心国际化业务审计
    • 数式Oinone核心产品特性

      低无一体面向软件公司场景无限制应用级扩容可分可合
  • 服务中心
    • 客户服务

      预约演示方案咨询私有部署找人定制
    • 开发者

      问答下载
    • Oinone学院

      社区学习

    《精讲面向软件公司的低代码平台——以Oinone为例》

  • 合作伙伴
    渠道申请伙伴名录专家库
  • 关于数式
0571-88757863

Data Operation:Unstored Field Search


Ⅰ、Unstored Field Search

(Ⅰ) Description

When using information outside the current model as search conditions, these fields are often set in the proxy model. This scenario is referred to as unstored field search.

(Ⅱ) Scenario One

The unstored field is of basic string type (String).

  1. Code Definition: The unstored field is a basic wrapper data type
@Field(displayName = "Confirm Password", store = NullableBoolEnum.FALSE)
private String confirmPassword;
  1. Designer Drag-and-Drop: The field needs to be draggable in the list, and the logic for whether the field is hidden is determined by business requirements.
  2. When the page searches using an unstored field as a basic wrapper data type, relevant information is appended to the queryData attribute of queryWrapper. queryData is a Map type where the key is the field name and the value is the search value.
  3. Backend logic processing code example:
Map<String, Object> queryData = queryWrapper.getQueryData();
if (null != queryData) {
    Object productIdObj = queryData.get(PRODUCT_ID);
    if (Objects.nonNull(productIdObj)) {
        String productId = productIdObj.toString();
        queryWrapper.lambda().eq(MesProduceOrderProxy::getProductId, productId);
    }
}

(Ⅲ) Scenario Two

The unstored field is an unstored object.

  1. Defined as unstored
@Field(displayName = "Style", store = NullableBoolEnum.FALSE)
@Field.many2one
@Field.Relation(store = false)
private MesProduct product;
  1. The page drags the unstored field as a search condition in the search bar

3. Backend logic processing code example:

try {
    if (null != queryData && !queryData.isEmpty()) {
        List<Long> detailId = null;
        BasicSupplier supplier = JsonUtils.parseMap2Object((Map<String, Object>) queryData.get(supplierField), BasicSupplier.class);
        MesProduct product = JsonUtils.parseMap2Object((Map<String, Object>) queryData.get(productField), MesProduct.class);
        MesMaterial material = JsonUtils.parseMap2Object((Map<String, Object>) queryData.get(materialField), MesMaterial.class);
        if (supplier != null) {
            detailId = bomService.queryBomDetailIdBySupplierId(supplier.getId());
            if (CollectionUtils.isEmpty(detailId)) {
                detailId.add(-1L);
            }
        }

        if (product != null) {
            List<Long> produceOrderId = produceOrderService.queryProductOrderIdByProductIds(product.getId());
            if (CollectionUtils.isNotEmpty(produceOrderId)) {
                queryWrapper.lambda().in(MesProduceBomSizes::getProduceOrderId, produceOrderId);
            }
        }

        if (material != null) {
            // Find the union of two bom lists
            List<Long> materBomDetailId = bomService.queryBomDetailIdByMaterialId(material.getId());
            if (CollectionUtils.isNotEmpty(detailId)) {
                detailId = detailId.stream().filter(materBomDetailId::contains).collect(Collectors.toList());
            } else {
                detailId = new ArrayList<>();
                if (CollectionUtils.isEmpty(materBomDetailId)) {
                    detailId.add(-1L);
                } else {
                    detailId.addAll(materBomDetailId);
                }
            }
        }
        if (CollectionUtils.isNotEmpty(detailId)) {
            queryWrapper.lambda().in(MesProduceBomSizes::getProductBomId, detailId);
        }
    }
} catch (Exception e) {
    log.error("queryData processing exception", e);
}

Note:

If defined as:

@Field(displayName = "Style",store = NullableBoolEnum.FALSE)
@Field.Relation(relationFields = "produceId", referenceFields = "id",store = false)
@Field.many2one
private MesProduct product;

@Field(displayName = "Style Id",store = NullableBoolEnum.FALSE)
private Long produceId;

When searching, if produceId is selected for product search, produceId will be concatenated into the Rsql of QueryWrapper

Ⅱ、Rsql Parsing Class

pro.shushi.pamirs.framework.gateways.rsql.RSQLHelper

Ⅲ、Rsql Reference Code

/**
     * Rsql parsing: Extract attribute field values from the Rsql in the originRsql attribute of QueryWrapper
     * Replace original conditions with '1'=='1'
     *
     * @param queryWrapper Query Wrapper
     * @param fields       List of attribute fields to be parsed
     * @param valeMap      Map of attribute corresponding values
     * @return List of production order IDs
     */

public static QueryWrapper convertWrapper(QueryWrapper queryWrapper, List<String> fields, Map<String, Object> valeMap) {
    if (StringUtils.isNotBlank(queryWrapper.getOriginRsql())) {
        String rsql = RSQLHelper.toTargetString(RSQLHelper.parse(queryWrapper.getModel(), queryWrapper.getOriginRsql()), new RSQLNodeConnector() {
            @Override
            public String comparisonConnector(RSQLNodeInfo nodeInfo) {
                // Determine if the field is unStored and replace it
                String field = nodeInfo.getField();
                if (fields.contains(field)) {
                    valeMap.put(field, nodeInfo.getArguments().get(0));
                    RSQLNodeInfo newNode = new RSQLNodeInfo(nodeInfo.getType());
                    // Set the query field to "name"
                    newNode.setField("1");
                    newNode.setOperator(RsqlSearchOperation.EQUAL.getOperator());
                    newNode.setArguments(Collections.singletonList("1"));
                    return super.comparisonConnector(newNode);
                }
                return super.comparisonConnector(nodeInfo);
            }
        });
        queryWrapper = Pops.f(Pops.query().from(queryWrapper.getModel())).get();
        // Convert RSQL to SQL
        String sql = RsqlParseHelper.parseRsql2Sql(queryWrapper.getModel(), rsql);
        if (StringUtils.isNotBlank(sql)) {
            queryWrapper.apply(sql);
        }
        return queryWrapper;
    }
    return queryWrapper;
}
Edit this page
Last Updated:1/15/26, 4:02 AM
Prev
Data Operations:Custom SQL (Mapper) Statements
Next
Data Dialect:[DM] Backend Deployment with Dameng Database
默认页脚
Copyright © 2026 Mr.Hope