Spring jpa传递@Param字符串中的保留字

Spring jpa传递@Param字符串中的保留字,spring,spring-data,spring-data-jpa,Spring,Spring Data,Spring Data Jpa,我的目标是编写如下查询: select * from Book where author = any(select author from book) and(genre='comedy') order by ( '' )ASC, ( pages )DESC; 其中“anyselect author from book”丢失了单引号,因此我可以这样传递它 @Query("select b from Book b where b.author =:author and b.genre =:ge

我的目标是编写如下查询:

select * from Book where  author = any(select author from book)
and(genre='comedy') order by ( '' )ASC, ( pages )DESC;
其中“anyselect author from book”丢失了单引号,因此我可以这样传递它

@Query("select b from Book b where b.author =:author and b.genre =:genre")
List<Book> findAllBySearch(@Param("author") String author,
                    @Param("genre") String genre);
这样做的原因是因为我有一个表单,其中有5个输入条件,可能存在,也可能不存在,我不想为每个排列编写单独的查询。我知道一个查询在运行查询之前插入了“stringInput”或“anyselect Criterias from book”的case或null或空字符串

我想使用criteria API或类似的东西可以构建动态查询或插入保留的sql字,但我不知道如何轻松实现它,因为我正在扩展Spring data Crudepository,而不是使用entitymanager。。。。我想我必须这样做

有人知道如何逃避字符串输入@Param强加的错误吗?或者什么方法可以很容易地工作。。。例如标准API、存储过程、函数

请原谅我在这里没有经验

谢谢


看起来,使用5种可能的输入实现这一点的唯一方法是让运行时策略根据存在的输入从14个不同的查询中进行选择,但我试图避免这种情况

所以。。。这是解决办法

/**
 * A JPA-based implementation of the Book Service. Delegates to a JPA entity
 * manager to issue data access calls against the backing repository. The
 * EntityManager reference is provided by the managing container (Spring)
 * automatically.
 */
@Service("bookService")
@Repository
public class JpaBookService implements BookService {

private EntityManager em;

@PersistenceContext
public void setEntityManager(EntityManager em) {
    this.em = em;
}

public List<Book> searchBooks(String author, String genre, String pages, String year, String rating){

    List<Predicate> predList = new LinkedList<Predicate>();

    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Book> c =cb.createQuery(Book.class);
    Root<Book> b = c.from(Book.class);

    if(author!="")
      predList.add(cb.equal(b.get("author"), author));
    }
    if(genre!=""){
      predList.add(cb.equal(b.get("genre"), genre));
    }
    if(pages!=""){
      predList.add(cb.equal(b.get("pages"), pages));
    }
    if(year!=""){
      predList.add(cb.equal(b.get("year"), year));
    }
    if(rating!=""){
      predList.add(cb.equal(b.get("rating"), rating));
    }
    Predicate[] predArray = new Predicate[predList.size()];
    predList.toArray(predArray);
    c.where(predArray);     

    TypedQuery<Book> q = em.createQuery(c);
    List<Book> result = q.getResultList();

    return result;

  }

}
效果很好


Johnny O.

我有点怀疑您是否希望取消一个变量的scape,而这个变量并不是传递给应用程序的准备好的语句真正发生的事情。如果列变量是,我想选择所有的列变量,这就好像它不是一个标准,也不是一个过滤器。如果变量存在,那么我将使用它进行过滤。尝试通过插入->anyselect myColumn from book来实现这一点…原因是它不是从表单上的下拉选择中选择的。我认为您需要的是Spring数据JPA文档中的第3.6节。嗯,科林,谢谢。我会查出来的。编辑我的评论,添加到正确部分的链接。