自己做局域网站,广告设计公司创业计划书,网站营销推广培训,网络营销策略包含哪些要素我喜欢集成测试#xff0c;这是检查Hibernate生成哪些幕后花絮的SQL查询的好方法。 但是集成测试需要运行的数据库服务器#xff0c;这是您必须要做的第一选择。 1.使用类似生产的本地数据库服务器进行集成测试 对于生产环境#xff0c;我始终喜欢使用增量DDL脚本#xff… 我喜欢集成测试这是检查Hibernate生成哪些幕后花絮的SQL查询的好方法。 但是集成测试需要运行的数据库服务器这是您必须要做的第一选择。 1.使用类似生产的本地数据库服务器进行集成测试 对于生产环境我始终喜欢使用增量DDL脚本因为我始终可以知道在给定服务器上部署了什么版本以及哪些是需要部署的较新脚本。 我一直依靠Flyway来为我管理模式更新对此我非常满意。 在一个集成测试量很小的小型项目中您也可以使用类似于生产的本地数据库服务器进行测试。 这是最安全的选择因为它可以确保您在生产设置非常相似的环境下进行测试。 主要缺点是测试速度。 使用外部数据库意味着额外的时序成本这很容易在大型项目中失控。 毕竟谁喜欢每天运行60分钟的测试程序 2.内存数据库集成测试 我选择使用内存数据库进行集成测试的原因是为了加快测试的运行时间。 这是影响测试运行时间的一个方面还有许多其他方面可能会影响您例如销毁和重新创建包含大量bean依赖项的Spring应用程序上下文。 您可以选择许多内存数据库 HSQLDB H2 Apache Derby 仅举几例。 我一直在使用两种内存中模式生成策略它们都有优点和缺点下面将对它们进行解释。 2.1利用hibernate.hbm2ddl.auto ” update” Hibernate在配置它时非常灵活。 幸运的是我们可以使用“ hibernate.hbm2ddl.auto” SessionFactory属性来自定义DDL生成。 部署架构的最简单方法是使用“更新”选项。 这对于测试目的很有用。 在生产环境中我不会依赖它对于增量环境而言增量DDL脚本是一种更好的方法。 因此选择“更新”选项是Integration Testing架构管理的一种选择。 这就是我在Hibernate Facts代码示例中使用它的方式。 让我们从JPA配置开始您可以在META-INF / persistence.xml文件中找到 ?xml version1.0 encodingUTF-8?
persistence version2.0xmlnshttp://java.sun.com/xml/ns/persistencexmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsdpersistence-unit nametestPersistenceUnit transaction-typeJTAproviderorg.hibernate.ejb.HibernatePersistence/providerexclude-unlisted-classesfalse/exclude-unlisted-classespropertiesproperty namehibernate.archive.autodetectionvalueclass, hbm/property namehibernate.transaction.jta.platformvalueorg.hibernate.service.jta.platform.internal.BitronixJtaPlatform /property namehibernate.dialectvalueorg.hibernate.dialect.HSQLDialect/emproperty namehibernate.hbm2ddl.autovalueupdate//emproperty namehibernate.show_sqlvaluetrue//properties/persistence-unit
/persistence 并且dataSource配置如下所示 bean iddataSource classorg.springframework.jdbc.datasource.TransactionAwareDataSourceProxyconstructor-argbean classbitronix.tm.resource.jdbc.PoolingDataSource init-methodinitdestroy-methodcloseproperty nameclassName valuebitronix.tm.resource.jdbc.lrc.LrcXADataSource/property nameuniqueName valuetestDataSource/property nameminPoolSize value0/property namemaxPoolSize value5/property nameallowLocalTransactions valuetrue /property namedriverPropertiespropsprop keyuser${jdbc.username}/propprop keypassword${jdbc.password}/propprop keyurl${jdbc.url}/propprop keydriverClassName${jdbc.driverClassName}/prop/props/property/bean/constructor-arg/bean 我认为Bitronix是我使用过的最可靠的工具之一。 在开发JEE应用程序时我利用了使用中的Application Server提供的Transaction Manager。 对于基于Spring的项目我必须雇用独立的事务管理器在评估JOTMAtomikos和Bitronix之后我选择了Bitronix。 那是5年前自从我部署并使用了几个应用程序以来。 即使应用程序当前仅使用一个数据源我还是更喜欢使用XA Transactions。 我不必担心使用JTA会明显降低性能因为当当前事务仅使用一个登记的数据源时Bitronix使用1PC单阶段提交 。 由于最后一次资源提交的优化它还可以添加一个非XA数据源。 使用JTA时建议不要混合使用XA和本地事务因为并非所有XA数据源都允许在本地事务中进行操作因此我倾向于尽可能避免这种情况。 不幸的是就像这种DDL生成方法一样简单它有一个我不太喜欢的缺陷。 我不能禁用“ allowLocalTransactions”设置因为Hibernate会创建DDL脚本并在XA事务之外对其进行更新。 另一个缺点是您几乎无法控制Hibernate代表您部署的DDL脚本在这种特定的情况下我不希望牺牲灵活性而不是方便性。 如果您不使用JTA并且不需要决定在当前数据库服务器上部署哪种DDL模式的灵活性那么hibernate.hbm2ddl.auto “ update”可能是您的正确选择。 2.2灵活的架构部署 此方法包括两个步骤。 前者将使Hibernate生成DDL脚本而后者将以自定义方式部署它们。 要生成DDL脚本我必须使用以下Ant任务即使正在通过Maven运行这是因为在编写本文时没有可以使用的Hibernate 4 Maven插件 plugingroupIdorg.apache.maven.plugins/groupIdartifactIdmaven-antrun-plugin/artifactIdexecutionsexecutionidgenerate-test-sql-scripts/idphasegenerate-test-resources/phasegoalsgoalrun/goal/goalsconfigurationtasksproperty namemaven_test_classpath refidmaven.test.classpath/path idhibernate_tools_pathpathelement path${maven_test_classpath}//pathproperty namehibernate_tools_classpath refidhibernate_tools_path/taskdef namehibernatetoolclassnameorg.hibernate.tool.ant.HibernateToolTask/mkdir dir${project.build.directory}/test-classes/hsqldb/hibernatetool destdir${project.build.directory}/test-classes/hsqldbclasspath refidhibernate_tools_path/jpaconfiguration persistenceunittestPersistenceUnitpropertyfilesrc/test/resources/META-INF/spring/jdbc.properties/hbm2ddl dropfalse createtrue exportfalseoutputfilenamecreate_db.sqldelimiter; formattrue/hbm2ddl droptrue createfalse exportfalseoutputfilenamedrop_db.sqldelimiter; formattrue//hibernatetool/tasks/configuration/execution/executions...
/plugin 有了“创建”和“删除” DDl脚本后我们现在必须在Spring上下文启动时部署它们这是使用以下自定义Utility类完成的 public class DatabaseScriptLifecycleHandler implements InitializingBean, DisposableBean {private final Resource[] initScripts;private final Resource[] destroyScripts;private JdbcTemplate jdbcTemplate;Autowiredprivate TransactionTemplate transactionTemplate;private String sqlScriptEncoding UTF-8;private String commentPrefix --;private boolean continueOnError;private boolean ignoreFailedDrops;public DatabaseScriptLifecycleHandler(DataSource dataSource,Resource[] initScripts,Resource[] destroyScripts) {this.jdbcTemplate new JdbcTemplate(dataSource);this.initScripts initScripts;this.destroyScripts destroyScripts;}public void afterPropertiesSet() throws Exception {initDatabase();}public void destroy() throws Exception {destroyDatabase();}public void initDatabase() {final ResourceDatabasePopulator resourceDatabasePopulator createResourceDatabasePopulator();transactionTemplate.execute(new TransactionCallbackVoid() {Overridepublic Void doInTransaction(TransactionStatus status) {jdbcTemplate.execute(new ConnectionCallbackVoid() {Overridepublic Void doInConnection(Connection con) throws SQLException, DataAccessException {resourceDatabasePopulator.setScripts(getInitScripts());resourceDatabasePopulator.populate(con);return null;}});return null;}});}public void destroyDatabase() {final ResourceDatabasePopulator resourceDatabasePopulator createResourceDatabasePopulator();transactionTemplate.execute(new TransactionCallbackVoid() {Overridepublic Void doInTransaction(TransactionStatus status) {jdbcTemplate.execute(new ConnectionCallbackVoid() {Overridepublic Void doInConnection(Connection con) throws SQLException, DataAccessException {resourceDatabasePopulator.setScripts(getDestroyScripts());resourceDatabasePopulator.populate(con);return null;}});return null;}});}protected ResourceDatabasePopulator createResourceDatabasePopulator() {ResourceDatabasePopulator resourceDatabasePopulator new ResourceDatabasePopulator();resourceDatabasePopulator.setCommentPrefix(getCommentPrefix());resourceDatabasePopulator.setContinueOnError(isContinueOnError());resourceDatabasePopulator.setIgnoreFailedDrops(isIgnoreFailedDrops());resourceDatabasePopulator.setSqlScriptEncoding(getSqlScriptEncoding());return resourceDatabasePopulator;}
} 配置为 bean iddatabaseScriptLifecycleHandler classvladmihalcea.util.DatabaseScriptLifecycleHandlerdepends-ontransactionManagerconstructor-arg namedataSource refdataSource/constructor-arg nameinitScriptsarraybean classorg.springframework.core.io.ClassPathResourceconstructor-arg valuehsqldb/create_db.sql//bean/array/constructor-argconstructor-arg namedestroyScriptsarraybean classorg.springframework.core.io.ClassPathResourceconstructor-arg valuehsqldb/drop_db.sql//bean/array/constructor-arg
/bean 这次我们可以摆脱任何本地交易因此可以安全地设置 property nameallowLocalTransactions valuefalse / 代码可在GitHub上获得 。 参考 Hibernate Facts来自JCG合作伙伴 Vlad Mihalcea的集成测试策略来自Vlad Mihalcea的Blog博客。 翻译自: https://www.javacodegeeks.com/2013/12/hibernate-facts-integration-testing-strategies.html