Cayenne — поиск комбинации зависимостей

#sql #apache-cayenne

#sql #apache-cayenne

Вопрос:

Я создаю приложение, которое позволяет пользователям создавать форму, которая затем может быть загружена и заполнена другим пользователем, и затем можно просмотреть отправку этого пользователя.

Форма заполняется полями. Когда пользователь заполняет форму, создается объект базы данных отправки, и это представление имеет 1-миллионную связь с объектами FieldValue. Объект FieldValue имеет FK для поля и хранит строку ввода пользователя. Используя этот дизайн, чтобы просмотреть отправку, я просматриваю значения полей, связанные с отправкой, загружаю связанный объект поля и заполняю его вводом пользователя. В этом смысле все работает хорошо, но моя проблема заключается в поиске этих представлений.

Я работаю над страницей поиска, где я динамически создаю поля поиска на основе полей формы, в которой выполняется поиск. Например, имя и фамилия. Допустим, что пользователь выполняет поиск с помощью FirstName = j LastName = smith . Используя эти поля поиска, я хочу выполнить поиск всех отправлений, которые имеют значение поля, в котором FK соответствует FirstName, а текст содержит «j», И имеет ДРУГОЕ значение поля, в котором FK соответствует LastName, а текст содержит «smith»

Я пробовал варианты следующего кода:

  Expression exp = ExpressionFactory.matchExp(Submission.FORM_PROPERTY, _formId);

 for (SearchField searchField : searchFields)
 {                    
     Expression fieldExp = ExpressionFactory.matchExp(Submission.FIELD_VALUE_PROPERTY  "."   FieldValue.FIELD_PROPERTY, searchField.getFieldId());
     fieldExp = fieldExp.andExp(ExpressionFactory.likeIgnoreCaseExp(Submission.FIELD_VALUE_PROPERTY  "."   FieldValue.TEXT_PROPERTY, "%"   searchField.getText()   "%" ));

     exp = exp.joinExp(Expression.AND, fieldExp);                     
 }
 SelectQuery query = new SelectQuery(Submission.class, exp);
  

То, что я пытаюсь сделать, это перебирать каждое из полей поиска и добавлять его в список значений полей, которые должны быть в отправке. Проблема с этим заключается в том, что он продолжает искать ОДНО значение поля, которое имеет все эти значения, и поэтому, очевидно, терпит неудачу. Я никогда не выполнял поиск, который мог бы быть 1-М в другом классе, поэтому я предполагаю, что я что-то здесь упускаю. Буду признателен за любую помощь. Я прошу прощения за небольшой роман в попытке описать, что происходит, но для меня это немного необычно.

Ответ №1:

Вам нужно будет создать выражение, которое создает M соединений. «Разбиения» и «псевдонимы» управляют тем, как создаются соединения. Поскольку у вас есть более одного критерия для каждого объединения, разделение не будет работать, поэтому более уместно использовать явные псевдонимы. Просто дайте SelectQuery знать, что означает каждый псевдоним.

 import static org.apache.cayenne.exp.ExpressionFactory;

int len = searchFields.size();
String[] aliases = new String[len];
for (int i = 0; i < len; i  ) {
     SearchField f = searchFields[i];
     aliases[i] = f.getFieldId();                  
     Expression e = matchAllExp(alias  "."   FieldValue.FIELD_PROPERTY, f.getFieldId());
     e = e.andExp(likeIgnoreCaseExp(alias  "."   FieldValue.TEXT_PROPERTY, "%"   f.getText()   "%" ));

     exp = exp.joinExp(Expression.AND, e);                     
 }

 SelectQuery query = new SelectQuery(Submission.class, exp);
 query.aliasPathSplits(Submission.FIELD_VALUE_PROPERTY, aliases);
  

Комментарии:

1. Большое вам спасибо, Андрус! Ты спасатель.