2016-12-14 52 views
1

找到我想要進行這樣的查詢:許多列

SELECT * FROM table WHERE 
col1 = 'value1' OR 
col2 = 'value2' OR 
col3 = 'value3' OR 
col4 = 'value4'; 

使用Spring的JpaRepository我應該使用這樣的事情:

List<MyEntity> findByCol1OrCol2OrCol3OrCol4(
    String col1, String col2, String col3, String col4 
); 

現在想象一下,我不想檢查4列但10或20,方法名稱會很長!

我在這個answer中看到我可以用Specification在許多列中搜索相同的文本,但是我希望每個文本都有不同的文本值。

有什麼辦法可以縮短查找方法並動態地添加列(和相應的值)?

謝謝

+1

簡短回答爲否(用於'或'連接)。您可以使用QueryDSL支持動態構建查詢。 – manish

+0

您可以使用標準和查詢。存儲庫對於這裏指定的複雜查詢來說並不是那麼有用。http://stackoverflow.com/questions/17008947/whats-the-difference-between-spring-datas-mongotemplate-and-mongorepository – KayV

+0

似乎支持'OR'通過'Example's API即將推出匹配。您可能想要追蹤[此Spring Data JIRA](https://jira.spring.io/browse/DATAJPA-1025)以獲取發佈信息。 – manish

回答

1

這可以通過規格和地圖(屬性名稱,值)來實現。代碼示例(適用於任何數據):

Map<String, Object> whereClause = new HashMap<>(); 
whereClause.put("lastname", "Super-Lastname"); 
whereClause.put("firstname", "Firstńame"); 

userRepository.findOne(Specifications.where(
    CommonSpecifications.attributesEquals(whereClause)) 
) 

public static <T> Specification<T> attributesEquals(Map<String, Object> whereClause) { 
    return (root, query, builder) -> builder.or(root.getModel().getDeclaredSingularAttributes().stream() 
      .filter(a -> whereClause.keySet().contains(a.getName())) 
      .map(a -> builder.equal(root.get(a.getName()), whereClause.get(a.getName()))) 
      .toArray(Predicate[]::new)); 
} 
+0

我喜歡這個主意,但它說不能將java.util.function.Predicate轉換爲A [] - 這發生在你的答案中 - 請修復它 –