这是一个比实现问题更多的设计,它将会很长时间以待我。这是最好用一个例子说明: 通过服务API公开Hibernate标准
比方说,我有一个商业实体,称为产品了一堆属性(名,价格,厂商,等...)。
它通过一个接口(产品)和执行(ProductImpl,在Hibernate中映射)以及基本的CRUD服务接口(ProductService)和执行(ProductServiceImpl)表示。
产品和ProductService公开为API,但它们的实现不是。
我想添加一个列表findProducts(QueryCriteria标准)方法ProductService,将返回的产品满足给定标准的列表。 的要求是:通过直接产品性质(例如product.price gt 50.0
)
product.vendor.name = "Oracle"
)order by product.vendor.name desc, product.price asc"
)
- 查询
- 应用附加的过滤器。与由API客户端全部指定的上述3个项目不同,服务可以基于客户端身份(例如,客户端调用该方法可能仅限于查看由给定供应商制造的产品)来应用额外的过滤器。这样的过滤器的优先级高于由客户端指定的任何标准(例如,如果过滤器被设置为
product.vendor.name = "Microsoft"
,查询在上述(2)应当产生空结果集。
的问题,因此,是什么应该QueryCriteria通过这样的方法使用的界面看起来像我能想到的3个解决方案,我也不喜欢他们中的一个:?
- 允许客户端指定HQL(从“where”子句)直接 这是最直接的解决方案,但也是最有问题的安全方面。即使假定过滤器(上述#4)是简单的如果足够通过Hibernate的会话过滤器来实现,HQL仍然需要被解析为 - 至少 - 确保查询参数被指定为参数而不是内联。
- 使用纤细包装的Hibernate的DetachedCriteria代替QueryCriteria。 “Thinly wrapped”,因为客户端不能被允许直接创建DetachedCriteria将无法控制它创建的映射实体。 此外,这不会像HQL那样灵活,因为某些查询不容易(或根本不能)通过Criteria API表示。与HQL方法一样,过滤器(上述#4)将仅限于Hibernate会话过滤器。
- 写我自己的QueryCriteria接口/实现将在后台形成DetachedCriteria或HQL。尽管可能是最灵活的解决方案,但它必须从Criteria API中复制很多代码,这似乎不太理想。
任何有关上述方法的有效性的评论或 - 手指交叉 - 我没有想到的简单优雅的解决方案将不胜感激。
P.S.在我的具体情况中,所有的API客户端都是内部的和“半可信的” - 那就是我没有太在意那些试图故意破坏某些东西的人,因为糟糕的编程导致了5张表的笛卡尔积:-)然而,它如果能够提供一种能够承受API暴露于公众的解决方案,我们感到非常高兴。
看起来这个问题已经持续了两个月;我很好奇你定居在什么地方?我想我会采取#3,“写我自己的...”的方法,并试图将我需要的信息“扁平化”到ProductService/criteria API中作为可查询属性,具体取决于使用情况。 – RMorrisey 2009-09-22 00:20:30
@Rorrisey - 我已经添加了一个描述我的解决方案的答案。 – ChssPly76 2009-09-22 04:04:42