JDBC的簡單了解

JDBC

Java DataBase Connectivity java數(shù)據(jù)庫連接

是一種數(shù)據(jù)庫訪問規(guī)則規(guī)范。

簡單使用

基本步驟:

  • 注冊driver
  • 建立連接
  • 創(chuàng)建statement對象進(jìn)行交互
  • 執(zhí)行sql 獲取結(jié)果
  • 釋放資源

代碼舉例:

package com;

import java.sql.*;

public class Main {
    public static void main(String[] args) {
        Driver driver;
        Connection connection;
        Statement statement;
        ResultSet res;
        try {
            driver = new com.mysql.cj.jdbc.Driver();
            DriverManager.registerDriver(driver);
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/base1?serverTimezone=GMT&useSSL=false", "root", "Admin@123");
            statement = connection.createStatement();
            String sql = "select * from product";
            res =  statement.executeQuery(sql);
            while(res.next()) {
                System.out.println("pname: " + res.getString("pname")
                        + "price: " + res.getDouble("price"));
            }
            res.close();
            statement.close();
            connection.close();
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

maven依賴添加地址:

<!-- https://mvnrepository.com/artifact/mysql/mysql-connector-java -->
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
            <version>8.0.15</version>
        </dependency>

釋放資源代碼整理

將釋放資源的邏輯可以提出來,寫出一個(gè)工具類

package com;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class JDBCUtils {

    public static void close(ResultSet res, Statement statement, Connection connection) {
        closeRes(res);
        closeStatement(statement);
        closeConnection(connection);
    }

    public static void closeRes(ResultSet res) {
        try {
            if(res != null) {
                res.close();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            res = null;
        }
    }

    public static void closeStatement(Statement statement) {
        try {
            if(statement != null) {
                statement.close();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            statement = null;
        }
    }

    public static void closeConnection(Connection connection) {
        try {
            if(connection != null) {
                connection.close();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            connection = null;
        }
    }
}

優(yōu)化之后,上面的例子就可以寫成這樣:

package com;

import java.sql.*;

public class Main {
    public static void main(String[] args) {
        Driver driver;
        Connection connection = null;
        Statement statement = null;
        ResultSet res = null;
        try {
            driver = new com.mysql.cj.jdbc.Driver();
            DriverManager.registerDriver(driver);
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/base1?serverTimezone=GMT&useSSL=false", "root", "Admin@123");
            statement = connection.createStatement();
            String sql = "select * from product";
            res =  statement.executeQuery(sql);
            while(res.next()) {
                System.out.println("pname: " + res.getString("pname")
                        + "price: " + res.getDouble("price"));
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(res, statement, connection);// 在finally里去close()
        }
    }
}

關(guān)于注冊driver的優(yōu)化

看下源碼可以發(fā)現(xiàn)其內(nèi)部有個(gè)static代碼塊:

    static {
        try {
            DriverManager.registerDriver(new Driver()); // 已經(jīng)注冊了一個(gè)Driver
        } catch (SQLException var1) {
            throw new RuntimeException("Can't register driver!");
        }
    }

內(nèi)部已經(jīng)進(jìn)行了driver的注冊,所以沒必要重復(fù)注冊第二個(gè)driver,按照文檔中的示例,可以采用Class.forName("com.mysql.jdbc.Driver").newInstance()(其實(shí)沒必要去newInstance()已經(jīng)有driver,這個(gè)操作浪費(fèi)空間);

優(yōu)化過后的代碼如下所示:

package com;

import java.sql.*;

public class Main {
    public static void main(String[] args) {
        Driver driver;
        Connection connection = null;
        Statement statement = null;
        ResultSet res = null;
        try {
//            driver = new com.mysql.cj.jdbc.Driver(); // 改用動(dòng)態(tài)加載一個(gè)driver類
            Class.forName("com.mysql.cj.jdbc.Driver");
//            DriverManager.registerDriver(driver); // com.mysql.cj.jdbc.Driver內(nèi)部已經(jīng)注冊過driver了  沒必要重復(fù)注冊
            connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/base1?serverTimezone=GMT&useSSL=false", "root", "Admin@123");
            statement = connection.createStatement();
            String sql = "select * from product";
            res =  statement.executeQuery(sql);
            while(res.next()) {
                System.out.println("pname: " + res.getString("pname")
                        + "price: " + res.getDouble("price"));
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(res, statement, connection);
        }
    }
}

關(guān)于Class.forName(className), 在一些應(yīng)用中,無法事先知道使用者將加載什么類(比如本例中使用jdbc可能是其他數(shù)據(jù)庫),而必須讓使用者指定類名稱以加載類,可以使用 Class 的靜態(tài) forName() 方法實(shí)現(xiàn)動(dòng)態(tài)加載類。詳見Class.forName

jdbc.properties

上述例子中的數(shù)據(jù)庫配置等信息都是寫在代碼中的,我們一般是要從配置文件中讀取的,所以我們創(chuàng)建一個(gè)名為jdbc.properties的文件,如下:

driverClass=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://localhost:3306/base1?serverTimezone=GMT&useSSL=false
userName=root
password=Admin@123

然后我們修改JDBCUtils里面的代碼:

package com;

import java.io.FileInputStream;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.Statement;
import java.util.Properties;

public class JDBCUtils {
    static String driverClass = null; // 數(shù)據(jù)庫類型
    static String url = null; // 數(shù)據(jù)庫地址
    static String userName = null;
    static String password = null;

    static { // 默認(rèn)static代碼塊  讀取properties配置
        try {
            Properties properties = new Properties(); // 獲取Properties對象
            InputStream setting = new FileInputStream("src/jdbc.properties"); // 獲取文件流
            properties.load(setting);// properties對象加載讀取到的配置
            driverClass = properties.getProperty("driverClass"); // 從配置中讀取特定的配置
            url = properties.getProperty("url");
            userName = properties.getProperty("userName");
            password = properties.getProperty("password");
        }catch (Exception e) {
            e.printStackTrace();
        }
    }

//    注冊驅(qū)動(dòng)并且并且獲取連接Connection
    public static Connection getConnection() {
        Connection connection = null;
        try {
            Class.forName(driverClass);
            connection = DriverManager.getConnection(url, userName, password);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            return connection;
        }
    }


//     釋放資源
    public static void close(ResultSet res, Statement statement, Connection connection) {
        closeRes(res);
        closeStatement(statement);
        closeConnection(connection);
    }

    public static void closeRes(ResultSet res) {
        try {
            if(res != null) {
                res.close();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            res = null;
        }
    }

    public static void closeStatement(Statement statement) {
        try {
            if(statement != null) {
                statement.close();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            statement = null;
        }
    }

    public static void closeConnection(Connection connection) {
        try {
            if(connection != null) {
                connection.close();
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            connection = null;
        }
    }
}

JDBC對數(shù)據(jù)庫的CRUD

  • insert
 @Test
    public void testInsert() {
        Connection connection = null;
        Statement statement = null;
        ResultSet res = null;
        try{
            connection =  JDBCUtils.getConnection();
            statement = connection.createStatement();
            String sql = "insert into product values(null, '泡椒鳳爪', 3, null, 5);";
            int result = statement.executeUpdate(sql); // 執(zhí)行insert update  delete的時(shí)候使用executeUpdate return int
            if(result > 0) { // result為影響的行數(shù)
                System.out.println("insert successfully!");
            }else {
                System.out.println("insert failed");
            }
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(res, statement, connection);
        }
    }

update和delete同理

使用junit進(jìn)行單元測試

  1. 添加junit依賴
<!-- https://mvnrepository.com/artifact/junit/junit -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
            <scope>test</scope>
        </dependency>
  1. 添加一個(gè)類,定義測試方法,給其加上@Test注解
import com.JDBCUtils;
import org.junit.Test;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.Statement;

public class TestDemo {

    @Test
    public void testQuery() {
        Connection connection = null;
        Statement statement = null;
        ResultSet res = null;
        try{
            connection =  JDBCUtils.getConnection();
            statement = connection.createStatement();
            String sql = "select * from product;";
            res = statement.executeQuery(sql);
        }catch (Exception e) {
            e.printStackTrace();
        }finally {
            JDBCUtils.close(res, statement, connection);
        }
    }
}

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容