我想在我的Dropwizard服务器中实现数据过滤。让我们说,我们想要寻找古迹。用户可以使用诸如名称、城市、类别等过滤器对古迹列表进行过滤。
uri看起来类似于/monuments?name="Eiffel"&city"Paris"&category="Engineering Marvel"
我不清楚如何实现这个API,因为一些用户可能会在指定名称筛选器之后停止,而其他用户则可能使用全部3。
在这种情况下,如何实现DAO中的Java代码和查询,以便根据传递的过滤器修改查询?
我的想法和尝试:
1(最坏的情况)-有一个列表,所有可能的组合查询这些过滤器,并使用一个取决于哪个组合的参数被传递。
2-我以为JDBI会自动消除调用DAO方法时为null的参数,但情况并非如此,至少ilike子句是这样的(因为上面的所有参数都是字符串)。
3-在Postgres中使用案例。但是这是无法扩展的,因为随着用例的增加,随着时间的推移,我可能会有其他的参数来搜索。
4-使用Java数据结构和DAOs在内部过滤结果,比如先获取所有基于(比方说)名称的纪念碑,然后将Ids传递给带有city子句的SQL查询,然后再传递给同样的类别子句。但随着数据的增加,这将需要很长的时间来处理。
这似乎是一个相当常见的场景,但我找不到任何好的答案,大多数讨论的是URI和RESTful设计,而不是实现细节。
发布于 2019-01-24 16:38:08
当可选参数很少时,@Hitobat建议的答案会很好,但是如果您正在处理许多可选参数,一个更优雅的解决方案是考虑创建一个请求pojo,并使用冬眠准则,其中只在参数不是null的情况下添加一个限制。
请求类:
public class FilteredRequest{
String name;
String city;
String category;
}资源类别:
@GET
@Path("/monuments")
public Response searchMonuments(@ApiParam("filters") FilteredRequest filteredRequest){
return Response.ok().entity(monumentsDAO.findAll(filteredRequest)).build()
}DAO:
public List<Monuments> class MonumentsDAO() {
public findAll(FilteredRequest filteredRequest){
Criteria criteria = getSearchCriteria(filteredRequest);
return list(criteria);
}
private Criteria getSearchCriteria(FilteredRequest filteredRequest){
Criteria criteria = criteria();
if (StringUtils.isNotEmpty(filteredRequest.getName())) {
criteria.add(Restrictions.eq("name", filteredRequest.getName()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCity())) {
criteria.add(Restrictions.eq("city", filteredRequest.getCity()));
}
if (StringUtils.isNotEmpty(filteredRequest.getCategory())) {
criteria.add(Restrictions.eq("category", filteredRequest.getCategory()));
}
return criteria;
}
}https://stackoverflow.com/questions/53465419
复制相似问题