【问题标题】:How to select JDBC / JPA implementations at run time?如何在运行时选择 JDBC / JPA 实现?
【发布时间】:2017-09-03 14:58:28
【问题描述】:

我正在编写一个应用程序来管理一个数据库,使用 JDBC 和 JPA 进行考试。我希望用户在开始时选择一次要使用的 API,以便所有应用程序都将使用所选 API(无论是 JPA 还是 JDBC)。

目前我决定使用这种方法:

  1. 我为每个 DAO 类创建了一个接口(例如interface UserDAO),其中包含所有需要的方法声明。
  2. 我为每个 DAO 创建了两个类通过使用的 API 区分(例如 UserDAOImplJDBCUserDAOImplJPA)。它们都实现了接口(在我们的例子中,UserDAO)。
  3. 我创建了第三个类(例如UserDAOImpl),它扩展了 JDBC 实现类。 在我的所有代码中,我一直在使用这个类。当我想切换到 JPA 时,我只需将所有 DAO 类中的 extends ***ImplDAOJDBC 更改为 extends ***ImplDAOJPA

现在,由于我开始拥有许多 DAO 类,因此每次修改代码都开始变得复杂。

有没有办法更快地更改所有extends? 我正在考虑在第一个屏幕中添加一个选项(例如 radioGroup)来选择 JDBC 或 JPA。但是我不知道如何在不重构所有代码的情况下使其工作。有什么想法吗?

【问题讨论】:

  • 我建议改变你的方法。 (1) 保留UserDAOUserDAOImplJDBCUserDAOImplJPA。 (2) 创建一个类和方法DaoProvider.getUserDao(Type t)(或工厂,如果您正在创建新实例而不是重用它们),它将根据所需类型(JPA 或 JDBC)返回正确的UserDAO
  • 问你的老师,因为这真的没有意义,即使目标是比较两种方法。它们太不同了,当您开始使用 JDBC 时,您将无法有意义地使用大部分 JPA。如果您从 JPA 开始,则必须使用 JDBC 对其进行模拟。无论如何,这不会是一个有意义的比较。在生产环境中有两个实现是很浪费的。

标签: java jpa optimization jdbc


【解决方案1】:

每次需要时使用工厂获取适当的 DAO:

public class UserDaoFactory {
    public UserDao create() {
        if (SomeSharedSingleton.getInstance().getPersistenceOption() == JDBC) {
            return new UserDAOImplJDBC();
        }
        else {
            return new UserDAOImplJPA();
        }
    }
}

这是一个经典的 OO 模式。

也就是说,我希望你意识到你在那里所做的事情真的不应该在真正的应用程序中完成:

  • 没有理由以两种不同的方式做完全相同的事情
  • JPA 和 JDBC 的持久化模型非常不同:JPA 实体由 JPA 引擎管理,因此对 JPA 实体的每次更改都透明地持久化。 JDBC 不是这种情况,您从数据库中获取的数据是分离的。因此,JPA 和 JDBC 实现业务逻辑的方式非常不同:使用 JPA 时通常不需要保存任何更改。

【讨论】:

  • 谢谢,这对我帮助很大。我必须这样做的真正原因是因为我的教授要求我这样做。我承认我还没有生成 JPA 代码,而且我没有意识到它会使用不同的方法。你会建议我做什么?从 JDBC 开始创建一个新项目?
  • 我不知道你的老师想让你做什么。我只是说,在一个真实的项目中,你不会以两种不同的方式做同样的事情。您可以在任何地方使用 JPA,除非在某些使用 JDBC 可以更好地实现的用例中,或者您可以在任何地方使用 JDBC,但您不会以两种不同的方式实现所有用例。这只会带来更多的复杂性、更多的错误、更多的开发时间,而附加值为零。
【解决方案2】:

1 和 2 正确,但 3 完全错误。
例如,不要让Impl 扩展其他实现之一,而是选择使用实用程序方法初始化哪个实现。这是假设您不使用 Spring 等依赖注入框架。

UserDAO dao = DBUtils.getUserDAO();

public class DBUtils {

   public static boolean shouldUseJdbc() {
      // Decide on some configuration what should you use
   }

   public static UserDAO getUserDAO() {
      if (shouldUseJdbc()) {
          return new UserDAOImplJDBC();
      }
      else {
          return new UserDAOImplJPA();
      }
   }
}

这仍然只是一个示例,因为您的 DAO 不需要每次都实例化,但实际上应该是单例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-14
    • 2021-06-24
    相关资源
    最近更新 更多