我的目标是编写一个类似的查询:
select * from Book where author = any(select author from book)
and(genre='comedy') order by ( '' )ASC, ( pages )DESC;
其中'any(从书中选择作者)'丢失了单引号,因此我可以通过它
@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'或'any(从book中选择条件)',或者在运行查询之前插入null或空字符串。
我认为使用条件API或类似的东西可以构建动态查询或插入保留的sql单词,但我不知道如何轻松实现它,因为我正在扩展Spring数据CrudRepository而不是使用entitymanager ...... ..我想我必须这样做。
有没有人知道如何逃避字符串输入@Param强加的'或者哪种方法很容易起作用?例如Criteria API,存储过程,函数?
请原谅我在这里缺乏经验......
谢谢!
看起来使用5种可能输入来实现此目的的唯一方法是让运行时策略根据存在的输入选择14种不同的查询,但我试图避免这种情况!
答案 0 :(得分:0)
所以......这是解决方案!
/**
* 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。