我有一个方法,它接收一个dto,其中许多字段用于基于非空字段进行动态查询。我通过lambda中的反射访问每个字段,以将非空字段添加到动态查询中。这可以工作,但我不知道如何让列表返回它。
@Override
public List<AirlinePreOrderDto> getPreorders(AirlinePreOrderDto airlinePreOrderDto) {
PreOrder entity = PreOrderMapper.mapToJpaEntity(airlinePreOrderDto);
Query dynamicQuery = new Query();
ReflectionUtils.doWithLocalFields(entity.getClass(), field -> {
field.setAccessible(true);
try {
if (field.get(entity) != null) {
if (!field.getName().equals("serialVersionUID")) {
if(field.getName().equals("preorderId")) {
dynamicQuery.addCriteria(Criteria.where(field.getName()).is(field.get(entity)));
} else {
dynamicQuery.addCriteria(Criteria.where(field.getName()).is(field.get(entity)));
}
}
List<AirlinePreOrderDto> result = PreOrderMapper
.mapToDtos(mongoTemplate.find(dynamicQuery, PreOrder.class, "preorders"));
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
});
// return result list;
}
我建议你使用封闭类。
class EnclosingResults {
List<AirlinePreOrderDto> results;
public void setResults(List<AirlinePreOrderDto> results) {
this.results = results;
}
public List<AirlinePreOrderDto> getResults() {
return results;
}
}
所以你的方法是:
@Override
public List<AirlinePreOrderDto> getPreorders(AirlinePreOrderDto airlinePreOrderDto) {
PreOrder entity = PreOrderMapper.mapToJpaEntity(airlinePreOrderDto);
Query dynamicQuery = new Query();
EnclosingResults resultEncloser = new EnclosingResults();
ReflectionUtils.doWithLocalFields(entity.getClass(), field -> {
field.setAccessible(true);
try {
if (field.get(entity) != null) {
if (!field.getName().equals("serialVersionUID")) {
if(field.getName().equals("preorderId")) {
dynamicQuery.addCriteria(Criteria.where(field.getName()).is(field.get(entity)));
} else {
dynamicQuery.addCriteria(Criteria.where(field.getName()).is(field.get(entity)));
}
}
List<AirlinePreOrderDto> result = PreOrderMapper
.mapToDtos(mongoTemplate.find(dynamicQuery, PreOrder.class, "preorders"));
resultEncloser.setResults(result);
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
});
return resultEncloser.getResults()
}
似乎您不想在lambda内部调用mongoTemplate.find
或PreOrderMapper.mapToDtos
,因为lambda将为每个本地字段执行一次。
但是从你的代码中,我估计你真的想在从所有字段构建dynamicQuery
对象后执行查询。
并且由于您已经在lambda中操作了dynamicQuery
引用的对象,因此只需将代码移动到实际中执行即可:
PreOrder entity = PreOrderMapper.mapToJpaEntity(airlinePreOrderDto);
Query dynamicQuery = new Query();
ReflectionUtils.doWithLocalFields(entity.getClass(), field -> {
field.setAccessible(true);
try {
if (field.get(entity) != null) {
if (!field.getName().equals("serialVersionUID")) {
if(field.getName().equals("preorderId")) {
dynamicQuery.addCriteria(Criteria.where(field.getName()).is(field.get(entity)));
} else {
dynamicQuery.addCriteria(Criteria.where(field.getName()).is(field.get(entity)));
}
}
}
} catch (IllegalArgumentException e) {
e.printStackTrace();
}
});
List<AirlinePreOrderDto> result = PreOrderMapper
.mapToDtos(mongoTemplate.find(dynamicQuery, PreOrder.class, "preorders"));
return result;