【问题标题】:Connect Java to a MySQL database将 Java 连接到 MySQL 数据库
【发布时间】:2022-01-01 23:53:20
【问题描述】:

如何用 Java 连接到 MySQL 数据库?

当我尝试时,我得到了

java.sql.SQLException: No suitable driver found for jdbc:mysql://database/table
    at java.sql.DriverManager.getConnection(DriverManager.java:689)
    at java.sql.DriverManager.getConnection(DriverManager.java:247)

或者

java.lang.ClassNotFoundException: com.mysql.jdbc.Driver

或者

java.lang.ClassNotFoundException: com.mysql.cj.jdbc.Driver

【问题讨论】:

标签: java mysql jdbc


【解决方案1】:

这里分步说明如何安装 MySQL 和 JDBC 以及如何使用:

  1. Download 并安装 MySQL 服务器。只需按照通常的方式进行即可。更改端口号时请记住它。默认为3306

  2. Download JDBC 驱动并放入类路径,解压 ZIP 文件并将包含的 JAR 文件放入类路径中。特定于供应商的 JDBC 驱动程序是 JDBC API (tutorial here) 的具体实现。

    如果您使用 Eclipse 或 Netbeans 之类的 IDE,则可以通过将 JAR 文件作为 Library 添加到项目的 Build Path 中来将其添加到类路径中特性。

    如果您在命令控制台中“普通”地执行此操作,那么您需要在执行 Java 应用程序时在 -cp-classpath 参数中指定 JAR 文件的路径。

    java -cp .;/path/to/mysql-connector.jar com.example.YourClass

    . 只是为了将 current 目录也添加到类路径中,以便它可以找到com.example.YourClass; 是类路径分隔符,就像在 Windows 中一样。在 Unix 和克隆中应该使用 :

  3. 在 MySQL 中创建 database。让我们创建一个数据库javabase。你当然想要 World Domination,所以我们也使用 UTF-8。

    CREATE DATABASE javabase DEFAULT CHARACTER SET utf8 COLLATE utf8_unicode_ci;
    
  4. Create an user 用于 Java,grant 用于访问。仅仅因为使用root 是一种不好的做法。

    CREATE USER 'java'@'localhost' IDENTIFIED BY 'password';
    GRANT ALL ON javabase.* TO 'java'@'localhost' IDENTIFIED BY 'password';
    

    是的,java 是用户名,password 是这里的密码。

  5. Determine JDBC URL。要使用 Java 连接 MySQL 数据库,您需要使用以下语法的 JDBC URL:

    jdbc:mysql://hostname:port/databasename
    • hostname:安装 MySQL 服务器的主机名。如果它安装在您运行 Java 代码的同一台机器上,那么您可以使用localhost。它也可以是像127.0.0.1 这样的IP 地址。如果您遇到连接问题并且使用127.0.0.1 而不是localhost 解决了它,那么您的网络/DNS/主机配置有问题。

    • port:MySQL 服务器监听的 TCP/IP 端口。默认为3306

    • databasename:您要连接的数据库的名称。那是javabase

    所以最终的 URL 应该是这样的:

    jdbc:mysql://localhost:3306/javabase
  6. Test the connection 使用 Java 到 MySQL。使用main() 方法创建一个简单的Java 类来测试连接。

    String url = "jdbc:mysql://localhost:3306/javabase";
    String username = "java";
    String password = "password";
    
    System.out.println("Connecting database...");
    
    try (Connection connection = DriverManager.getConnection(url, username, password)) {
        System.out.println("Database connected!");
    } catch (SQLException e) {
        throw new IllegalStateException("Cannot connect the database!", e);
    }
    

    如果您收到SQLException: No suitable driver,则表示根本没有自动加载 JDBC 驱动程序或 JDBC URL 错误(即,任何加载的驱动程序都无法识别它)。通常,只要将 JDBC 4.0 驱动程序放到运行时类路径中,就应该自动加载它。要排除一个和另一个,您可以随时手动加载它,如下所示:

    System.out.println("Loading driver...");
    
    try {
        Class.forName("com.mysql.jdbc.Driver");
        System.out.println("Driver loaded!");
    } catch (ClassNotFoundException e) {
        throw new IllegalStateException("Cannot find the driver in the classpath!", e);
    }
    

    请注意,此处不需要调用newInstance()。这只是为了修复旧的和错误的org.gjt.mm.mysql.DriverExplanation here。如果此行抛出ClassNotFoundException,则包含 JDBC 驱动程序类的 JAR 文件根本没有放在类路径中。

    请注意,您不需要每次 连接之前加载驱动程序。在应用程序启动期间只需一次就足够了。

    如果您收到SQLException: Connection refusedConnection timed out 或特定于MySQL 的CommunicationsException: Communications link failure,则意味着根本无法访问数据库。这可能有以下一种或多种原因:

    1. JDBC URL 中的 IP 地址或主机名错误。
    2. 本地 DNS 服务器无法识别 JDBC URL 中的主机名。
    3. JDBC URL 中的端口号缺失或错误。
    4. 数据库服务器已关闭。
    5. 数据库服务器不接受 TCP/IP 连接。
    6. 数据库服务器已用完连接。
    7. Java 和 DB 之间的某些东西阻塞了连接,例如防火墙或代理。

    要解决其中一个问题,请遵循以下建议:

    1. 使用ping 验证和测试它们。
    2. 刷新 DNS 或改用 JDBC URL 中的 IP 地址。
    3. 根据 MySQL DB 的my.cnf 进行验证。
    4. 启动数据库。
    5. 验证mysqld是否在没有--skip-networking option的情况下启动。
    6. 重新启动数据库并相应地修复您的代码以关闭finally 中的连接。
    7. 禁用防火墙和/或配置防火墙/代理以允许/转发端口。

    请注意,关闭Connection 非常很重要。如果您不关闭连接并在短时间内不断获得大量连接,那么数据库可能会耗尽连接并且您的应用程序可能会中断。始终在try-with-resources statement 中获取Connection。或者,如果您还没有使用 Java 7,请在 finallytry-finally 块中明确关闭它。在finally 中关闭只是为了确保它在出现异常时也被关闭。这也适用于StatementPreparedStatementResultSet

