【问题标题】:Java Singleton is not accessable although it is public staticJava Singleton 不可访问,尽管它是公共静态的
【发布时间】:2020-06-02 09:22:17
【问题描述】:

我目前正在编写一个三层架构银行应用程序作为学生项目。 由于我理解了 Dao 模式,我实现了它并想处理与它的数据库交互,但我实际上做不到,因为我的 dao 类无法访问数据库单例 getInstanceDB。 dao 类是一个接口的实现。这些类都在同一个包中。 这似乎是一个可见性问题,因为 Singleton 在除自身之外的任何其他类中都不可调用。 这是代码。

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.sql.Statement;

    public class Database {
        private static Database instance;
        private Connection conn;
        private Statement stmt;

        private Database() {
            try {
                Class.forName("oracle.jdbc.driver.OracleDriver");
                conn = DriverManager.getConnection("jdbc:oracle:thin:@oracle.leuphana.de:1521:oradb1", "...", "...");
                stmt = conn.createStatement();
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }

        // Thread-Safe Singleton
        public static synchronized Database getInstanceDB() {
            if (instance == null) {
                instance = new Database();
            }
            return instance;
        }
    }
// Select Data by CustomerID
    @Override
    public ResultSet select(Kunde kunde) {
        if (kunde == null)
            throw new IllegalArgumentException("given id is null");

        if (kunde.getId() < 0)
            throw new IllegalArgumentException("given id has an invalid value");

        String query = "SELECT * FROM customer WHERE customer_id=" + Integer.toString(kunde.getId());
        ResultSet rs  = null;
        try {
            Connection conn = getInstanceDB().getConnection();
            Statement stmt = conn.createStatement();
            rs =  stmt.executeQuery(query);
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return rs;
    }

我是stackoverflow的新手,希望这个帖子没问题,如果您需要更多信息,请问我^^

编辑: 错误:方法 getInstanceDao() 未定义 KundeDao 类型 getConnection() 看答案,除了catch部分是一样的

感谢您提供快速而有帮助的答案。

【问题讨论】:

  • 你得到什么错误?
  • 没有错误信息,我只能猜测:可能是Database.getInstanceDB().getConnection(); 而不是getInstanceDB().getConnection();
  • 您的数据库连接逻辑有点错误。您正在创建一个私有构造函数来创建一个数据库连接,并且在创建实例之后,您正在尝试访问您从未创建的 getConnection() 以供公共共享。
  • 新海报的教训:请使您的代码完整参见minimal reproducible example。您省略了getConnection 的定义以及调用方法是在同一个类中还是在另一个类中等基本部分。代码需要足够完整,我们才能编译并尝试运行。此外,如果您收到错误消息,请始终将其包含在您的问题中,格式为代码(不是图像)。请使用edit 链接解决这些问题。
  • 错误是:“方法getInstanceDB() 未定义KundeDao 类型”。 @TomStroemer 这就是解决方案,谢谢。好的,我已经怀疑我的数据库逻辑是错误的,我目前正在尝试了解 OJDBC 是如何工作的。在我看来,文档有点勉强。

标签: java singleton dao ojdbc


【解决方案1】:

我认为你的逻辑有点错误。试试这样的。

public Connection getConnection() {
    try {
        Class.forName("oracle.jdbc.driver.OracleDriver");
        conn = DriverManager.getConnection("jdbc:oracle:thin:@oracle.leuphana.de:1521:oradb1", "...", "...");
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    }
    return conn;
}

然后创建您的数据库实例并像这样调用 getConnection() 方法。

Database dbInstance = Database.getInstanceDB();

public void anyMethod(){
    try {
        Connection conn = dbInstance.getConnection();
        Statement stmt = conn.createStatement();
    } catch (SQLException e) {
        e.printStackTrace();
    }
}

注意:要打开关闭连接,您应该使用try-with-resources 以获得更方便的方法。

【讨论】:

  • 这些异常应该被抛出,而不是被捕获。第二个示例应该在过去几年的任何时候使用 try-with-resources。 Connection 和 Statmeent 的实例成员的整个想法是完全不正确的,
  • @user207421 实际上我没有更改 OP 代码。我只是将他提供的内容转移到另一种方法中来指出问题。我也接受你所说的 try-wtih-resources。
  • 好吧,我不知道这个,我们这学期才学了这种操作作为最佳实践。是一个连接池最佳实践,你提到过这个@user207421
  • @1stNox 通常你必须创建一个连接并最终关闭它,或者推荐使用资源尝试的方法。
  • @Natsu 如果我理解正确,我应该放弃 Database 类,只使用打开和关闭连接的函数吗?另一种方法是创建连接池和资源?我刚刚阅读了一些关于资源的内容,这似乎是最佳实践?
猜你喜欢
  • 1970-01-01
  • 2023-03-30
  • 1970-01-01
  • 2010-10-19
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多