SQL方言如何在hibernate和JOOQ等框架内部实际工作

问题描述 投票:2回答:1

正如我们在获得数据源后所看到的那样。我们需要根据我们使用的数据库配置SQL方言。在我们选择一个特定的方言后,如何使用它来进行特定于DB的SQL查询。像hibernate和JOOQ这样的框架是否基于所选方言在字符串中构造SQL查询?如果是这样,哪个是我们自己的框架中支持这个的最佳方式?

entity-framework hibernate orm jooq
1个回答
7
投票

像hibernate和JOOQ这样的框架是基于所选方言在字符串中构造SQL查询

是。在jOOQ中,有一个内部StringBuilder,它从表达式树中收集SQL片段,这些片段是专门为目标SQL方言生成的。你可以在这个网站上看到它的运作方式:https://www.jooq.org/translate。尝试翻译例如此输入:SELECT * FROM t LIMIT 1(可能对应于您的jOOQ API用法ctx.selectFrom(T).limit(1)。它转换为:

-- Oracle 12c and more
SELECT * FROM t FETCH NEXT 1 ROWS ONLY

-- Oracle 11g and less
SELECT *
FROM (
  SELECT x.*, rownum rn
  FROM (SELECT * FROM t) x
  WHERE rownum <= 1
)
WHERE rn > 0

如果是这样,哪个是我们自己的框架中支持这个的最佳方式?

你需要:

  1. SQL查询的表达式树表示。
  2. 或者,你可以解析一个字符串来构建这个表达式树,如果你想支持实际的SQL就像jOOQ's parser一样,或者你可以像Hibernate那样使用HQL / JPQL进行自己的语言抽象
  3. 使用类似访问者的东西遍历表达式树来收集SQL字符串并绑定变量。

But!

当你拥有像jOOQ这样的现成产品或者在某种程度上可以做同样的Hibernate产品时,不要自己构建。构建这样一个通用的SQL抽象真的很难,除非你想要实际销售这样的产品(你可能没有提出你的问题),花这么多时间来构建这个产品根本不值得。

上面的LIMIT仿真是jOOQ中更简单的例子之一。 Here's a lot more to help you decide against rolling your own,这个答案仍然只是触及jOOQ在幕后所做的事情。

© www.soinside.com 2019 - 2024. All rights reserved.