为啥需要配置数据源的 SQL 方言?
Posted
技术标签:
【中文标题】为啥需要配置数据源的 SQL 方言?【英文标题】:Why do I need to configure the SQL dialect of a data source?为什么需要配置数据源的 SQL 方言? 【发布时间】:2014-01-27 13:34:43 【问题描述】:当我们使用 Hibernate 配置数据源时,我们应该添加 hibernate.dialect
属性(如果您使用的是 EclipseLink,则添加 eclipselink.target-database
)。
我想知道方言是什么意思?这个属性我是按照Hibernate的文档来配置的,但是不知道是什么意思。
【问题讨论】:
【参考方案1】:Hibernate 使用“方言”配置来了解您正在使用哪个数据库,以便将 Hibernate 查询转换为特定于数据库的查询。
【讨论】:
【参考方案2】:方言是特定人群使用的一种语言形式。
在这里,在 hibernate 框架的上下文中,当 hibernate 想要与数据库交谈(使用查询)时,它使用方言。
SQL 方言源自结构化查询语言,该语言使用人类可读的表达式来定义查询语句。hibernate dialect 向框架提供有关如何将 hibernate 查询(HQL) 转换为本地SQL 查询的信息。
hibernate 的方言可以使用以下属性进行配置:
hibernate.dialect
Here,是完整的休眠方言列表。
注意:hibernate的方言属性不是强制的。
【讨论】:
这是一个当前列表:docs.jboss.org/hibernate/orm/current/javadocs/org/hibernate/…【参考方案3】:hibernate通过以下方式使用方言属性
-
生成优化的 SQL 查询。
如果您有多个数据库,请与您想要的特定数据库交谈。
根据我们使用的数据库软件设置休眠配置文件属性的默认值,即使它们未在配置文件中指定。
【讨论】:
【参考方案4】:Hibernate 上下文中的方言将处理数据库数据类型,例如在 orace 中它是整数,但在 SQL 中它是 int,因此在 hibernate 中通过此属性知道如何在内部映射字段。
【讨论】:
【参考方案5】:简答
“JDBC 的讽刺之处在于,尽管编程接口是 可移植,SQL 语言不是。尽管多次尝试 标准化它,仍然很少编写任何复杂的 SQL 将在两个主要的数据库平台上运行不变。甚至在哪里的SQL 方言是相似的,每个数据库的表现不同,具体取决于 查询的结构,需要特定于供应商的调整 大多数情况。”
..stolen from Pro JPA 2 Mastering the Java Persistence API,第 1 章,第 9 页
因此,我们可能会将 JDBC 视为抽象出与数据库相关的所有内容的终极规范,但事实并非如此。
引用JDBC specification,第 4.4 章,第 20 页:
驱动层可能掩盖标准 SQL:2003 语法之间的差异 以及数据源支持的本地方言。
可能并不能保证驱动程序会,因此我们应该提供方言以便有一个工作的应用程序。在最好的情况下,如果持久性提供者知道要使用哪种方言,应用程序将可以工作,但可能不会像它应该的那样有效地运行。在 Hibernate 的情况下,除非您向他提供方言,否则他将拒绝部署您的应用程序。
那么JPQL呢?
JDBC 规范没有提到 JPQL 这个词。 JDBC 是一种标准化的数据库访问方式。去阅读this JavaDoc,你会发现一旦应用程序可以访问数据库,必须输入到 JDBC 兼容驱动程序中的是 vanilla = undecorated SQL。
值得注意的是,JPQL 是一种查询语言,而不是数据定义语言 (DDL)。因此,即使我们可以为 JDBC 驱动程序提供 JPQL,在解析 persistence.xml
文件和设置表的阶段,这对于持久性提供程序也没有用处。
仔细看看属性
供您参考,这里有一个 Hibernate 和 EclipseLink 示例,说明如何在 persistence.xml 文件中指定 Java DB 方言:
<property name="hibernate.dialect" value="org.hibernate.dialect.DerbyTenSevenDialect"/>
<property name="eclipselink.target-database" value="JavaDB"/>
属性是强制性的吗?
理论上,该属性尚未标准化,JPA 2.1 specification 对 SQL 方言只字未提。所以我们运气不好,必须求助于供应商特定的实证研究和文档。
Hibernate 拒绝接受未指定属性的部署存档,该属性使存档不可部署。 Hibernate documentation 说:
始终将 hibernate.dialect 属性设置为正确的 org.hibernate.dialect.Dialect 数据库的子类。
所以这很清楚。请注意,文档中列出的方言专门针对一个或另一个供应商。没有“通用”方言或类似的东西。鉴于该属性是成功部署的绝对要求,您会期望捆绑 Hibernate 的 WildFly 应用程序服务器的 documentation 应该说些什么,但事实并非如此。
另一方面,EclipseLink 更宽容一些。如果您不提供该属性,则会部署部署(也不会发出警告)。 EclipseLink documentation 说:
使用 eclipselink.target-database 属性指定数据库 使用、控制自定义操作和 SQL 生成 指定的数据库。
谈话是关于“自定义操作和 SQL 生成”的,如果你问我,意思是有点模糊。但有一点很清楚:他们没有说财产是强制性的。另请注意,可用值之一是代表“通用数据库”目标的“数据库”。嗯,那是什么“方言”? SQL 2.0??但是话又说回来,该属性被称为“目标数据库”而不是“方言”,因此“数据库”可能根本不会转换为 SQL,哈哈。转到捆绑 EclipseLink 的 GlassFish 服务器。 Documentation(“6-3”页)说:
您可以指定可选的 eclipselink.target-database 属性以 保证数据库类型正确。
因此,GlassFish 认为该属性是“可选的”,而附加值是我实际使用 Java DB 的“保证”——以防我不知道。
结论
复制粘贴你在谷歌上找到的任何东西,然后向上帝祈祷。
【讨论】:
【参考方案6】:SQL 方言将我们在 java 或任何其他面向对象程序中编写的 HQL 查询转换为特定的数据库 SQL。
例如在java中假设我写 列出员工 = session.createQuery("FROM Employee").list();
但是当我的方言是
<property name="hibernate.dialect">
org.hibernate.dialect.mysql方言
HQL(“FROM Employee”)在访问 MySQL 数据库之前被转换为“SELECT * FROM EMPLOYEE”
【讨论】:
【参考方案7】:Hibernate.dialect
属性告诉 Hibernate 为所选数据库生成适当的 SQL 语句。
可在此处找到可用方言列表:http://javamanikandan.blogspot.in/2014/05/sql-dialects-in-hibernate.html
RDBMS Dialect
DB2 org.hibernate.dialect.DB2Dialect
DB2 AS/400 org.hibernate.dialect.DB2400Dialect
DB2 OS390 org.hibernate.dialect.DB2390Dialect
PostgreSQL org.hibernate.dialect.PostgreSQLDialect
MySQL org.hibernate.dialect.MySQLDialect
MySQL with InnoDB org.hibernate.dialect.MySQLInnoDBDialect
MySQL with MyISAM org.hibernate.dialect.MySQLMyISAMDialect
Oracle (any version) org.hibernate.dialect.OracleDialect
Oracle 9i/10g org.hibernate.dialect.Oracle9Dialect
Sybase org.hibernate.dialect.SybaseDialect
Sybase Anywhere org.hibernate.dialect.SybaseAnywhereDialect
Microsoft SQL Server org.hibernate.dialect.SQLServerDialect
SAP DB org.hibernate.dialect.SAPDBDialect
Informix org.hibernate.dialect.InformixDialect
HypersonicSQL org.hibernate.dialect.HSQLDialect
Ingres org.hibernate.dialect.IngresDialect
Progress org.hibernate.dialect.ProgressDialect
Mckoi SQL org.hibernate.dialect.MckoiDialect
Interbase org.hibernate.dialect.InterbaseDialect
Pointbase org.hibernate.dialect.PointbaseDialect
FrontBase org.hibernate.dialect.FrontbaseDialect
Firebird org.hibernate.dialect.FirebirdDialect
【讨论】:
这里有一个更详尽的列表:docs.jboss.org/hibernate/orm/current/javadocs/org/hibernate/…【参考方案8】:数据库在它们使用的SQL
中实现了细微的差异。例如,数据类型之类的东西因数据库而异(例如,在 Oracle 中,您可以将整数值放在数字字段中,而在 SQL Server 中使用 int 字段)。或特定于数据库的功能 - 选择前 n 行因数据库而异。方言对此进行了抽象,因此您不必担心。
【讨论】:
【参考方案9】:方言是您的数据库使用的 SQL 方言。
List of SQL dialects 用于休眠。
在 hibernate.cfg.xml 中将其提供为:
<hibernate-configuration>
<session-factory name="session-factory">
<property name="hibernate.dialect">org.hibernate.dialect.SQLServerDialect</property>
...
</session-factory>
</hibernate-configuration>
或在属性文件中为:
hibernate.dialect=org.hibernate.dialect.SQLServerDialect
【讨论】:
【参考方案10】:简答
hibernate.dialect
属性使 Hibernate 为所选数据库生成适当的 SQL 语句。
【讨论】:
【参考方案11】:方言的意思是“一种语言的变体”。众所周知,Hibernate 与数据库无关。它可以与不同的数据库一起工作。但是,数据库具有专有扩展/原生 SQL 变体,以及 SQL 标准实现的集合/子集。因此,在某些时候,hibernate 必须使用特定于数据库的 SQL。 Hibernate 使用“方言”配置来了解您正在使用哪个数据库,以便它可以随时随地切换到特定于数据库的 SQL 生成器代码。
【讨论】:
以上是关于为啥需要配置数据源的 SQL 方言?的主要内容,如果未能解决你的问题,请参考以下文章
Hibernate SQL方言 (hibernate.dialect) Spring配置文件applicationContext.xml