简单的jdbc包装器

问题描述 投票:14回答:6

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

我曾经使用过的最酷的框架是Spring-Jdbc。但是,我公司的政策是避免外部依赖,尤其是Spring,J2EE等。所以我们正在考虑编写自己的方便的jdbc框架,功能类似于Spring-jdbc:行映射,错误处理,java5的支持功能,但没有交易支持。

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

提前致谢。

java jdbc data-access spring-jdbc
6个回答
14
投票

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

  • 我们接受了sql而没有试图隐藏它。唯一的调整是添加对命名参数的支持。参数很重要,因为我们不鼓励使用动态sql(出于安全考虑),我们总是使用PreparedStatements。
  • 对于连接管理,我们使用Apache DBCP。这在当时很方便,但目前还不清楚现代JDBC实现需要多少(这方面的文档缺乏)。 DBCP还汇集了PreparedStatements。
  • 我们没有打扰行映射。相反(对于查询)我们使用类似于Apache dbutil的ResultSetHandler,它允许您将结果集“提供”到一个方法中,然后可以将信息转储到您喜欢的任何地方。这更灵活,实际上为行映射实现ResultSetHandler并不困难。对于插入/更新,我们创建了一个通用记录类(基本上是一个带有一些额外铃声和口哨声的散列映射)。行映射(对我们来说)最大的问题是,当你执行“有趣”的查询时,你就会被卡住,因为你可能有字段映射到不同的类;因为你可能有一个分层的类结构,但结果集很平;或者因为映射很复杂并且依赖于数据。
  • 我们建立了错误记录。用于异常处理:在查询中我们捕获并记录,但是对于更新,我们捕获,记录和重新抛出未经检查的异常。
  • 我们使用包装器方法提供了事务支持。调用者提供执行事务的代码,我们确保事务得到妥善管理,不会忘记完成事务并且内置回滚和错误处理。
  • 稍后,我们添加了一个非常简单的关系方案,允许单个更新/插入应用于记录及其所有依赖项。为了简单起见,我们没有在查询中使用它,我们特别决定不支持删除,因为使用级联删除更可靠。

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


5
投票

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


3
投票

我更喜欢的那个: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;
    }
}

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


1
投票

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

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

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


1
投票

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

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

而已。


0
投票

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.