You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Hyperledger Composer可选参数查询问题:动态查询实现求助

Creating a Dynamic Query for QuantityChange with Optional Parameters

Hey there! Let's tackle this dynamic query issue you're facing with your QuantityChange transaction. The goal is to let users pass any number of fields as filter criteria without making all variables required—here's how to approach it:

1. Define the Query with Optional Parameters

First, make sure your query object doesn't enforce required fields. Use nullable types (like wrapper classes for primitives) and avoid mandatory constructors that force all parameters to be provided. For example:

public class FindQuantityChangesQuery {
    // All fields are nullable (no @NotNull annotations)
    private String partNumber;
    private String facilityId;
    private Double quantity; // Use Double instead of double to allow null
    private InvType invType;
    private AppType application;
    private String refDocId;

    // Empty constructor + setters for flexibility
    public FindQuantityChangesQuery() {}

    // Getters and setters for all fields
    public String getPartNumber() { return partNumber; }
    public void setPartNumber(String partNumber) { this.partNumber = partNumber; }
    // ... repeat for other fields
}

2. Build Dynamic Query Logic

In your query handler, only apply filters for parameters that are actually provided (i.e., non-null). Using JPA Criteria API is a great way to do this dynamically:

import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;
import java.util.ArrayList;
import java.util.List;

public class FindQuantityChangesHandler {
    private final EntityManager entityManager;

    public FindQuantityChangesHandler(EntityManager entityManager) {
        this.entityManager = entityManager;
    }

    public List<QuantityChange> handle(FindQuantityChangesQuery query) {
        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<QuantityChange> cq = cb.createQuery(QuantityChange.class);
        Root<QuantityChange> root = cq.from(QuantityChange.class);

        List<Predicate> predicates = new ArrayList<>();

        // Add conditions only for non-null parameters
        if (query.getPartNumber() != null) {
            predicates.add(cb.equal(root.get("partNumber"), query.getPartNumber()));
        }
        if (query.getFacilityId() != null) {
            predicates.add(cb.equal(root.get("facilityId"), query.getFacilityId()));
        }
        if (query.getQuantity() != null) {
            predicates.add(cb.equal(root.get("quantity"), query.getQuantity()));
        }
        if (query.getInvType() != null) {
            predicates.add(cb.equal(root.get("invType"), query.getInvType()));
        }
        if (query.getApplication() != null) {
            predicates.add(cb.equal(root.get("application"), query.getApplication()));
        }
        if (query.getRefDocId() != null) {
            predicates.add(cb.equal(root.get("refDocId"), query.getRefDocId()));
        }

        // Apply all non-null predicates (if any)
        cq.where(predicates.toArray(new Predicate[0]));
        return entityManager.createQuery(cq).getResultList();
    }
}

3. Expose Optional Parameters in Your API

If you're exposing this query via a REST API, ensure each request parameter is marked as optional. For example, in Spring Boot:

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;

@RestController
public class QuantityChangeController {
    private final FindQuantityChangesHandler queryHandler;

    public QuantityChangeController(FindQuantityChangesHandler queryHandler) {
        this.queryHandler = queryHandler;
    }

    @GetMapping("/quantity-changes")
    public List<QuantityChange> getQuantityChanges(
            @RequestParam(required = false) String partNumber,
            @RequestParam(required = false) String facilityId,
            @RequestParam(required = false) Double quantity,
            @RequestParam(required = false) InvType invType,
            @RequestParam(required = false) AppType application,
            @RequestParam(required = false) String refDocId
    ) {
        FindQuantityChangesQuery query = new FindQuantityChangesQuery();
        query.setPartNumber(partNumber);
        query.setFacilityId(facilityId);
        query.setQuantity(quantity);
        query.setInvType(invType);
        query.setApplication(application);
        query.setRefDocId(refDocId);

        return queryHandler.handle(query);
    }
}

4. Handle Edge Cases

  • For numeric fields like quantity, use wrapper types (Double instead of double) so null clearly indicates the parameter wasn't provided (distinct from passing 0).
  • For enum types (invType, application), add validation to return a meaningful error if an invalid value is passed, but ignore the filter if the parameter is omitted.
  • If you're using a different framework (like MongoDB, GraphQL, etc.), the core idea stays the same: make parameters optional and dynamically build the query based on provided values.

This approach lets users pass any combination of fields as filters—no mandatory parameters, no errors when omitting values.

内容的提问来源于stack exchange,提问作者Jeron Sanders

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:50:15