Hibernate底层依然使用SQL语句来执行数据库操作,虽然所有关系型数据库都支持使用标准SQL语句,但所有数据库都对标准SQL进行了一些扩展,所以在语法细节上存在一些差异,因此Hibernate需要根据数据库来识别这些差异。

举例来说,我们在MySQL数据库里进行分页查询,只需使用limit关键字就可以了;而标准SQL并不支持limit关键字,例如Oracle则需要使用行内视图的方式来进行分页。同样的应用程序,当我们在不同数据库之间迁移时,底层数据库的访问细节会发生改变,而Hibernate也为这种改变做好了准备,现在我们需要做的是:告诉Hibernate应用程序的底层即将使用哪种数据库——这就是数据库方言。

一旦我们为Hibernate设置了合适的数据库方言,Hibernate将可以自动应付底层数据库访问所存在的细节差异。

不同数据库所应使用的方言如表5.1所示。

表 不同数据库及其对应方言

关系数据库

方 言

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

org.hibernate.dialect.Oracle9iDialect

Oracle 10g

org.hibernate.dialect.Oracle10gDialect

 

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

如果一个系统可能运行于多种数据库,或者同时使用多种数据库,那么,使用Hibernate将会给你带来很多的方便,想信很多接触Hibernate的人都会体会到。Hibernate底层是通过dialect包来对各种数据库的差异进行抽象的。Dialect类中实现每种数据库相同的东西,而不同数据库对应会有该类的一个扩展实现,最终通过DialectFactory来决定创建哪一个类。通常我们都会指定hibernate.dialect属性,那直接创建该属性对应的类。如果我们没有指定该属性,那么由Hibernate自己决定选择合适的方言。在DialectFactory中初始化各种数据库对应的方言的Map,以数据库产品名为key,以方言的包装对象为value。Hibernate自动选择方言时,会通过JDBC的DatabaseMetadata取得数据库的产品名称,根据名称取得对应的方言。DialectFactory中对该Map的初始化的部分代码如下:

  1. // TODO : this is the stuff it'd be nice to move to a properties file or some other easily user-editable place
  2. private static final Map MAPPERS = new HashMap();
  3. static {
  4. // detectors...
  5. MAPPERS.put( "HSQL Database Engine", new VersionInsensitiveMapper( "org.hibernate.dialect.HSQLDialect" ) );
  6. MAPPERS.put( "H2", new VersionInsensitiveMapper( "org.hibernate.dialect.H2Dialect" ) );
  7. MAPPERS.put( "MySQL", new VersionInsensitiveMapper( "org.hibernate.dialect.MySQLDialect" ) );
  8. MAPPERS.put( "PostgreSQL", new VersionInsensitiveMapper( "org.hibernate.dialect.PostgreSQLDialect" ) );
  9. MAPPERS.put( "Apache Derby", new VersionInsensitiveMapper( "org.hibernate.dialect.DerbyDialect" ) );
  10. <SPAN>...</SPAN> 原本上,这种自动选择的方式,会给我们带来方便,只可惜,从以上的代码的注释中可以知道,目前这一部分的初始化是通过硬编码的,只有在以后的版本才会移动到配置文件或其他容易用户编译的地方,否则,我们可以非常容易的添加我们的配置供Hibernate进行自动选择。而经常我们所使用的数据库驱动程序所取到的数据库产品名称会跟以上硬编码的不同,所以最终我们还是得自己配置数据库方言。

    由于我们的系统中用到了好几个数据源,经常也是对应不同类型的数据库,并且数据源都是由容器提供的,在首次部署时经常因为数据库类型变了而忘了修改对应的数据库方言,而出了问题,这给实施人员带来了很多的不便。不过目前除了对各种数据库提供与以上硬编码相同的数据库产品名称的驱动程序外,我们就只能自己动手了

  11. Hibernate对各数据库的连接方言

  12. <session-factory>
    <property name="connection.driver_class">net.sourceforge.jtds.JDBC.Driver</property>
    <property name="connection.url">jdbc:jtds:sqlserver://ALEX:1134/News</property>
    <!--for Oracle 9
    <property name="dialect">org.Hibernate.dialect.Oracle9Dialect</property>
    -->
    <!--for MySQL
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    -->
    <!--for Ms SQL Server-->
    <property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
    <property name="connection.username">sa</property>
    <property name="connection.password">sa</property>
    <property name="show_sql">true</property>
    </session-factory> ? <!--MySql 驱动程序 eg. mysql-connector-java-5.0.4-bin.jar-->
    <property name="dialect">org.hibernate.dialect.MySQLDialect</property>
    <property name="connection.driver_class">com.mysql.jdbc.Driver</property> <!-- JDBC URL -->
    <property name="connection.url">jdbc:mysql://localhost/dbname?characterEncoding=gb2312</property> <!-- 数据库用户名-->
    <property name="connection.username">root</property> <!-- 数据库密码-->
    <property name="connection.password">root</property> <!--Sql Server 驱动程序 eg. jtds-1.2.jar-->
    <property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
    <property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property> <!-- JDBC URL -->
    <property name="connection.url">jdbc:jtds:sqlserver://localhost:1433;DatabaseName=dbname</property> <!-- 数据库用户名-->
    <property name="connection.username">sa</property> <!-- 数据库密码-->
    <property name="connection.password"></property> <!--Oracle 驱动程序 ojdbc14.jar-->
    <property name="dialect">org.hibernate.dialect.OracleDialect</property>
    <property name="connection.driver_class">oracle.jdbc.driver.OracleDriver</property> <!-- JDBC URL -->
    <property name="connection.url">jdbc:oracle:thin:@localhost:1521:dbname</property> <!-- 数据库用户名-->
    <property name="connection.username">test</property> <!-- 数据库密码-->
    <property name="connection.password">test</property> 如果出现如下错误,则可能是Hibernate SQL方言 (hibernate.dialect)设置不正确。
    Caused by: java.sql.SQLException: [Microsoft][SQLServer 2000 Driver for JDBC][SQLServer]'last_insert_id' 不是可以识别的 函数名。 ? RDBMS 方言
    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

      

详解在Hibernate中配置数据库方言的作用和好处以及各种数据库的方言连接的更多相关文章

  1. 【转】 详解Kafka生产者Producer配置

    粘贴一下这个配置,与我自己的程序做对比,看看能不能完善我的异步带代码:   -----------------------------------------    详解Kafka生产者Produce ...

  2. ubuntu apache2配置详解(含虚拟主机配置方法)

    ubuntu apache2配置详解(含虚拟主机配置方法) 在Windows下,Apache的配置文件通常只有一个,就是httpd.conf.但我在Ubuntu Linux上用apt-get inst ...

  3. Spring、Spring事务详解;使用XML配置事务

    @Transactional可以设置以下参数: @Transactional(readOnly=false) // 指定事务是否只读的 true/false @Transactional(rollba ...

  4. NUint使用详解及Visual Studio配置

    NUint使用详解及Visual Studio配置 阅读目录 什么是单元测试? 为什么使用单元测试? NUint使用详解: 示例 属性 断言 简单测试 VS配置: External Tools Vis ...

  5. [转载]详解网络传输中的三张表,MAC地址表、ARP缓存表以及路由表

    [转载]详解网络传输中的三张表,MAC地址表.ARP缓存表以及路由表 虽然学过了计算机网络,但是这部分还是有点乱.正好在网上看到了一篇文章,讲的很透彻,转载过来康康. 本文出自 "邓奇的Bl ...

  6. Ubuntu19.04的安装过程详解以及操作系统初始化配置

    Ubuntu19.04的安装过程详解以及操作系统初始化配置                                                                       ...

  7. 详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别

    详解 $_SERVER 函数中QUERY_STRING和REQUEST_URI区别 http://blog.sina.com.cn/s/blog_686999de0100jgda.html   实例: ...

  8. 详解 Go 语言中的 time.Duration 类型

    swardsman详解 Go 语言中的 time.Duration 类型swardsman · 2018-03-17 23:10:54 · 5448 次点击 · 预计阅读时间 5 分钟 · 31分钟之 ...

  9. 详解jquery插件中(function ( $, window, document, undefined )的作用。

    1.(function(window,undefined){})(window); Q:(function(window,undefined){})(window);中为什么要将window和unde ...

随机推荐

  1. Linux curl 常用命令

    命令:curl在Linux中curl是一个利用URL规则在命令行下工作的文件传输工具,可以说是一款很强大的http命令行工具.它支持文件的上传和下载,是综合传输工具,但按传统,习惯称url为下载工具. ...

  2. Django之QuerySet 创建对象

    在前面的模型介绍中设置了3个对象,出版商(publisher),作者(Authro),书籍(book).首先我们在网页中添加各个对象信息填写的界面.填写后点击提交.将会传递给后端.传递方式采用post ...

  3. 循环队列(Joseplus Problem)

    #include <iostream> #include <stdio.h> using namespace std; ]; ; void Enqueue(int x) { ) ...

  4. 【机器学习】李宏毅机器学习-Keras-Demo-神经网络手写数字识别与调参

    参考: 原视频:李宏毅机器学习-Keras-Demo 调参博文1:深度学习入门实践_十行搭建手写数字识别神经网络 调参博文2:手写数字识别---demo(有小错误) 代码链接: 编程环境: 操作系统: ...

  5. 设计一个MQ的考虑点

    转自: https://segmentfault.com/a/1190000004461970 序 这里总结下MQ的研究点,以及如果要自己设计一个MQ应该考虑的因素. 考虑点 1.远程通信功能 (1) ...

  6. USACO 1.3.6 Ski Course Design[滑雪课程设计]

    先说说思路: 这题比上一道坑人的wormholes简单多了!我一看到这题,“XXX设计”,还以为要用到什么dp呢,没想到是水题 用两层循环,第一层循环相差17中的上界,第二层遍历所有的山峰计算答案.并 ...

  7. Docker部署MySql应用

    1. MySQL部署 1.1拉取MySQL镜像 docker pull mysql 查看镜像 docker images 1.2创建MySQL容器 docker run -di --name piny ...

  8. 数据结构11: 栈(Stack)的概念和应用及C语言实现

    栈,线性表的一种特殊的存储结构.与学习过的线性表的不同之处在于栈只能从表的固定一端对数据进行插入和删除操作,另一端是封死的. 图1 栈结构示意图 由于栈只有一边开口存取数据,称开口的那一端为“栈顶”, ...

  9. C++基础学习7:new/delete操作符

    在C语言中,动态分配和释放内存的函数是malloc.calloc和free,而在C++语言中,new.new[].delete和delete[]操作符通常会被用来动态地分配内存和释放内存. 需要注意的 ...

  10. kuangbin专题十六 KMP&&扩展KMP HDU1358 Period

    For each prefix of a given string S with N characters (each character has an ASCII code between 97 a ...