【问题标题】:What is the correct way to dynamically set the DataSource for a particular DBMS (db engine)?为特定 DBMS(数据库引擎)动态设置 DataSource 的正确方法是什么?
【发布时间】:2020-04-03 01:13:28
【问题描述】:

我有一个项目需要连接到数据库。我正在从 config.xml 文件中读取数据库连接信息,但是,我被困在为特定 db 引擎定义 DataSource 的部分(从技术上讲,它是 dbms,但这些术语似乎可以互换使用)。下面是相关代码sn-p:

String engine = get(xmldoc, "engine");
if (engine == "postgres")
{
    PGSimpleDataSource ds = new PGSimpleDataSource();
}
else if (engine == "mssql")
{
    SQLServerDataSource ds = new SQLServerDataSource();
}
else if (engine == "sqlite")
{
    SQLiteDataSource ds = new SQLiteDataSource();
}
else
{
    throw new Exception(String.format("Unknown DBMS type %s", engine));
}

ds.setServerName(get(xmldoc, "hostname"));
ds.setDatabaseName(get(xmldoc, "databasename"));
ds.setUser(get(xmldoc, "username"));

当我尝试编译它时,每次对 ds 的引用都会得到一堆 error: cannot find symbol。经过一番挖掘,我发现这是因为我的 ds 变量是声明它的 if 语句的本地变量(参考:Cannot find symbol if statement error)。不过,与那个问题不同的是,我不能简单地在一开始就声明它,因为我不知道它将是什么特定的 DataSource。

那么,动态设置我的数据源的最佳方法是什么?最好不要将我所有的初始化代码都放在每个 if 语句中,因为那样我就必须把我所有的数据库调用也放在那里。是否有某种方法可以将ds 最初声明为通用数据源,然后将其转换为 if 语句中的特定数据源?

【问题讨论】:

    标签: java database compiler-errors datasource


    【解决方案1】:

    首先,你以错误的方式比较字符串:

    但您真正问题的解决方案是使用多态性。

    1. 您需要定义一个DataSource 接口来声明您的应用程序将要调用的所有方法。

    2. 所有现有的数据库特定数据源类都需要实现DataSource 接口及其方法。 (也许您可以使用抽象类来实现一些常用功能。)

    3. ds 声明为DataSource;例如

      String engine = get(xmldoc, "engine");
      DataSource ds = null;
      if (engine.equals("postgres")) {
          ds = new PGSimpleDataSource();
      }
      else if (engine.equals("mssql")) {
          ds = new SQLServerDataSource();
      }
      else if (engine.equals("sqlite")) {
          ds = new SQLiteDataSource();
      }
      else {
          throw new Exception(String.format("Unknown DBMS type %s", engine));
      }
      
      ds.setServerName(get(xmldoc, "hostname"));
      ds.setDatabaseName(get(xmldoc, "databasename"));
      ds.setUser(get(xmldoc, "username"));
      

    上面的问题是标准的DataSource 接口和类没有实现你想要使用的方法。因此,您将不得不为PGSimpleDataSourceSQLServerDataSource 等创建自己的接口和包装类。

    (你确定要自己写这段代码吗?找一个已有的库使用不是更好吗?或者如果只是设置服务器名、数据库和用户,在里面做“连接”配置if / else 分支使用源特定的 API 方法。)

    【讨论】:

      猜你喜欢
      • 2011-12-17
      • 1970-01-01
      • 2018-01-24
      • 1970-01-01
      • 2015-09-30
      • 1970-01-01
      • 2019-10-28
      • 2019-04-14
      • 1970-01-01
      相关资源
      最近更新 更多