【问题标题】:How best to process dynamic query parameters using Java & Spring如何最好地使用 Java 和 Spring 处理动态查询参数
【发布时间】:2020-02-28 15:25:32
【问题描述】:

问题:

我有一个处理多个查询参数的 api 端点。使用Spring实现,查询参数用于从postgres数据库中查询数据,我使用JDBC Template查询。

我正在寻找一种成熟的查询生成器技术来解决我的问题。

示例:

一个简单的查询可能看起来像这样:

api/book?name=LOTR&cover=hardback

将查询参数添加到地图中,并根据地图数据构建查询字符串:

String sqlQuery += (String) map.entrySet().stream()
            .map(entry -> entry.getKey() + "='" + entry.getValue() + "' AND ")
            .collect(Collectors.joining());

这不是最有效的,因为我必须始终从字符串中删除结尾的 "AND" 子句,但它确实有效。

但是,如果查询在哪里看起来像

api/book?name=LOTR&name=Ulysses&cover=hardback

现在添加了"OR" 子句,上面的代码无法处理。我可以看到自己很快就进入了使用繁琐的字符串解析来创建 SQL 语句的领域。

既然我已经提出了我的问题,我想知道是否有一种技术可以很好地处理这种问题?

我想避免在这个项目中使用任何 ORM,所以 Hibernate 和 MyBatis 是不可能的。我查看了一些 JOOQ 示例,但它们看起来与 JDBC 模板不兼容。

【问题讨论】:

    标签: sql spring postgresql http query-parameters


    【解决方案1】:

    对于琐碎的实现,例如您必须在构建查询后删除最后一个 AND 的第一种情况,有一个简单的技巧 - 在您添加 1 = 1 之后立即添加,然后为每个 WHERE 谓词添加 AND [COLUMN] = [价值]。

    注意:大多数数据库在执行前会优化 WHERE 子句中常​​量的使用,因此性能不会成为问题

    /*
      select <columns> from <tables> where 1 = 1
      [dynamically built Where predicates will come here from following code] 
    */
    
    String sqlQuery += (String) map.entrySet().stream()
        .map(entry -> "AND " + entry.getKey() + "='" + entry.getValue() + "'")
        .collect(Collectors.joining());
    

    但是,对于严肃的生产实现,您可能希望使用 myBatis 之类的框架,它可以让您对查询进行模板化,然后在运行时传递参数以构建最终查询。

    你可以找到一个很好的教程here

    /* An example */
    <select id = "getName_Id_phone" parameterType = "Student" resultType = "Student">
       SELECT * FROM STUDENT    
       <where>
          <if test = "id != null">
             id = #{id}
          </if>
          <if test = "name != null">
             AND name LIKE #{name}
          </if>
       </where>     
    </select>
    

    【讨论】:

      【解决方案2】:

      带着同样的问题来到这里。也许你想看看RSQL 1

      【讨论】:

      • 请在您的回答中提供更多详细信息。不仅仅是一个链接。
      猜你喜欢
      • 1970-01-01
      • 2010-09-26
      • 2020-03-08
      • 1970-01-01
      • 1970-01-01
      • 2021-12-05
      • 1970-01-01
      • 1970-01-01
      • 2020-10-03
      相关资源
      最近更新 更多