使用Java和SQL数据库动态创建搜索条件和结果

时间:2012-05-03 00:43:17

标签: java sql performance hibernate search

我目前正在使用由Hibernate支持的基于Java的Web应用程序(JSF),该应用程序具有针对不同区域的各种不同搜索页面。

搜索页面包含搜索字段部分,用户可以自定义他们感兴趣的搜索字段。可以添加一系列不同的搜索字段类型(确切文本,开头,包含,多个选择列表框,逗号分隔值等等)。搜索字段不需要填写并被忽略,而某些其他搜索字段需要不同的搜索字段才能使此搜索字段的值有效。

我们目前每个区域使用一个特定于该区域的自定义搜索对象,并且具有硬编码的getter和setter搜索字段。

public interface Search {
  SearchFieldType getSearchPropertyOne();
  void setSearchPropertyOne(SearchFieldType searchPropertyOne);

  AnotherSearchFieldType getSearchPropertyTwo();
  void setSearchPropertyTwo(AnotherSearchFieldType searchPropertyTwo);

  ...
}

在此示例中,SearchFieldType和AnotherSearchFieldType表示不同的搜索类型,如TextSearchField或NumericSearchField,它们分别具有搜索类型(Starts with,Contains等)或(Greater Than,Equals,Less Than等)和他们可以输入或留空的搜索值(忽略搜索字段)。

我们使用此搜索对象来准备Criteria对象

搜索结果部分是一个表,用户也可以自定义该表以仅包含他们感兴趣的结果对象的列。大多数列可以按升序或降序排序。

我们将结果返回到每个结果的Result对象中,该结果也对可以显示的列进行硬编码。这个表由hibernate注释支持,但我们尝试使用平面数据而不是允许其他hibernate支持的对象来最小化延迟连接数据。

@Entity(table = "result_view")
public interface Result {
  @Column(name = "result_field_one")
  Long getResultFieldOne();
  void setResultFieldOne(Long resultFieldOne);

  @Column(name = "result_field_two")
  String getResultFieldTwo();
  void setResultFieldTwo(String resultFieldTwo);

  ...
}

搜索页面由我们数据库中的视图支持,该视图处理每个可能结果所需的所有表的连接。这个视图变得非常庞大,我们每次搜索都会受到巨大的性能影响,即使用户只想搜索一个字段并显示几列,因为我们有超过30个搜索字段选项和30个不同的列可以显示这一切都得到了一个观点的支持。

除此之外,用户还会在他们想要添加到页面的所有时间内请求新的搜索字段和列。我们最终必须更改搜索和结果对象以及后备视图以进行这些更改。

我们正在努力调查此事并找到替代方案。提到的一种方法是创建我们根据搜索结果表中显示的字段动态选择的不同视图。不同的视图可能会加入不同的列,我们会选择哪个视图来进行任何给定的搜索。

我试图以不同的方式思考问题。我认为最好不要使用视图,而是根据请求的搜索字段和结果列动态连接我们需要的表。我还认为搜索和结果对象不应包含硬编码的getter / setter,而应该是搜索字段的集合和结果列的集合(或映射)。我还没有完全充实我的想法。

hibernate仍然是这个问题的有效解决方案吗?我不希望创建一个在休眠标准中使用的Result对象,因为它们的结果列可能不同。搜索字段和/或结果列都可能需要连接表。

是否有可以帮助解决问题的框架?我一直在寻找一些东西,而我发现的最接近的东西是SqlBuilder。

还有其他人动态解决了类似问题吗?

如果解决方案已经存在,我宁愿不重新发明轮子。

我很抱歉这最终成了一面文字。这是我的第一篇stackoverflow帖子,我想确保我彻底定义了我的问题。

提前感谢您的回答!

1 个答案:

答案 0 :(得分:0)

我不完全理解这个问题。但JPA Criteria API似乎非常灵活,可用于根据用户提交的过滤条件构建查询。