详解在Hibernate中配置数据库方言的作用和好处以及各种数据库的方言连接
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 |
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 |
- // TODO : this is the stuff it'd be nice to move to a properties file or some other easily user-editable place
- private static final Map MAPPERS = new HashMap();
- static {
- // detectors...
- MAPPERS.put( "HSQL Database Engine", new VersionInsensitiveMapper( "org.hibernate.dialect.HSQLDialect" ) );
- MAPPERS.put( "H2", new VersionInsensitiveMapper( "org.hibernate.dialect.H2Dialect" ) );
- MAPPERS.put( "MySQL", new VersionInsensitiveMapper( "org.hibernate.dialect.MySQLDialect" ) );
- MAPPERS.put( "PostgreSQL", new VersionInsensitiveMapper( "org.hibernate.dialect.PostgreSQLDialect" ) );
- MAPPERS.put( "Apache Derby", new VersionInsensitiveMapper( "org.hibernate.dialect.DerbyDialect" ) );
- <SPAN>...</SPAN> 原本上,这种自动选择的方式,会给我们带来方便,只可惜,从以上的代码的注释中可以知道,目前这一部分的初始化是通过硬编码的,只有在以后的版本才会移动到配置文件或其他容易用户编译的地方,否则,我们可以非常容易的添加我们的配置供Hibernate进行自动选择。而经常我们所使用的数据库驱动程序所取到的数据库产品名称会跟以上硬编码的不同,所以最终我们还是得自己配置数据库方言。
由于我们的系统中用到了好几个数据源,经常也是对应不同类型的数据库,并且数据源都是由容器提供的,在首次部署时经常因为数据库类型变了而忘了修改对应的数据库方言,而出了问题,这给实施人员带来了很多的不便。不过目前除了对各种数据库提供与以上硬编码相同的数据库产品名称的驱动程序外,我们就只能自己动手了
Hibernate对各数据库的连接方言
-
- <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