2008-11-18 48 views
13

要在我们的应用程序中实现数据访问代码,我们需要一些框架来包装jdbc(因为可伸缩性,ORM不是我们的选择)。简单的jdbc包装器

我曾经使用过的最酷的框架是Spring-Jdbc。然而,我公司的政策是避免外部依赖,尤其是Spring,J2EE等。因此我们正在考虑编写自己的手工制作的jdbc框架,其功能与Spring-jdbc类似:行映射,错误处理,支持功能java5,但没有事务支持。

有没有人有编写这样的jdbc包装框架的经验? 如果任何人有使用其他jdbc包装框架的经验,请分享您的经验。

在此先感谢。

+10

“我公司的政策是避免外部依赖,尤其是Spring,J2EE等。”哇,这听起来像一场噩梦。听起来像是重复发明轮子的无限循环。 – 2009-05-14 17:38:40

回答

13

我们写了我们自己的包装。这个主题是值得纸,但我怀疑我会永远有时间写出来,所以这里有一些关键点:

  • 我们拥抱SQL和没有试图隐瞒。唯一的调整是增加对命名参数的支持。参数很重要,因为我们不鼓励使用即时sql(出于安全原因),我们总是使用PreparedStatements。

  • 对于连接管理,我们使用了Apache DBCP。这在当时很方便,但目前还不清楚现代JDBC实现需要多少这方面的知识(缺少这方面的文档)。 DBCP还会集合PreparedStatements。

  • 我们没有打扰行映射。相反,对于查询,我们使用了类似于Apache dbutil的ResultSetHandler,它可以将结果集“提供给”一个方法,然后可以将信息转储到任何你喜欢的地方。这更加灵活,事实上,为行映射实现ResultSetHandler并不困难。对于插入/更新,我们创建了一个通用记录类(基本上是带有一些额外的铃声和口哨的散列表)。行映射(对我们来说)最大的问题是,只要您执行“有趣”的查询,就会卡住,因为您可能有映射到不同类的字段;因为你可能有一个分层的类结构,但是有一个平坦的结果集;或者因为映射很复杂并且与数据有关。

  • 我们建立了错误日志记录。对于异常处理:在我们进行陷阱和日志记录的查询中,但是对于更新,我们会捕获,记录并重新引发未检查的异常。

  • 我们使用包装方法提供了事务支持。调用者提供执行事务的代码,并确保事务得到妥善管理,不会忘记完成事务,并且内置回滚和错误处理。

  • 稍后,我们添加了一个非常简单的关系方案,它允许单个更新/插入应用于记录及其所有依赖关系。为了简单起见,我们没有在查询中使用它,并且我们特别决定不使用删除来支持此操作,因为使用级联删除更加可靠。

该包装已成功用于两个项目迄今。当然,它是轻量级的,但是现在每个人都说他们的代码是轻量级的。更重要的是,它增加了程序员的生产力,减少了错误的数量(并且使问题更容易追踪),并且如果需要的话追踪相对容易,因为我们不相信为了提供美丽的架构而添加许多层。

5

Spring-JDBC非常棒。考虑到像Spring这样的开源项目,外部依赖关系的负面影响最小化。您可以采用满足JDBC抽象要求的Spring最稳定版本,并且您知道如果遇到问题,您将始终能够修改源代码 - 而不依赖于外部参与方。您还可以检查实施情况,了解您的组织使用外部用户编写的代码时可能遇到的任何安全问题。

1

尝试JdbcSessionjcabi-jdbc。它就像JDBC一样简单,例如:

String name = new JdbcSession(source) 
    .sql("SELECT name FROM foo WHERE id = ?") 
    .set(123) 
    .select(new SingleOutcome<String>(String.class)); 

就是这样。

1

这听起来像是一个非常短视的决定。考虑开发/维护这种框架的成本,特别是当你可以得到它时,它是免费的源代码。你不但不需要自己进行开发,如果需要的话,你可以随意修改它。

这就是说,你真正需要复制的是JdbcTemplate的概念,它的回调函数(PreparedStatementCreator,PreparedStatementCallback)以及RowMapper/RowCallbackHandler。写这样的东西不应该过于复杂(特别是考虑到你不必做事务管理)。

正如我所说的那样,为什么在您可以免费获得它时编写它,并根据需要修改源代码?

2

我更喜欢的那个:Dalesbred。这是MIT许可的。

获取自定义类(Department)的所有行的简单示例。

List<Department> departments = db.findAll(Department.class, 
    "select id, name from department"); 

当自定义类的定义为:

public final class Department { 
    private final int id; 
    private final String name; 

    public Department(int id, String name) { 
     this.id = id; 
     this.name = name; 
    } 
} 

免责声明:这是由我工作的公司。