我在我们目前在 SQL Server 上工作的应用程序中引入了一个 DAO 层,因为我需要将它移植到 Oracle。
我想使用 Hibernate 并编写一个工厂(或使用依赖注入)来根据部署配置选择正确的 DAO。在这种情况下,最佳实践是什么?我应该有两个具有不同 hibernate.cfg.xml 和 *.hbm.xml 文件的包并在我的工厂中相应地选择它们吗?我的 DAO 是否有可能在没有(太多)麻烦的情况下与两个 DBMS 一起正常工作?
我在我们目前在 SQL Server 上工作的应用程序中引入了一个 DAO 层,因为我需要将它移植到 Oracle。
我想使用 Hibernate 并编写一个工厂(或使用依赖注入)来根据部署配置选择正确的 DAO。在这种情况下,最佳实践是什么?我应该有两个具有不同 hibernate.cfg.xml 和 *.hbm.xml 文件的包并在我的工厂中相应地选择它们吗?我的 DAO 是否有可能在没有(太多)麻烦的情况下与两个 DBMS 一起正常工作?
假设两者之间的表名和列相同,您应该可以使用相同的hbm.xml
文件。但是,您肯定需要提供不同的 Hibernate 配置值 ( hibernate.cfg.xml
),因为您需要将 Hibernate 的方言从 SQLServer 更改为 Oracle。
如果两者之间存在细微的名称差异,那么我将创建两组映射文件 - 每个数据库服务器一组 - 并将它们打包成单独的 JAR(例如yourproject-sqlserver-mappings.jar
和yourproject-oracle-mappings.jar
),然后使用一个 JAR 或另一个部署应用程序,具体取决于环境。
不久前我为一个客户做了这个——在部署时,取决于文件中设置的属性,我使用 Antproduction.properties
更改了文件hibernate.dialect
中的属性(您可以使用任何 xml 转换器)。cfg
然而,这只有在 Hibernate 代码是无缝的 btw 两个 DB 时才有效,即没有特定于 db 的函数调用等。HQL/JPAQL 有标准的函数调用,可以帮助解决这方面的问题UPPER(s)
,LENGTH(s)
等等。
如果数据库实现必须不同,那么您必须执行@matt 建议的操作。
我开发了一个支持很多数据库(Oracle、Informix、SQL Server、MySQL)的应用程序。我们有一个配置文件和一组映射。我们使用 jndi 进行数据库连接,因此我们不必在应用程序中处理不同的连接 URL。当我们初始化 SessionFactory 时,我们有一个从底层连接推断数据库类型的方法。例如,通过 JNDI 手动获取连接,然后使用 connection.getMetaData().getDatabaseProductName() 找出数据库是什么。您还可以使用容器环境变量来显式设置它。然后使用 configuration.setProperty(Environment.DIALECT, deducedDialect) 设置方言并正常初始化 SessionFactory。
你必须处理的一些事情:
这里有一张表映射了 Oracle 和 SQLServer 之间的差异:http: //psoug.org/reference/sqlserver.html
在我看来,最大的陷阱是:1)日期。功能和机制完全不同。您将不得不为每个数据库使用不同的代码。2) 密钥生成——Oracle 和 SQLServer 使用不同的机制,如果你试图通过拥有自己的密钥表来完全避免“本机”生成——那么,你只是完全序列化了所有“插入”。对性能不好。3)并发/锁定有点不同。对于每个数据库,性能敏感的部分代码可能会有所不同。4) Oracle 区分大小写,SQLServer 不区分。你需要小心。
还有更多 :) 编写将在两个数据库上运行的 SQL 代码具有挑战性。有时让它变得更快似乎几乎是不可能的。