Spring Boot:具有2个连续括号的Custome @Query导致忽略一对

时间:2017-08-11 07:49:37

标签: spring-boot spring-data-jpa

在我的JpaRepository中,我跟随@Query:

@Query("SELECT m FROM Msg m WHERE ((m.from = ?1 AND m.to = ?2) OR (m.from = ?2 AND m.to = ?1))  AND m.time = ?3")
Msg find(String firstId, String secondId, long lastAccess);

但是在日志控制台中,这个查询是在没有上括号的情况下记录的,而且似乎是这样执行的:

SELECT m FROM Msg m WHERE (m.from = ?1 AND m.to = ?2) OR (m.from = ?2 AND m.to = ?1)  AND m.time = ?3

那么如何正确添加多个连续括号?

我用:

德比

Spring Boot 1.4.3.RELEASE

1 个答案:

答案 0 :(得分:2)

我使用Spring Boot 1.4.3-RELEASE 1.5.4-RELEASE 进行了一些小调查,其中包含两个依赖项:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>

<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

我已经模仿你的JpaRespository:

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

interface PersonRepository extends JpaRepository<Person, Long> {

    @Query("SELECT p FROM Person p WHERE ((p.firstName = :firstName AND p.lastName = :lastName) OR (p.firstName = :lastName AND p.lastName = :firstName)) AND p.age = :age")
    Person findWithCustomQuery(@Param("firstName") String firstName, @Param("lastName") String lastName, @Param("age") Integer age);
}

这是Person类的样子:

import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;

@Entity
@Builder
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Person {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    private String firstName;

    private String lastName;

    private Integer age;
}
  

以下是完整的源代码:https://github.com/wololock/stackoverflow-answers/tree/master/45629734

我看到执行的SQL查询如下:

select person0_.id as id1_0_, person0_.age as age2_0_, person0_.first_name as first_na3_0_, person0_.last_name as last_nam4_0_ from person person0_ where (person0_.first_name=? and person0_.last_name=? or person0_.first_name=? and person0_.last_name=?) and person0_.age=?

正如您所见,括号中的简化为

(person0_.first_name=? and person0_.last_name=? or person0_.first_name=? and person0_.last_name=?)

但它仍然正确,因为and运算符的优先级高于or运算符。

需要更多信息

我很乐意帮助您找到问题的解决方案,但我需要更多信息,例如

  • 你使用什么数据库(我在这个例子中使用H2,很明显不同的SQL方言可能会生成不同的查询)
  • 您使用的是什么版本的Spring Boot?
  • 您使用的是什么版本的Spring Data?