我有一个Java类,其中有一些字段用@SearchCriteria(criteria = "class1.class2.field")
注释。注释中的criteria
参数意味着对于类,此字段应设置为休眠条件,这意味着,如果字段标记为示例:
@SearchCriteria(criteria = "class1.class2.field")
private String value;
我希望动态创建看起来像
的hibernate标准DetachedCriteria hibernateCriteria = forClass(Class.class);
hibernateCriteria.createCriteria("class1").createCriteria("class2").add(eq("field", value));
问题是我无法设置已添加的其他条件,这意味着我应该检查注释criteria
选项。
switch (annotationCriteria.length - 1) {
case 0:
hibernateCriteria.add(isNull(annotationCriteria[0]));
case 1:
hibernateCriteria.createCriteria(annotationCriteria[0]).add( Restrictions.isNull(annotationCriteria[annotationCriteria.length - 1]));
case 2: hibernateCriteria.createCriteria(annotationCriteria[0]).createCriteria(annotationCriteria[1]).add( Restrictions.isNull(annotationCriteria[annotationCriteria.length - 1]));
}
我想删除这个“swith”。我现在可以通过“名称”来为已添加的标准添加标准,并为其添加新的子标准。
答案 0 :(得分:1)
不,这是不可能的。 Detached Criteria API不会 - 无论好坏 - 允许发现,因此您将无法向其询问“现有”标准。
但是,您可以通过关联路径维护自己的嵌套条件映射。在伪代码中:
Map<String, DetachedCriteria> criteriaMap = ...;
for ( ) { // loop over annotation criteria's "elements"
DetachedCriteria existing = criteriaMap.get(fullPath);
if (existing==null) {
existing = parentCriteria.createCriteria(pathElement);
criteriaMap.put(fullPath, existing);
}
existing.add(whateverCondition);
}
答案 1 :(得分:1)
我为这个问题找到了更好的解决方案。 首先创建一些searchCriteria类,例如:
public class SearchCriteria {
@SearchCriteria(path = "someclass.someclass.id")
private Integer someId;
public Integer getSomeId() {
return someId;
}
public void setSomeId(Integer someId) {
this.someId= someId;
}
}
自定义注释:
@Target(value = { ElementType.FIELD })
@Retention(RUNTIME)
public @interface SearchCriteria {
String path() default "";
boolean optional() default true;
}
在DAO课程中:
@Override
public Collection<SomeClass> find(SearchCriteria criteria) {
DetachedCriteria hibernateCriteria = forClass(SomeClass.class);
for (Field field : criteria.getClass().getDeclaredFields()) {
Annotation annotation = field.getAnnotation(SearchCriteria.class);
if (annotation == null) {
continue;
}
List<String> elements = Arrays.asList(StringUtils.split(((SearchCriteria) annotation).path(), "."));
field.setAccessible(true);
Object fieldValue = null;
try {
fieldValue = field.get(criteria);
} catch (IllegalArgumentException e) {
LOG.error("while trying to get private field value of entity " + SearchCriteria.class, e);
} catch (IllegalAccessException e) {
LOG.error("while trying to get private field value of entity " + SearchCriteria.class, e);
}
for (String element : elements) {
if (elements.indexOf(element) == elements.size() - 1) {
hibernateCriteria = hibernateCriteria.add(eq(element, fieldValue));
} else {
hibernateCriteria = hibernateCriteria.createCriteria(element);
}
}
}
return getHibernateTemplate().findByCriteria(hibernateCriteria);
}