为了在我们的应用程序中实现数据访问代码,我们需要一些框架来包装 jdbc(由于可扩展性,ORM 不是我们的选择)。

我曾经使用过的最酷的框架是 Spring-Jdbc. 。然而,我公司的政策是避免外部依赖,尤其是spring、J2EE等。所以我们正在考虑编写自己的手工jdbc框架,其功能类似于Spring-jdbc:行映射、错误处理、支持java5的特性,但不支持事务。

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

提前致谢。

有帮助吗?

解决方案

我们编写了自己的包装器。这个话题值得写一篇论文,但我怀疑我是否有时间来写它,所以这里有一些要点:

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

  • 对于连接管理,我们使用 Apache DBCP。这在当时很方便,但尚不清楚现代 JDBC 实现需要多少(缺乏关于这方面的文档)。DBCP 还池化PreparedStatements。

  • 我们没有考虑行映射。相反(对于查询)我们使用了类似于 Apache dbutil 的 ResultSetHandler 的东西,它允许您将结果集“馈送到”一个方法中,然后该方法可以将信息转储到您想要的任何地方。这样更加灵活,实际上实现一个用于行映射的 ResultSetHandler 并不难。对于插入/更新,我们创建了一个通用记录类(基本上是一个带有一些额外功能的哈希图)。行映射的最大问题(对我们来说)是,一旦执行“有趣的”查询,您就会陷入困境,因为您可能有映射到不同类的字段;因为你可能有一个分层的类结构,但有一个扁平的结果集;或者因为映射很复杂并且依赖于数据。

  • 我们内置了错误日志记录。对于异常处理:对于查询,我们捕获并记录,但对于更新,我们捕获、记录并重新抛出未经检查的异常。

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

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

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

其他提示

Spring-JDBC太棒了。考虑到对于像Spring这样的开源项目,外部依赖的缺点是最小化的。您可以采用最稳定的Spring版本来满足您的JDBC抽象要求,并且您知道如果遇到问题,您将始终能够自己修改源代码 - 而不依赖于外部方。您还可以使用外部方编写的代码检查组织可能遇到的任何安全问题的实现。

我更喜欢的那个: Dalesbred 。这是麻省理工学院的许可。

获取自定义类(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;
    }
}

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

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

话虽如此,你真正需要复制的是JdbcTemplate及其回调(PreparedStatementCreator,PreparedStatementCallback)以及RowMapper / RowCallbackHandler的概念。写这样的东西不应该过于复杂(特别是考虑到你不必进行事务管理)。

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

尝试 JdbcSession a href =“http://jdbc.jcabi.com/”rel =“nofollow”> jcabi-jdbc 。它就像JDBC一样简单,例如:

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

就是这样。

mJDBC: https://mjdbc.github.io/

我使用它多年,发现它非常有用。

它受到JDBI库的启发,但没有依赖关系,添加了事务支持,提供了性能计数器,并且允许在Java(旧的简单JDBC API)中轻松切换到尽可能低的SQL级别,以防您真正需要它。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top