这就是连接问题。您可以找到here 一个更高级的教程,如何借助基本的 DAO 类在数据库中加载和存储完全有价值的 Java 模型对象。


对数据库连接使用单例模式是一种不好的方法。除其他问题外,请参阅:http://stackoverflow.com/q/9428573/。这是 #1 的初学者错误。

【讨论】:

    【解决方案2】:

    DriverManager 是一种相当古老的做事方式。更好的方法是获取DataSource,或者通过查找您的应用服务器容器已经为您配置的一个:

    Context context = new InitialContext();
    DataSource dataSource = (DataSource) context.lookup("java:comp/env/jdbc/myDB");
    

    或直接从您的数据库驱动程序实例化和配置一个:

    MysqlDataSource dataSource = new MysqlDataSource();
    dataSource.setUser("scott");
    dataSource.setPassword("tiger");
    dataSource.setServerName("myDBHost.example.org");
    

    然后从中获取连接,同上:

    Connection conn = dataSource.getConnection();
    Statement stmt = conn.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT ID FROM USERS");
    ...
    rs.close();
    stmt.close();
    conn.close();
    

    【讨论】:

    • 其他例子怎么用com.mysql.jdbc.Driver?这种方法更好吗?
    • 我认为这是与旧式驱动机制一起工作的旧式驱动程序类。 MysqlDataSource 实现了 javax.sql.DataSource,这是较新的机制。
    • 嗨@SeanOwen 我想知道,我们为什么要关闭rsstmt?为什么不只是conn
    • 也许你应该添加 dataSource.setDatabaseName("database")。
    • 明确地 close() 是一种很好的做法,尽管它需要更多的代码。任何好的实现都必须在连接关闭时关闭资源,是的。考虑一下您想要重用语句或连接的其他上下文。在 Java 7 的 try-with-resources 中,无论如何你都可以免费获得这种行为:
    【解决方案3】:

    初始化数据库常量

    创建常量属性数据库用户名、密码、URL 和驱动程序、轮询限制等

    // init database constants
    // com.mysql.jdbc.Driver
    private static final String DATABASE_DRIVER = "com.mysql.cj.jdbc.Driver";
    private static final String DATABASE_URL = "jdbc:mysql://localhost:3306/database_name";
    private static final String USERNAME = "root";
    private static final String PASSWORD = "";
    private static final String MAX_POOL = "250"; // set your own limit
    

    初始化连接和属性

    一旦建立连接,最好保存起来以备重用。

    // init connection object
    private Connection connection;
    // init properties object
    private Properties properties;
    

    创建属性

    属性对象保存连接信息,检查是否已经设置。

    // create properties
    private Properties getProperties() {
        if (properties == null) {
            properties = new Properties();
            properties.setProperty("user", USERNAME);
            properties.setProperty("password", PASSWORD);
            properties.setProperty("MaxPooledStatements", MAX_POOL);
        }
        return properties;
    }
    

    连接数据库

    现在使用初始化的常量和属性连接到数据库。

    // connect database
    public Connection connect() {
        if (connection == null) {
            try {
                Class.forName(DATABASE_DRIVER);
                connection = DriverManager.getConnection(DATABASE_URL, getProperties());
            } catch (ClassNotFoundException | SQLException e) {
                // Java 7+
                e.printStackTrace();
            }
        }
        return connection;
    }
    

    断开数据库

    完成数据库操作后,只需关闭连接即可。

    // disconnect database
    public void disconnect() {
        if (connection != null) {
            try {
                connection.close();
                connection = null;
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
    

    一切都在一起

    修改database_name、用户名和密码等后直接使用这个类MysqlConnect

    import java.sql.Connection;
    import java.sql.DriverManager;
    import java.sql.SQLException;
    import java.util.Properties;
    
    public class MysqlConnect {
        // init database constants
        private static final String DATABASE_DRIVER = "com.mysql.cj.jdbc.Driver";
        private static final String DATABASE_URL = "jdbc:mysql://localhost:3306/database_name";
        private static final String USERNAME = "root";
        private static final String PASSWORD = "";
        private static final String MAX_POOL = "250";
    
        // init connection object
        private Connection connection;
        // init properties object
        private Properties properties;
    
        // create properties
        private Properties getProperties() {
            if (properties == null) {
                properties = new Properties();
                properties.setProperty("user", USERNAME);
                properties.setProperty("password", PASSWORD);
                properties.setProperty("MaxPooledStatements", MAX_POOL);
            }
            return properties;
        }
    
        // connect database
        public Connection connect() {
            if (connection == null) {
                try {
                    Class.forName(DATABASE_DRIVER);
                    connection = DriverManager.getConnection(DATABASE_URL, getProperties());
                } catch (ClassNotFoundException | SQLException e) {
                    e.printStackTrace();
                }
            }
            return connection;
        }
    
        // disconnect database
        public void disconnect() {
            if (connection != null) {
                try {
                    connection.close();
                    connection = null;
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    

    如何使用?

    初始化数据库类。

    // !_ note _! this is just init
    // it will not create a connection
    MysqlConnect mysqlConnect = new MysqlConnect();
    

    代码中的其他地方 ...

    String sql = "SELECT * FROM `stackoverflow`";
    try {
        PreparedStatement statement = mysqlConnect.connect().prepareStatement(sql);
        ... go on ...
        ... go on ...
        ... DONE ....
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        mysqlConnect.disconnect();
    }
    

    这就是全部:)如果有什么要改进的编辑它!希望这会有所帮助。

    【讨论】:

    • 马克,是否每个类都需要维护它自己的独立 MysqlConnect 实例始终打开 - 假设它们需要与数据交互?我只是想知道这个设置在类之间是如何工作的。
    • 应该使用 com.mysql.jdbc.Driver 代替 jdbc:mysql://localhost:3306/stocks,因为前者已被弃用。
    • 如果您要硬连线帐户名、密码、数据库名等,这种方式非常笨拙。只需将所有这些详细信息放入 JDBC URL 字符串即可。 (包括池大小...)
    【解决方案4】:
    String url = "jdbc:mysql://127.0.0.1:3306/yourdatabase";
    String user = "username";
    String password = "password";
    
    // Load the Connector/J driver
    Class.forName("com.mysql.jdbc.Driver").newInstance();
    // Establish connection to MySQL
    Connection conn = DriverManager.getConnection(url, user, password);
    

    【讨论】:

    • 这里的数据库是什么?数据库名称?
    • newInstance() 不是必需的。是吗?
    • 不。它不是。从 Java 6 开始,这整个方法已经过时了。并且驱动程序类名称已更改......
    • 有趣的是,在 DriverManager docs.oracle.com/javase/6/docs/api/java/sql/DriverManager.html 的文档中声明不再需要 Class.forName() 而是可以使用一些属性文件 java.sql.Driver
    • 这里的数据库名称似乎是“您的数据库”,您可以在 url 中看到
    【解决方案5】:

    这是从 MySQL 数据库中获取数据所需的最低要求:

    Class.forName("com.mysql.jdbc.Driver").newInstance();
    Connection conn = DriverManager.getConnection
       ("jdbc:mysql://localhost:3306/foo", "root", "password");
    
    Statement stmt = conn.createStatement();
    stmt.execute("SELECT * FROM `FOO.BAR`");
    stmt.close();
    conn.close();
    

    添加异常处理、配置等。

    【讨论】:

    • 为什么需要Class.forName(...).newInstance()
    • @mmcrae 你没有,从 2007 年开始。
    【解决方案6】:

    您的类路径中需要有 mysql 连接器 jar。

    在 Java JDBC API 中,一切都使用数据库。使用 JDBC 我们可以编写 Java 应用程序到
    1. 发送查询或更新 SQL 到 DB(任何关系数据库) 2. 从数据库中检索和处理结果

    通过以下三个步骤,我们可以从任何数据库中检索数据

    Connection con = DriverManager.getConnection(
                         "jdbc:myDriver:DatabaseName",
                         dBuserName,
                         dBuserPassword);
    
    Statement stmt = con.createStatement();
    ResultSet rs = stmt.executeQuery("SELECT a, b, c FROM Table");
    
    while (rs.next()) {
        int x = rs.getInt("a");
        String s = rs.getString("b");
        float f = rs.getFloat("c");
    }
    

    【讨论】:

      【解决方案7】:

      您可以查看从 Java 应用程序here 连接 MySQL 数据库的所有步骤。对于其他数据库,您只需在第一步中更改驱动程序。请确保您提供正确的数据库路径以及正确的用户名和密码。

      访问http://apekshit.com/t/51/Steps-to-connect-Database-using-JAVA

      【讨论】:

        【解决方案8】:

        MySQL JDBC 连接与 useSSL。

        private String db_server = BaseMethods.getSystemData("db_server");
        private String db_user = BaseMethods.getSystemData("db_user");
        private String db_password = BaseMethods.getSystemData("db_password");
        
        private String connectToDb() throws Exception {
           String jdbcDriver = "com.mysql.jdbc.Driver";
           String dbUrl = "jdbc:mysql://" + db_server  +
                "?verifyServerCertificate=false" +
                "&useSSL=true" +
                "&requireSSL=true";
            System.setProperty(jdbcDriver, "");
            Class.forName(jdbcDriver).newInstance();
        
            Connection conn = DriverManager.getConnection(dbUrl, db_user, db_password);
            Statement statement = conn.createStatement();
            String query = "SELECT EXTERNAL_ID FROM offer_letter where ID =" + "\"" + letterID + "\"";
            ResultSet resultSet = statement.executeQuery(query);
            resultSet.next();
            return resultSet.getString(1);
        }
        

        【讨论】:

        • 查询字符串的创建方式是一种非常糟糕的做法,容易受到 SQL 注入攻击。
        【解决方案9】:

        又短又甜的代码。

        try {       
            Class.forName("com.mysql.jdbc.Driver");
            System.out.println("Driver Loaded");
            conn = DriverManager.getConnection("jdbc:mysql://localhost:3306/testDB","root","");
            //Database Name - testDB, Username - "root", Password - ""
            System.out.println("Connected...");         
        } catch(Exception e) {
            e.printStackTrace();
        }
        

        对于 SQL Server 2012

        try {
            String url = "jdbc:sqlserver://KHILAN:1433;databaseName=testDB;user=Khilan;password=Tuxedo123"; 
            //KHILAN is Host    and 1433 is port number     
            Class.forName("com.microsoft.sqlserver.jdbc.SQLServerDriver");
            System.out.println("Driver Loaded");
            conn = DriverManager.getConnection(url);
            System.out.println("Connected...");
        } catch(Exception e) {
            e.printStackTrace();
        }
        

        【讨论】:

          【解决方案10】:

          Connection我前段时间用过,它看起来是最简单的方法,但也有人建议在那里做if声明-正是

          Connection con = DriverManager.getConnection(
                               "jdbc:myDriver:DatabaseName",
                               dBuserName,
                               dBuserPassword);
          if (con != null){
           //..handle your code there 
          }
          

          或者类似的方式:)

          可能有一些情况,而getConnection 可以返回null :)

          【讨论】:

            【解决方案11】:
            如何
            • 设置驱动程序以运行快速示例
            1. Go to https://dev.mysql.com/downloads/connector/j/, get the latest version of Connector/J
            
            2. Remember to set the classpath to include the path of the connector jar file.
            If we don't set it correctly, below errors can occur:
            
            No suitable driver found for jdbc:mysql://127.0.0.1:3306/msystem_development
            
            java.lang.ClassNotFoundException: com.mysql.jdbc:Driver
            
            • 设置类路径

            方法一:设置CLASSPATH变量。

            export CLASSPATH=".:mysql-connector-java-VERSION.jar"
            java MyClassFile
            

            在上述命令中,我已将 CLASSPATH 设置为当前文件夹和 mysql-connector-java-VERSION.jar 文件。所以当java MyClassFile 命令执行时,java 应用程序启动器会尝试加载CLASSPATH 中的所有Java 类。 它发现Drive class=> BOOM 错误消失了。

            方法二:

            java -cp .:mysql-connector-java-VERSION.jar MyClassFile
            

            注意:Class.forName("com.mysql.jdbc.Driver");这在 2019 年 4 月的这一刻已被弃用。

            希望这可以帮助别人!

            【讨论】:

              【解决方案12】:

              MySql JDBC 连接:

              Class.forName("com.mysql.jdbc.Driver");     
              
              Connection con=DriverManager.getConnection("jdbc:mysql://localhost:3306/DatabaseName","Username","Password");         
              Statement stmt=con.createStatement();            
              stmt = con.createStatement();
              ResultSet rs=stmt.executeQuery("Select * from Table");  
              

              【讨论】:

                【解决方案13】:

                短代码

                public class DB {
                
                    public static Connection c;
                
                    public static Connection getConnection() throws Exception {
                        if (c == null) {
                            Class.forName("com.mysql.jdbc.Driver");
                            c =DriverManager.getConnection("jdbc:mysql://localhost:3306/DATABASE", "USERNAME", "Password");
                        }
                        return c;
                    }
                
                    // Send data TO Database
                    public static void setData(String sql) throws Exception {
                        DB.getConnection().createStatement().executeUpdate(sql);
                    }
                
                    // Get Data From Database
                    public static ResultSet getData(String sql) throws Exception {
                        ResultSet rs = DB.getConnection().createStatement().executeQuery(sql);
                        return rs;
                    }
                }
                

                【讨论】:

                  【解决方案14】:

                  下载 JDBC 驱动程序

                  下载链接(选择平台无关):https://dev.mysql.com/downloads/connector/j/

                  将 JDBC 驱动移至 C 盘

                  解压缩文件并移动到 C:\ 驱动器。你的驱动路径应该是C:\mysql-connector-java-8.0.19\mysql-connector-java-8.0.19

                  运行您的 Java

                  java -cp "C:\mysql-connector-java-8.0.19\mysql-connector-java-8.0.19\mysql-connector-java-8.0.19.jar" testMySQL.java
                  

                  testMySQL.java

                  import java.sql.*;
                  import java.io.*;
                  
                  public class testMySQL {
                      public static void main(String[] args) {
                      // TODO Auto-generated method stub
                          try
                          {  
                              Class.forName("com.mysql.cj.jdbc.Driver");  
                              Connection con=DriverManager.getConnection(  
                                  "jdbc:mysql://localhost:3306/db?useSSL=false&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC","root","");  
                              Statement stmt=con.createStatement();  
                              ResultSet rs=stmt.executeQuery("show databases;");  
                              System.out.println("Connected");  
                          }
                          catch(Exception e)
                          {
                              System.out.println(e);
                          }
                  
                      }  
                  
                  }
                  

                  【讨论】:

                    猜你喜欢
                    • 2015-02-06
                    相关资源
                    最近更新 更多