#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. Большое вам спасибо, Андрус! Ты спасатель.