Oracle 和 SQLServer 上的休眠
我在当前运行于 SQL Server 上的应用程序中引入了 DAO 层,因为我需要将其移植到 Oracle。
我想使用 Hibernate 并编写一个工厂(或使用依赖注入)来根据部署配置选择正确的 DAO。在这种情况下,最佳实践是什么?我是否应该有两个包含不同 hibernate.cfg.xml 和 *.hbm.xml 文件的包并在我的工厂中相应地选择它们?我的 DAO 是否有可能在两个 DBMS 中正常工作而不会出现(太多)麻烦?
I'm introducing a DAO layer in our application currently working on SQL Server because I need to port it to Oracle.
I'd like to use Hibernate and write a factory (or use dependency injection) to pick the correct DAOs according to the deployment configuration. What are the best practices in this case? Should I have two packages with different hibernate.cfg.xml and *.hbm.xml files and pick them accordingly in my factory? Is there any chance that my DAOs will work correctly with both DBMS without (too much) hassle?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
假设两者之间的表名和列相同,您应该能够使用相同的
hbm.xml
文件。然而,您肯定需要提供不同的 Hibernate 配置值 (hibernate.cfg.xml
),因为您需要将 Hibernate 的方言从 SQLServer 更改为 Oracle。如果两者之间存在轻微的名称差异,那么我将创建两组映射文件 - 每个数据库服务器一组 - 并将它们打包到单独的 JAR 中(例如
yourproject-sqlserver-mappings.jar
和yourproject-oracle-mappings.jar
),并根据环境使用一个或另一个 JAR 部署应用程序。Assuming that the table names and columns are the same between the two, you should be able to use the same
hbm.xml
files. However you will certainly need to supply different a Hibernate Configuration value (hibernate.cfg.xml
), as you will need to change Hibernate's dialect from SQLServer to Oracle.If there are slight name differences between the two, then I would create two sets of mapping files - one per Database server - and package these up into separate JARs (such as
yourproject-sqlserver-mappings.jar
andyourproject-oracle-mappings.jar
), and deploy the application with one JAR or the other depending on the environment.不久前,我为一个客户做了这件事——在部署时,根据
production.properties
文件中设置的属性,我更改了中的
文件(您可以使用任何 xml 转换器)。然而,只有当 Hibernate 代码在两个数据库之间都是无缝的,即没有特定于数据库的函数调用等时,这才有效。HQL/JPAQL 有标准函数调用,可以帮助解决这方面的问题,例如hibernate.dialect
使用 Ant 创建 .cfgUPPER(s)
、LENGTH(s)
等。如果数据库实现必须不同,那么您必须执行 @matt 建议的操作。
I did this for a client a while back -- at deployment depending on a property set in a
production.properties
file I changed out thehibernate.dialect
in thecfg
file using Ant (you can use any xml transformer). However this would only work if the Hibernate code is seamless btw both DBs i.e. no db-specific function calls etc. HQL/JPAQL has standard function calls that help ion this regard likeUPPER(s)
,LENGTH(s)
etc.If the db implementations must necessarily be different then you'd have to do something like what @matt suggested.
我开发过一个支持多种数据库(Oracle、Informix、SQL Server、MySQL)的应用程序。我们有一个配置文件和一组映射。我们使用 jndi 进行数据库连接,因此不必在应用程序中处理不同的连接 URL。当我们初始化 SessionFactory 时,我们有一个方法可以从底层连接中推断出数据库的类型。例如,通过JNDI手动获取连接,然后使用connection.getMetaData().getDatabaseProductName()来找出数据库是什么。您还可以使用容器环境变量来显式设置它。然后使用configuration.setProperty(Environment.DIALECT, deducedDialect) 设置方言并正常初始化SessionFactory。
您必须处理的一些事情:
I've worked on an app that supports a lot of databases (Oracle, Informix, SQL Server, MySQL). We have one configuration file and one set of mappings. We use jndi for the database connection so we don't have to deal with different connection URLs in the app. When we initialize the SessionFactory we have a method that deduces the type of database from the underlying connection. For example, manually get a connection via JNDI and then use connection.getMetaData().getDatabaseProductName() to find out what the database is. You could also use a container environment variable to explicitly set it. Then set the dialect using configuration.setProperty(Environment.DIALECT, deducedDialect) and initialize the SessionFactory as normal.
Some things you have to deal with:
这里有一个表映射了 Oracle 和 SQLServer 之间的差异: http://psoug.org/reference/sqlserver .html
在我看来,最大的陷阱是:
1)日期。功能和机制完全不同。您必须为每个数据库使用不同的代码。
2) 密钥生成 - Oracle 和 SQLServer 使用不同的机制,如果您尝试通过拥有自己的密钥表来完全避免“本机”生成 - 那么,您只需完全序列化所有“插入”即可。对性能不利。
3)并发/锁定有点不同。对于每个数据库,性能敏感的代码部分可能会有所不同。
4) Oracle 区分大小写,SQLServer 不区分大小写。你需要小心这一点。
还有很多:)
编写将在两个数据库上运行的 SQL 代码具有挑战性。有时,让它变得快速似乎几乎是不可能的。
There is a table mapping the differences between Oracle and SQLServer here: http://psoug.org/reference/sqlserver.html
In my opinion the biggest pitfalls are:
1) Dates. The functions and mechanics are completely different. You will have to use different code for each DB.
2) Key generation - Oracle and SQLServer use different mechanics and if you try to avoid the "native" generation altogether by having your own keys table - well, you just completely serialized all your "inserts". Not good for performance.
3) Concurrency/locking is a bit different. Parts of the code that is performance sensitive will probably be different for each DB.
4) Oracle is case sensitive, SQLServer is not. You need to be careful with that.
There are lots more :)
Writing SQL code that will run on two DBs is challenging. Making it fast can seem nearly impossible at times.