【问题标题】:Hibernate translation capabilities休眠翻译功能
【发布时间】:2009-12-04 16:34:12
【问题描述】:

我们的项目必须能够在 Oracle 和 SQL Server 中运行。问题是我们有许多 HQL + 本机查询,它们带有非标准运算符(即 bitand 和 || )和函数(即 SUBSTR ),它们在 Oracle 中可以正常工作,但在 SQL Server 中却不行。

我想知道 Hibernate 是否能够动态翻译它们。我想 HQL 可能确实如此,因为它创建了一个 AST,但我怀疑这同样适用于本机查询。

附加问题:处理这些麻烦查询的最佳方法是什么?条件、子类化、其他……目标不是大量修改代码。

提前感谢

【问题讨论】:

    标签: java oracle hibernate


    【解决方案1】:

    为 HQL 使用自定义方言。不要使用 ||,而是创建自己的名为 concat 的函数。然后,在 SQL Server 方言中将其添加到构造函数中:

    registerFunction("concat", new VarArgsSQLFunction(Hibernate.STRING, "", "+", ""));
    

    您不必更改Oracle方言,因为Oracle已经有一个concat函数所以它只是通过,但对于其他函数,您可能需要在两者中注册新函数。

    对于 SQL 查询,由于无论如何都是动态构建的,因此可以使用基类方法,例如 super.addBitAndClause(leftSide, rightSide)。

    你甚至可以动态获取方言,尽管 Hibernate 并没有通过放置界面来轻松实现:

    Dialect d = ((SessionFactoryImpl)sessionFactory).getDialect()
    

    【讨论】:

    • 我试试 registerFunction 方法,看来正是我们需要的。但是我不太明白在哪里放置 super.addBitAndClause。
    • 在您链接到的示例中,您使用 if/else 语句执行了大量 sql 连接,以便为 Oracle 和 SQL Server 执行不同的操作。我只是说而不是所有 if/else 部分,您可以让该类扩展一个基类,该基类具有一组处理差异的方法。您也可以使用辅助类,例如: String sqlStatement = "select * from table where " + SqlHelper.addBitwideAnd("left, "right")... 基类或辅助类是唯一需要知道的类方言差异。这部分仅适用于您无法使用 HQL 时。
    • 好的,我明白了。但是我已经重构了该代码,因为我们使用修饰的 Session 类来创建查询,我在执行 SQL 查询之前替换了特定函数,在 regexp 的帮助下。虽然不是一个完美的解决方案,但它似乎有效。
    【解决方案2】:

    我建议将 HQL 查询从代码移动到外部 .hbm 文件,并在切换数据库之前使用命名查询。正如您所说,HQL 查询应该不是问题。本机查询是一个问题,您必须找到其他 DBMS 的等价物。但是通过将查询放入外部文件,您可以将 sessionfactory 配置为使用特定于数据库的 .hbm 文件,并且不需要更改仅依赖于命名查询的代码,该命名查询可以是本机查询或 HQL 要获取命名查询,您可以执行以下操作:

    Query query = session.getNamedQuery("YourNamedHQLorSQLQuery");
    

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-07
    • 1970-01-01
    • 2012-04-18
    • 2017-01-17
    • 2012-11-14
    • 1970-01-01
    相关资源
    最近更新 更多