数据库

位置:IT落伍者 >> 数据库 >> 浏览文章

利用HSQLDB进行Hibernate的单元测试一


发布日期:2020年07月09日
 
利用HSQLDB进行Hibernate的单元测试一

动机

曾经使用许多方法在数据库和目标代码之间传输数据从手动编码的SQL到JDO然后再到EJB我从未找到一种特别喜欢的方法自从采用测试驱动开发(TDD)作为指导原则以来这种不满情绪变得更加强烈

单元测试的障碍应尽可能少在关系数据库中障碍的范围从外部依赖(数据库在运行吗?)到保持关系模型和对象模型同步的速度由于这些原因保持数据库访问代码与核心对象模型分离且无需涉及真实数据库而进行尽可能多的测试是很重要的

通常这会导致我们进入下面两种模式之一第一种是具体化所有访问域对象的数据以及数据与单独类或接口之间的关系这就是典型的能够检索编辑删除和添加域实体的数据存储对象

这在单元测试中是最容易模拟出来的但趋向于把域模型对象作为不带有任何关系行为的纯数据对象直接从父对象访问子记录是最理想的而不是将父对象处理为第三方类来决定子记录

其他方法已经使访问接口的域对象进入数据映射层(一种la Martin Fowler的数据映象模式)这具有推动域模型中的对象关系的优点在域模型中对象关系型接口只需表达一次即可

使用域模型的类不支持持久性机制因为它本身内在化到域模型中这使代码集中在设法解决的业务问题而很少关注对象关系型映射机制

我的当前项目涉及到处理大量的棒球统计数据并使用这些数据进行模拟因为数据已经在关系数据库中所以对于我来说有机会开发Hibernate对象关系型映射系统

我曾对Hibernate有很深刻的印象但我遇到的一个问题是在使用Hibernate进行单元测试的数据映射时设法插入一个间接层

该附加层非常脆弱编写起来感到非常困难实际部署版本简单地通过了特定于Hibernate的实现更坏的情况是模拟版本比真正的产品级版本更复杂只因为模拟版本里没有基本对象存储器和带有Hibernate的映射

我也使用很多复杂的Hibernate查询想要对应用程序的重要部分进行单元测试然而对活动的数据库进行测试不是好主意因为这几乎总是产生维护问题

另外由于测试最好互相独立在测试上下文数据中使用相同的主键意味着必须在每次测试前创建代码来清理数据库当涉及到大量关系时就成为一个实际问题

通过使用HSQLDB和Hibernate强大的模式生成工具能够对应用程序映射层进行单元测试并在对象查询中找到不计其数的bug这在以前手工测试时是做不到的利用下面的技术概述可以在开发过程中对整个应用程序进行测试并且在测试有效区域内没有损害

设置HSQLDB

以前使用HSQLDB 为了使用数据库的内存版本需要激活orghsqldbjdbcDriver的静态加载程序当获得JDBC连接时就可以使用JDBC url例如jdbc:hspldb:mem:yourdb这里yourdb就是想要使用的内存数据库的名称

因为使用Hibernate ( beta )所以我几乎无需接触实际活动的JDBC对象相反我可以让Hibernate完成很多繁重的任务包括从Hibernate映射文件中自动创建数据库模式

因为Hibernate创建自身专有的连接池所以它会基于TestSchema类中的配置代码自动加载HSQLDB JDBC驱动程序下面就是该类的静态的初始化程序

public class TestSchema {

static {

Configuration config = new Configuration()

setProperty(hibernatedialect orghibernatedialectHSQLDialect)

setProperty(nnectiondriver_class orghsqldbjdbcDriver)

setProperty(nnectionurl jdbc:hsqldb:mem:baseball)

setProperty(nnectionusername sa)

setProperty(nnectionpassword )

setProperty(nnectionpool_size )

setProperty(nnectionautocommit true)

setProperty(hibernatecacheprovider_class

orghibernatecacheHashtableCacheProvider)

setProperty(hibernatehbmddlauto createdrop)

setProperty(hibernateshow_sql true)

addClass(Playerclass)

addClass(BattingStintclass)

addClass(FieldingStintclass)

addClass(PitchingStintclass);

HibernateUtilsetSessionFactory(configbuildSessionFactory());

}

Hibernate提供了许多不同的方式来配置该框架包括程序方面的配置上述代码设置了连接池注意使用HSQLDB的内存数据库需要用户名sa还样要确保指定一个空格作为口令为了启动Hibernate的自动模式生成功能需设置hibernatehbmddlauto属性为creatdrop

实际测试 我的项目是处理将大量的棒球数据所以我添加了四个进行映射的类(PlayerPintchingStintBattingSint和FieldStint)最后创建Hibernate的会话工厂并将其插入HibernateUtil类该类只为Hibernate会话的整个应用程序提供一个访问方法HibernateUtil的代码如下

import orghibernate*;

import orghibernatecfgConfiguration;

public class HibernateUtil {

private static SessionFactory factory;

public static synchronized Session getSession() {

if (factory == null) {

factory = new Configuration(nfigure()buildSessionFactory();

}

return factoryopenSession();

}

public static void setSessionFactory(SessionFactory factory) {

HibernateUtilfactory = factory;

}

}

上一篇:tomcat的sql server数据源的配置

下一篇:Hibernate 基于JDBC的事务