2

我已经为列出项目构建了一个 REST 端点/api/items,它可以通过查询参数传递一些选项来过滤结果。

例如,GET /api/items?minPrice=30&maxPrice=100&minRating=4&onSale=true

如何将其转换为我的 SQL 查询?

如果我收到一个只有 的请求maxPrice=50,那么其他参数呢?让我们假设以下是我的查询 -

select * from items 
where minPrice=(???) and maxPrice=50 and minRating=(???) and onSale=(???)

如果没有任何请求,我如何“忽略”过滤器,只过滤maxPrice=50?有没有一种程序化的方式来做到这一点?

就我而言,我使用的是 postgres,因此我使用 , 等参数化了查询&1&2其中包含每个查询的值。

4

2 回答 2

2

为此,您需要为任何类型的条件编写自定义查询。

通常 ORM 工具做得很好:

对于 Java(Spring 和 JPA),您可以使用标准 api 和一些帮助程序,其中之一是 Spring Data 的规范构建器模式:

Specifications fullSpec = null;
if (param1 != null) {
    fullSpec = Specifications.where(<... criteria condition for param1 ...>);
}

if (param2 != null) { 
    if (fullSpec != null) {
        specs = fullSpec.and(<define condition using criteria api>);
    } else {
        fullSpec = Specifications.where(<same condition for param2>);
    }
}

当您在 NodeJS 上时(从标签来看似乎是真的),您可以使用Sequelize。直接来自它的教程:

var filterObject = {
    minValue: <its value received from request>, 
    maxValue: <its value received from request>, 
    minRating: <its value received from request>, 
    maxRating: <its value received from request>
  };

// filterout null valued properties out of filter
filterObject = _.compactObject(filterObject);

Items.findAll({
  where: filterObject
});

这就是您以安全的方式实现结果所需的全部内容。

此示例使用下划线混合从对象中过滤掉空值,如此响应中所示

您也可以随时按照以下方式编写查询:

var query = 'select * from items where maxPrice=:maxPrice'
if (minPrice) {
    query = query + ' and minPrice=:minPrice'
}
//...
// fill-in all other conditions.
//...
// and then simply query with named parameters.
于 2018-02-16T05:40:58.273 回答
0

如果 REST 调用中未提供这些值,您应该提供有意义的默认值。例如

minValue = 0 
maxValue = <veryHighValue>
minRating = 0
onSale in (true, false)

或者,您可以从这些默认值开始,然后使用 REST 调用提供的值覆盖。

于 2018-02-16T05:19:00.217 回答