我正在创建一个允许用户创建表单的应用程序,然后可以由另一个用户加载和填写该表单,然后可以查看该用户的提交。
表单中填充了字段。当用户填写表单时,将创建一个Submission数据库对象,并且此提交与FieldValue对象具有1-M关系。 FieldValue对象具有Field的FK,并存储用户输入的String。使用此设计,要查看提交,我会读取与提交相关联的FieldValues,并加载关联的Field对象,并使用用户的输入填充它。在这个意义上,一切都运作良好,但我的问题在于搜索这些提交。
我在搜索页面上工作,在此页面中,我根据要搜索的表单的字段动态创建搜索字段。例如firstName和lastName。让我们说用户使用firstName = j lastName = smith进行搜索。使用这些搜索字段,我想搜索具有FieldValue的所有提交,其中FK与firstName匹配,文本包含" j" AND有一个不同的FieldValue,其中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);
我尝试做的是遍历每个搜索字段,并将其添加到必须位于提交中的FieldValues列表中。这个问题是它不断搜索具有所有这些值的ONE FieldValue,因此显然失败了。我从来没有在另一个班级做过1-M的搜索,所以我认为我在这里遗漏了一些东西。任何帮助将不胜感激。我为这部小小的小说道歉,试图描述正在发生的事情,但这对我来说有点不同寻常。
答案 0 :(得分:0)
您需要构建一个创建M连接的Expression。 "拆分"和"别名"控制how joins are generated。由于每个连接都有多个条件,因此拆分不起作用,因此使用显式别名更合适。只需让SelectQuery know what each alias means。
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);