使用具有相同休眠映射文件的两个不同数据库
基本上,这个想法是对两个不同的底层数据库使用相同的休眠映射文件。在生产中,底层数据库是 MySQL5,出于测试目的,我想使用 Apache Derby - 以避免出于测试目的设置和维护各种 MySQL 数据库。
我希望只需切换数据源的驱动程序并更改一些参数即可完成这项工作,但我已经遇到了一些小困难。所以实际上有两个问题。第一个具体问题是:
I. 如果某个数据类型在 MySQL 中可用但在 Derby 中不存在,是否可以告诉 Derby 使用哪种数据类型。映射如下:
<property name="about">
<column name="`about`" not-null="false" sql-type="text"></column>
</property>
Derby 不知道 sql 类型“text”,因此它拒绝创建表。它是 Derby 10.4.2.0 和 Hibernate 3.2.6。顺便一提。
二.您在测试和生产中使用两个不同的数据库有什么经验?我知道有一些缺点,例如您无法测试存储过程或数据库特定查询 - 但另一方面,它使测试变得更容易和更快(如果您最终运行它)。你怎么认为?
Basically the idea is to use the same hibernate mapping files for two different underlying databases. In production the underlying database is MySQL5 and for testing purposes I'd like to use Apache Derby - in order to avoid setting up and maintaining various MySQL databases for testing purposes.
I hoped that just switching the DataSource's Driver and changing a few params would do the job, but I've already run into some minor difficulties. So there are in fact two questions. The first concrete question is:
I. Is it possible to tell Derby which datatype to use if a datatype is available in MySQL and is not in Derby. The mapping is as follows:
<property name="about">
<column name="`about`" not-null="false" sql-type="text"></column>
</property>
Derby doesn't know the sql-type "text" so it refuses to create the table. It is Derby 10.4.2.0 and Hibernate 3.2.6. by the way.
II. What's your experience with using two different databases for testing and in production? I know there are some drawbacks that e.g. you can't test stored procedures or database specific queries - but on the other hand it makes testing easier and faster (if you finally got it running). What do you think?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
问题#1 - 不指定 sql 类型;使用 Hibernate 类型 相反:
您可以扩展 Hibernate 提供的 Derby(或 MySQL)方言,以根据(未)指定的长度将该类型映射到适当的数据库类型。看一下 MySQLDialect 的例子;它将字符串类型映射为
varchar
或基于长度的text
类型之一。问题#2 - 您的意思是使用不同的数据库进行开发和生产吗?因为使用不同的数据库进行测试和生产就像玩满桶的俄罗斯轮盘赌 - 你不会赢:-)
你总是需要测试所有适用的部署配置。如果您确实需要支持两者,那么使用不同的数据库进行开发和生产并不是一个坏方法,因为它有助于及早找到可移植性问题。
Question #1 - don't specify sql type; use Hibernate type instead:
You can then extend Derby (or MySQL) dialect provided by Hibernate to map that type to appropriate DB type based on (un)specified length. Take a look at MySQLDialect for an example; it maps string type to either
varchar
or one oftext
types based on length.Question #2 - did you mean using different databases for development and production? Because using different databases for testing and production is like playing a Russian roulette with fully loaded barrel - you ain't gonna win :-)
You always need to test all applicable deployment configurations. Using different DBs for development and production is not a bad approach if you indeed need to support both as it helps locate the portability issues early.
在我看来,在测试中使用不同类型的数据库的主要原因是为了进行更快的单元测试,在这种情况下伪造或模拟数据库是不切实际的(尽管如果可以的话,您应该做后者)。请注意,应该有一个临时会话,可以在其中针对生产类型的数据库运行测试,以确保您没有对测试数据库进行编码。它还迫使您编写通用数据库的代码——有时这是一个好主意,有时则不是。
显然,如果您需要数据库特定的函数(存储过程甚至特殊类型),您应该使用相同的类型。
对于 MySQL,您可以在测试中将表设置为 存储在内存中。如果您可能需要 MySQL 特定项目,这是一个选项。如果目标是数据库通用,那么在开发/低级测试中使用不同的数据库可能是一件好事。
The primary reason to use a different type of database in testing is, in my opinion, to have faster unit tests where it is impractical to fake or mock the database (although when you can you should do the latter). Note that there should be a staging session where the tests can run against a production type of database to make certain you are not coding to the test database. It also forces you to code to a generic database -- sometimes that is a good idea and sometimes that is not.
Obviously if you need a database specific function (stored procedure or even special type) you should use the same type.
In the case of MySQL, you can set up tables in a test to be stored in memory. If you are likely to need MySQL specific items that is an option. If the goal is to be database generic than using a different database in development/low-level testing can be a good thing.
不同环境下使用不同数据库厂商应该没有问题(注意ChssPly76的回答TEST和PROD应该是一样的)。虽然我还没有尝试过德比。
就我个人而言,我喜欢在 DEV 环境中使用 HSQLDB 。它体积小、灵活且易于携带,几乎不需要任何设置。使用像 Unitils 这样的工具将 Hibernate、DbUnit 和 JUnit 粘合在一起对我来说效果非常好。在执行 JUnit 测试之前,HSQLDB 会加载静态测试数据。这允许数据访问层 JUnit 测试具有基于真实数据的断言(它是从测试附近的一些 xml 文件加载的)。
(Unitils 需要注意的一点是,默认的“loadStrategy”是在加载之前删除所有现有数据,因此请小心您指向该内容的位置)。
There should be no problem to using different database vendors in different environments (pay attention to ChssPly76's answer that TEST and PROD should be the same). Although I haven't tried Derby (yet).
Personally I like to use HSQLDB for the DEV environment. It's small, flexible, and easily portable, requiring little-to-no setup. Using a tool like Unitils to glue together Hibernate, DbUnit, and JUnit has worked exceedingly well for me. Before the JUnit tests are executed the HSQLDB is loaded with static test data. This allows for the data access layer JUnit tests to have assertions based on real data (it's loaded from some xml files sitting near the tests).
(One word of caution with Unitils is that the default "loadStrategy" is to drop all existing data before loading, so be careful where you point that thing).
根据我的经验,您测试的数据库实现越多,您就越早发现任何意外依赖于不可跨数据库移植的东西的地方。
如果 Derby 使您的测试更快、更容易,那么这是一个很好的结果,因为更快、更容易的测试会鼓励更多的测试。
我认为 Derby 是测试的绝佳选择,因为 Derby 非常努力地遵守 SQL 标准并且仅支持标准中指定的语法和行为,因此这应该有助于确保您避免使用非- 标准数据库功能。
但我同意,当您接近部署应用程序时,您需要使用尽可能接近您的预期部署配置的配置来测试它。
In my experience, the more database implementations you test with, the sooner you find any places where you have accidentally depended on something which is not portable across databases.
If Derby is making your testing faster and easier, then that is a great result, since faster and easier testing encourages more testing.
I think that Derby is an excellent choice for testing with, as Derby tries very hard to conform to the SQL standard and to only support the syntax and behaviors that are specified in the standard, so this should help ensure that you are avoiding use of non-standard database features.
But I agree that as you get close to deploying your application, you need to be testing it using a configuration which is as close as possible to your intended deployment configuration.