Java/Hibernate:如何为复杂的 SQL 编写 DAO 代码

Posted

技术标签:

【中文标题】Java/Hibernate:如何为复杂的 SQL 编写 DAO 代码【英文标题】:Java/Hibernate: how to write DAO code for complex SQLs 【发布时间】:2010-01-26 22:36:32 【问题描述】:

我目前的工作场所使用标准的 Spring/Hibernate/JSP 组合通过 XML 向其 Flex 客户端提供内容。访问数据的方式有很多种,但最流行的一种是通过对数据库的直接 SQL 调用和手动转换为 XML。

问题在于,随着应用程序变得越来越大,SQL 变得越来越复杂且难以维护。好像维护使用 StringBuilders 创建的 SQL 还不够难,现在更糟糕的是,使用许多 if 语句和循环动态构造 SQL。

我知道通常正确的方法是使用 Hibernate 查询和实体获取项目。但是,在我们的一些请求中,结果无法映射到单个 Hibernate 实体,恐怕需要使用直接 SQL。

解决这个问题的正确方法是什么?有没有办法让动态 sql 查询更清晰?有没有办法用 Hibernate 实体做到这一点?

对于这个问题的抽象性质,我深表歉意。尽管如此,我还是希望你有好的意见;)

感谢您的 cmets!

【问题讨论】:

【参考方案1】:

HQL 支持获取多个实体的查询。也支持连接。例如:

SELECT new com.package.model.SearchResultEntry(product, price) FROM Product product, 
    IN(product.variantPrices) price WHERE ....

上面返回一个新的(非实体!)对象,它由两个实体组成——产品和价格。您还可以使用List 将不同的实体放在同一个结果中。

彻底阅读this tutorial。

使用动态参数进行这些查询,并使用最合适的类将它们存储为@NamedQueries

【讨论】:

【参考方案2】:

您可以考虑将一些 SQL 逻辑移动到数据库中并通过视图访问数据:这当然会带来其自身的问题(您现在在两个地方都有业务逻辑)但可能值得考虑。

【讨论】:

我有点同意这里,尽管很多人不喜欢 SQL 中的存储过程和逻辑。如果你有一个非常复杂的 SQL 查询,真的没有办法通过尝试在代码中完成它,或者使用像 HQL 这样不太健壮的查询语言来简化它。【参考方案3】:

假设您无法在 HQL 中执行您需要的操作,请查看 ibatis 它将允许您使用特定的 SQL 查询和存储过程设置映射。它也将是您项目的另一个依赖项,因此也要考虑到这一点。

【讨论】:

以上是关于Java/Hibernate:如何为复杂的 SQL 编写 DAO 代码的主要内容,如果未能解决你的问题,请参考以下文章

如何为最小的列数显示一行?

如何为复杂的 json 文档定义 avro 模式?

如何为两个不同实体之间的复杂消息系统设计表?

哈希表的插入复杂度如何为 O(1)

如何为复杂对象编写自定义 JSON 解码器?

使用请求时如何为 Flask-Restless 构建复杂的过滤器?