简体   繁体   English

Oracle和SQLServer上的Hibernate

[英]Hibernate on Oracle AND SQLServer

I'm introducing a DAO layer in our application currently working on SQL Server because I need to port it to Oracle. 我正在我们的应用程序中引入一个DAO层,目前正在使用SQL Server,因为我需要将它移植到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. 我想使用Hibernate并编写工厂(或使用依赖注入)来根据部署配置选择正确的DAO。 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? 我应该有两个包含不同hibernate.cfg.xml和* .hbm.xml文件的包,并在我的工厂中相应地选择它们吗? Is there any chance that my DAOs will work correctly with both DBMS without (too much) hassle? 我的DAO是否有可能在没有(太多)麻烦的情况下与两个DBMS一起正常工作?

Assuming that the table names and columns are the same between the two, you should be able to use the same hbm.xml files. 假设表名和列在两者之间是相同的,您应该能够使用相同的hbm.xml文件。 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. 但是,您肯定需要提供不同的Hibernate配置值( hibernate.cfg.xml ),因为您需要将Hibernate的方言从SQLServer更改为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 and yourproject-oracle-mappings.jar ), and deploy the application with one JAR or the other depending on the environment. 如果两者之间存在细微的名称差异,那么我将创建两组映射文件 - 每个数据库服务器一个 - 并将它们打包到单独的JAR中(例如yourproject-sqlserver-mappings.jaryourproject-oracle-mappings.jar ),并根据环境使用一个JAR或另一个部署应用程序。

I did this for a client a while back -- at deployment depending on a property set in a production.properties file I changed out the hibernate.dialect in the cfg file using Ant (you can use any xml transformer). 我在一段时间内为客户端做了这个 - 在部署时,取决于在production.properties文件中设置的属性,我使用Ant更改了cfg文件中的hibernate.dialect (您可以使用任何xml转换器)。 However this would only work if the Hibernate code is seamless btw both DBs ie no db-specific function calls etc. HQL/JPAQL has standard function calls that help ion this regard like UPPER(s) , LENGTH(s) etc. 但是,这只有在Hibernate代码无缝两个DB的情况下才有效,即没有特定于db的函数调用等.HQL / JPAQL具有标准函数调用,可以帮助实现这一点,如UPPER(s)LENGTH(s)等。

If the db implementations must necessarily be different then you'd have to do something like what @matt suggested. 如果db实现必须是不同的,那么你必须做像@matt建议的那样的事情。

I've worked on an app that supports a lot of databases (Oracle, Informix, SQL Server, MySQL). 我已经开发了一个支持大量数据库的应用程序(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. 我们使用jndi进行数据库连接,因此我们不必在应用程序中处理不同的连接URL。 When we initialize the SessionFactory we have a method that deduces the type of database from the underlying connection. 当我们初始化SessionFactory时,我们有一个方法可以从底层连接中推断出数据库的类型。 For example, manually get a connection via JNDI and then use connection.getMetaData().getDatabaseProductName() to find out what the database is. 例如,通过JNDI手动获取连接,然后使用connection.getMetaData()。getDatabaseProductName()来查找数据库是什么。 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. 然后使用configuration.setProperty(Environment.DIALECT,deducedDialect)设置方言并正常初始化SessionFactory。

Some things you have to deal with: 你需要处理的一些事情:

  • Primary key generation. 主键生成。 We use a customized version of the TableGenerator strategy so we have one key table with columns for table name and next key. 我们使用TableGenerator策略的自定义版本,因此我们有一个密钥表,其中包含表名和下一个键的列。 This way every database can use the same strategy rather than sequence in Oracle, native for SQL Server, etc. 这样,每个数据库都可以使用相同的策略而不是Oracle中的序列,SQL Server的本机等。
  • Functions specific to databases. 特定于数据库的函数。 We avoid them when possible. 我们尽可能避免它们。 Hibernate dialects handle the most common ones. Hibernate方言处理最常见的方言。 Occasionally we'll have to add our own to our custom dialect classes, .eg date arithmetic is pretty non-standard, so we'll just make up a function name and map it to each database's way of doing it. 偶尔我们必须将自己的方法添加到我们的自定义方言类中。例如,日期算术非常不标准,所以我们只需要组成一个函数名称并将其映射到每个数据库的方法。
  • Schema generation - we use the Hibernate schema generation class - it works with the dialects to create the correct DDL for each type of database and forces the database to match the mappings. 模式生成 - 我们使用Hibernate模式生成类 - 它与方言一起使用,为每种类型的数据库创建正确的DDL,并强制数据库匹配映射。 You have to be aware of the keywords for each database, eg don't try to have a USER table in Oracle (USERS will work), or a TRANSLATION table in MySQL. 您必须知道每个数据库的关键字,例如,不要尝试在Oracle中使用USER表(USERS将起作用),或在MySQL中使用TRANSLATION表。

There is a table mapping the differences between Oracle and SQLServer here: http://psoug.org/reference/sqlserver.html 这里有一个映射Oracle和SQLServer之间差异的表: http//psoug.org/reference/sqlserver.html

In my opinion the biggest pitfalls are: 1) Dates. 在我看来,最大的陷阱是:1)日期。 The functions and mechanics are completely different. 功能和机制完全不同。 You will have to use different code for each DB. 您必须为每个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". 2)密钥生成 - Oracle和SQLServer使用不同的机制,如果您尝试通过拥有自己的密钥表来完全避免“本机”生成 - 那么,您只需完全序列化所有“插入”。 Not good for performance. 表现不佳。 3) Concurrency/locking is a bit different. 3)并发/锁定有点不同。 Parts of the code that is performance sensitive will probably be different for each DB. 对于每个数据库,性能敏感的代码部分可能会有所不同。 4) Oracle is case sensitive, SQLServer is not. 4)Oracle区分大小写,而SQLServer则不区分大小写。 You need to be careful with that. 你需要小心。

There are lots more :) Writing SQL code that will run on two DBs is challenging. 还有很多:)编写将在两个DB上运行的SQL代码具有挑战性。 Making it fast can seem nearly impossible at times. 快速制作似乎几乎不可能。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM