此自定义查询有效(这只是用于说明问题的基本查询):
public interface BookQueryRepositoryExample extends Repository<Book, Long> {
@Query(value = "select * from Book b where b.name=?1", nativeQuery = true)
List<Book> findByName(String name);
}
但是我需要另一个自定义查询,其中where
子句将在调用方法之前动态构造。
public interface BookQueryRepositoryExample extends Repository<Book, Long> {
@Query(value = "select * from Book b where ?1", nativeQuery = true)
List<Book> findByWhatever(String qry);
}
但我无法使其发挥作用。有没有解决方法?
更新时间:6/16/2017
只是想提一下,我正在搜索的字段是'非规范化'形式。值可能如下所示(如下)。所以我的查询有一系列类似的陈述
样本1:
name:John Smith;address1:123 Xyz St;city:New York;zip:12345;country:USA;id:ABC1234;email:js@abc.com;
示例2:重新排列
address1:123 Xyz St;zip:12345;email:js@abc.com;name:John Smith;country:USA;id:ABC1234;city:New York;
示例3:缺少字符串/文本
zip:12345;email:js@abc.com;name:John Smith;id:ABC1234;city:New York;
答案 0 :(得分:1)
这不会起作用,至少不是这种方法。
查询中的占位符不会被某些任意String
替换,而是变量,只能代替您提供的文字作为文字。
但是作为@M。 Deinum指出有其他选择:你可以write a custom method并使用
有关示例,请参阅此文章:https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
答案 1 :(得分:1)
解决这个问题就像是,您可以通过注入EnitiyManager
来创建一个类来执行动态查询,如下所示:
//Pseudo code
@Repository
public class SomeDao {
@PersistenceContext
private EntityManager entityManager;
public List<Book> findByWhatever(String qry){
Query q = entityManager.createNativeQuery(qry);
List<Object[]> books = q.getResultList();
//...... Your logic goes here
//return ...
}
}
答案 2 :(得分:1)
例如如果要根据authorName,title和cost等属性的组合查找Book,则可以使用以下查询
public interface BookQueryRepositoryExample extends Repository<Book, Long>
{
@Query(value = "select * from Book b where (?1 or null) and (?2 or null) and (?3 or null) ",
nativeQuery = true
)
List<Book> findByWhatever(String authorName,String title,Double cost);
}
答案 3 :(得分:1)
您可以使用spring-data提供的规范界面创建动态where子句。
以下是您的链接:https://spring.io/blog/2011/04/26/advanced-spring-data-jpa-specifications-and-querydsl/
答案 4 :(得分:0)
@Query(value =&#34; select * from Book b where?1&#34;,nativeQuery = true) 列出findByWhatever(String qry);
首先,建议不要使用您的方法,并且最有可能导致 SQL注入漏洞(如果您没有以正确的方式处理&#39; qry&#39;参数)。< / p>
其次,您正在尝试重新发明轮子。有很多可能的方法来实现动态查询,正如@Jens Schauder在他的回答中已经提到的那样。如果你不需要复杂的东西,我会添加一个似乎最简单的方法。它被称为&#34; Query by Example&#34;。
public interface BookRepository extends JpaRepository<Book, Long>{
}
然后,您创建一个对象的实例,该实例看起来就像您要查找的对象一样,这意味着您必须设置用于动态查询生成的属性:
Book book = new Book();
book.setYear(2015);
book.setPublisher("O'Realy")
Example<Book> bookExample = Example.of(book);
最后一步是将您的示例对象传递给Spring Data JPA存储库:
List<Book> books = bookRepository.findAll(bookExample);
因此,您将获得O&#39; Realy在2015年发布的图书清单。关于它的好处是你可以通过在book
实例中设置它来添加更多字段以便在运行时搜索。
如果您需要比精确值匹配更复杂的东西,您可以使用匹配器。在下面的示例中,Spring Data JPA将搜索名称以&#34; O&#34;开头的所有书籍。无视案例。
Book book = new Book();
book.setName("O")
ExampleMatcher matcher = ExampleMatcher.matching().
.withMatcher("publisher", startsWith().ignoreCase());
Example<Book> bookExample = Example.of(book, matcher);
List<Book> books = bookRepository.findAll(bookExample);