【问题标题】:Passing entire where clause to native spring jpa @Query [duplicate]将整个where子句传递给本机spring jpa @Query [重复]
【发布时间】:2019-11-13 10:55:49
【问题描述】:

目前,在我的 spring @Query 中创建本机 SQL 时,我无法知道 SQL where 子句(想想 adhoc)中的字段。因此,我传递了整个 where 子句。

如果我将 SQL 输出到控制台并将其粘贴到我的 sql 编辑器中,我就能收到一个有效的结果集。

SELECT * FROM lorder WHERE order_id = 1196077

到控制台的最后一个 SQL 输出是: 休眠:

/* dynamic native SQL query */ SELECT
    * 
FROM
    lorder 
WHERE
    ?
and the where clause value being passed in to the @query is:
order_id = 1196077

这是我目前正在做的,但不起作用。

@Query(
    value = "SELECT * FROM lorder WHERE :where",
    nativeQuery = true)
List<OrderEntity> listSelected(@Param("where") String where);  

不确定是否可以传递整个 where 子句,但我期待一个列表。但是我目前得到的是一个空集合。

【问题讨论】:

  • 我无法理解您想要实现的目标,以及为什么您使用本机查询而不是 JPQL 查询。如果您尝试执行动态创建的查询,请使用条件 API 或 QueryDSL。这就是他们的目的。如果你想用一个方法来执行几个不同的静态查询,千万不要这样做:它会导致无法测试该方法,多次重用它,使代码不清晰,测试更脆弱。跨度>
  • 谢谢 JB。我将其更改为使用 Query query = entityManager.createQuery("Select...)
  • 查看 Spring Data JPA 中的 JpaSpecificationExecutor&lt;T&gt;Specification&lt;T&gt;

标签: java spring-data-jpa


【解决方案1】:

由于使用@Query注解你只能使用命名参数(你的:where)或序数参数(例如?1,?2)特定的 Java 类型,不能注入部分 SQL 表达式。

但是您可以使用 TypedQuery 将部分 SQL 添加到查询中:

  public List<OrderEntity> getOrdersUsingWhereClause(EntityManager em, String whereClause) {
    TypedQuery<OrderEntity> query = em.createQuery(
        "SELECT o FROM lorders o WHERE " + whereClause,
        OrderEntity.class);
    return query.getResultList();
  }

https://www.objectdb.com/java/jpa/query/parameter#Parameters_vs.Literals

【讨论】:

  • 我相信需求本身因此答案很容易受到sql注入,除非你在外层处理这种攻击
  • @Jayr 完全同意。这是 OP 必须意识到的权衡取舍:security(受到潜在 sql-injection 的威胁)VS flexibility(通过简单地注入用户定义的 sql-partials 获得)。继续并通过询问这些值得考虑的进一步要求来评论原始帖子。
【解决方案2】:

JPA 的条件查询使您可以更强大地控制 where 子句以及许多其他受支持的功能。

函数列表:https://en.wikibooks.org/wiki/Java_Persistence/Criteria

条件查询:https://www.baeldung.com/hibernate-criteria-queries

详细了解条件查询和条件生成器here

【讨论】:

  • 使用 Criteria Queries 是一种可行的方法,它具有安全优势(禁止 SQL 注入)但限制了灵活性在运行时只允许在设计时编码的 WHERE 条件。超级你提供这些链接来学习。继续并添加一些代码来尝试解决所提出的具体问题:-)
猜你喜欢
  • 2016-11-26
  • 2015-09-20
  • 1970-01-01
  • 1970-01-01
  • 2018-06-22
  • 1970-01-01
  • 1970-01-01
  • 2011-09-10
相关资源
最近更新 更多