【问题标题】:Java/JDBC MySQL Database - Design QueryJava/JDBC MySQL 数据库 - 设计查询
【发布时间】:2016-10-31 02:04:30
【问题描述】:

我只需要澄清以下设计是否违反了面向对象设计的最佳实践(与实现 MySQL 数据库有关)。这不是Java EE 规模,而是本科二年级的工作,我在 Oracle 的教程中能找到的只是使用 Java 的大型数据库的设计指南,例如 Data Access Object

我有一个类处理加载JDBC driverMySQL Database。它具有定义为staticConnectionStatement 对象

/** Enables a connection to the chessleaguedb MySQL database 
 * @author Erdi Rowlands
 */
public class DatabaseConnection 
{
    private Console console;    // needed for relevant method to mask console input
    private Scanner keyboard;   // reads user input
    private String user;        // MySQL user account 
    private String pass;        // MySQL account password
    private String host;        // MySQL host 
    static Connection conn;     // application needs to communicate with JDBC driver
    static Statement st;        // issuing commands against the connection is reqiured

    /* When instantiated the JDBC driver attempts to load */
    public DatabaseConnection()
    {   
        this.loadDriver();
    }

    public void loadDriver()
    {
        try
        {
            Class.forName ("com.mysql.jdbc.Driver");
        }
        catch (ClassNotFoundException e)
        {
            System.out.println("Could not load the driver");
        }
    }

    public void connectToDatabase()
    {
        try 
        {
            this.readLogin();
            // prompts user to enter login info to console
            this.conn = DriverManager.getConnection
                ("jdbc:mysql://"+host+":3306/chessleaguedb", user, pass);
            System.out.println("\nSuccessfully connected to database: "
                    + "'chessleaguedb'");
        } 

        catch (SQLException ex) 
        {
            Logger.getLogger(DatabaseConnection.class.getName()).log(Level.SEVERE, null, ex);
        }
    }            

我有一个用于创建和填充数据库表的类:

/** Enables the creation and population of the MySQL database 'chessleaguedb' tables
 * @author Erdi Rowlands
 */
public class DatabaseTables 
{
    public DatabaseTables()
    {

    }

    public void createPlayerTable()
    {
        try 
        {
            DatabaseConnection.st = DatabaseConnection.conn.createStatement();
            DatabaseConnection.st.executeUpdate("CREATE TABLE IF NOT EXISTS"
                    + "(PlayerName VARCHAR(30)PRIMARY KEY,"
                    + "DateOfBirth DATE,"
                    + "FIDERating tinyint,"
                    + "ClubName FOREIGN KEY fk_club(Clubname) REFERENCES club(ClubName)");                    
                    // Create Actor table
        } 
        catch (SQLException ex) 
        {
            Logger.getLogger(DatabaseConnection.class.getName()).log(Level.SEVERE, null, ex);
        }        
    }
}

我是否通过在第二类中使用那些静态对象来执行数据库命令来破坏 OOD 最佳实践?如果没有,我将继续制作处理存储过程等的类,并且很高兴我没有做错什么。我不想自然地在 main 方法中包含所有内容,并且除了在需要它们的每个类中加载 JDBC driverConnection 之外,看不到任何其他方法(似乎是多余的)。

【问题讨论】:

  • 请为您的问题提供一个更具描述性的标题;标题应该引起人们的兴趣,而目前它几乎只有标签。

标签: java mysql database jdbc


【解决方案1】:

我是否通过在第二类中使用那些静态对象来执行数据库命令来破坏 OOD 最佳实践?

是的。在 JDBC Connection 对象中,应用程序是高度一次性的(由驱动程序或中间件池化),并且绝对不会在多个线程之间共享。

将 JDBC 连接声明为静态会导致违反这两个原则。

应该存储在类级别的唯一内容是您的 user/pass/host 变量。

您的 connectionstatement 对象应存储在使用它们的方法范围内——永远不要在类级别缓存。

consolekeyboard 变量与DatabaseConnection 无关,应该完全属于不同的类。

此外,我强烈反对只在 JDBC 连接失败的情况下记录 SQLException。除非您设置了某种故障转移/重试逻辑,否则您可能只想在 JDBC 连接失败时让您的应用程序崩溃并停止。

如果没有,我将继续制作处理存储过程等的类,并且很高兴我没有做错什么。我不想自然地在 main 方法中拥有所有内容,并且除了在需要它们的每个类中加载 JDBC 驱动程序和 Connection 之外,看不到任何其他方法(似乎是多余的)。

调用Class.forName(JDBC_DRIVER_CLASS); 是一个遗留要求,仍然遍布整个互联网。从 JDBC 4.0 开始,如果 JDBC 驱动程序位于您的类路径中,则无需在 JDBC 驱动程序类名称上调用 Class.forName()

JDBC 4.0 和更新的驱动程序有一个静态代码块,它自己向DriverManager 注册,因此应用程序不必这样做。

【讨论】:

  • 技术见解很有趣,值得赞赏。我已删除驱动程序调用。最后一个问题,我希望我能正确理解你的回答是在暗示我可以在每个需要它的类中加载一个新的连接? (正如你所说的一次性等)。
  • 我阅读了答案中的详细说明。谢谢你。此外,“控制台和键盘变量与 DatabaseConnection 无关,应该完全属于不同的类。”这迫使我提高自己的设计水平。
猜你喜欢
  • 1970-01-01
  • 2011-12-21
  • 1970-01-01
  • 2017-03-12
  • 2011-01-02
  • 1970-01-01
  • 1970-01-01
  • 2019-09-27
相关资源
最近更新 更多