2016-12-14 8 views
1

Я хочу, чтобы выполнить запрос следующим образом:Найти многих колоннах

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

Использование весны 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' совпадение может скоро появиться через API-интерфейс Example. Вы можете отслеживать [эту JARA данных весны] (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 to A [] - это происходит в обоих ваших ответах - пожалуйста, исправьте это –

Смежные вопросы