首頁新聞動態(tài)正文

JDBC詳細(xì)教程與jdbc連接數(shù)據(jù)庫方法

更新時間:2020-01-15 來源:黑馬程序員 瀏覽量:

1、什么是JDBC?

在web開發(fā)中,不可避免的地要使用數(shù)據(jù)庫來存儲和管理數(shù)據(jù)。為了在java語言中提供數(shù)據(jù)庫訪問的支持,Sun公司于1996年提供了一套訪問數(shù)據(jù)的標(biāo)準(zhǔn)Java類庫,即JDBC。

 

JDBC的全稱是Java數(shù)據(jù)庫連接(Java Database connect),它是一套用于執(zhí)行SQL語句的Java API。應(yīng)用程序可通過這套API連接到關(guān)系數(shù)據(jù)庫,并使用SQL語句來完成對數(shù)據(jù)庫中數(shù)據(jù)的查詢、更新和刪除等操作。應(yīng)用程序使用JDBC訪問數(shù)據(jù)庫的方式如下圖所示。

1579081855646_應(yīng)用程序使用JDBC訪問數(shù)據(jù)庫的方式.jpg


從上圖可以看出,應(yīng)用程序使用JDBC訪問特定的數(shù)據(jù)庫時,需要與不同的數(shù)據(jù)庫驅(qū)動進(jìn)行連接。由于不同數(shù)據(jù)庫廠商提供的數(shù)據(jù)庫驅(qū)動不同,因此,為了使應(yīng)用程序與數(shù)據(jù)庫真正建立連接,JDBC不僅需要提供訪問數(shù)據(jù)庫的API,還需要封裝與各種數(shù)據(jù)庫服務(wù)器通信的細(xì)節(jié)為了幫助大家更好地理解應(yīng)用程序如何通過JDBC訪問數(shù)據(jù)庫,下面通過一張圖來描述JDBC的具體實(shí)現(xiàn)細(xì)節(jié),如下圖。

 

1579081871336_JDBC實(shí)現(xiàn)細(xì)節(jié).jpg

從上圖中可以看出,JDBC的實(shí)現(xiàn)包括三部分。

 

(1)JDBC驅(qū)動管理器:負(fù)責(zé)注冊特定的JDBC驅(qū)動器,主要通過java.sql. Driver Manager類實(shí)現(xiàn)。

(2)JDBC驅(qū)動器API:由Sun公司負(fù)責(zé)制定,其中最主要的接口是java.sql. Driver接口。

 

(3)JDBC驅(qū)動器:它是一種數(shù)據(jù)庫驅(qū)動,由數(shù)據(jù)庫廠商創(chuàng)建,也稱為JDBC驅(qū)動程序JDBC驅(qū)動器實(shí)現(xiàn)了JDBC驅(qū)動器API,負(fù)責(zé)與特定的數(shù)據(jù)庫連接,以及處理通信細(xì)節(jié)。

 

 

2、JDBC常用API

在開發(fā)JDBC程序前,首先了解一下JDBC常用的API。JDBC API主要位于java.sql包中,該包定義了一系列訪問數(shù)據(jù)庫的接口和類,具體如下。

 

1. Driver接口

Driver接口是所有JDBC驅(qū)動程序必須實(shí)現(xiàn)的接口,該接口專門提供給數(shù)據(jù)庫廠商使用。在編寫JDBC程序時,必須要把指定數(shù)據(jù)庫驅(qū)動程序或類庫加載到項(xiàng)目的classpath中。

2. DriverManager類

Driver Manager類用于加載JDBC驅(qū)動并且創(chuàng)建與數(shù)據(jù)庫的連接。在Driver Manager類中,定義了兩個比較重要的靜態(tài)方法。如表所示:

registerDriver(Driver driver) 
該方法用于向 DriverManager中注冊給定的JDBC驅(qū)動程程序

getConnection(String url,String user,String pwd)
該方法用于建立和數(shù)據(jù)庫的連接,并返回表示連接的 Connection對象

1579081881999_01DriverManager類方法.jpg


3、Connection接口

Connection接口代表Java程序和數(shù)據(jù)庫的連接,在Connection接口中,定義了一系列方法,具體如表所示。

 

1579081891751_02connection接口.jpg


getMetaData()
該方法用于返回表示數(shù)據(jù)庫的元數(shù)據(jù)的 DatabaseMetaData對象

createStatement()
用于創(chuàng)建一個Statement對象來將SQL語句發(fā)送到數(shù)據(jù)庫

prepareStatement(String sql)
用于創(chuàng)建一個PreparedStatement對象來將參數(shù)化的SQL語句發(fā)送到數(shù)據(jù)庫

prepareCall(String sql)
用于創(chuàng)建一個CallableStatement對象來調(diào)用數(shù)據(jù)庫存儲過程

4、Statement接口

Statement接口用于向數(shù)據(jù)庫發(fā)送SQL語句,在Statement接口中,提供了三個執(zhí)行SQL語句的方法,具體如表所示。

execute(String sql)

用于執(zhí)行各種SQL語句,該方法返回一個boolean類型的值,如果為true,表示所執(zhí)行的SQL語句具備查詢結(jié)果,可通過Statement的getResultSet方法獲得查詢結(jié)果。

executeUpdate(String sql)

用于執(zhí)行SQL中的Insert、update和delete語句。該方法返回一個int類型的值,表示數(shù)據(jù)庫中受該SQL語句影響的記錄的數(shù)目。


executeQuery(String sql)

用于執(zhí)行SQL中的select語句,該方法返回一個表示查詢結(jié)果的ResultSet對象    

1579081902447_03Statement接口.jpg


5. PreparedStatement接口

 

PreparedStatement是Statement的子接口,用于執(zhí)行預(yù)編譯的SQL語句。在PreparedStatement接口中,提供了一些基本操作的方法,具體如表下所示。

 

1579081913409_04PreparedStatement接口.jpg

executeUpdate()    

在此PreparedStatement對象中執(zhí)行SQL語句,該語句必須是個DML語句或者是無返回內(nèi)容的SQL語句,比如DDL語句。

executeQuery()

在此PreparedStatement對象中執(zhí)行SQL查詢,該方法返回的ResultSet對象    


setInt(int   parameterIndex, int x)    

將指定參數(shù)設(shè)置為給定的int值    


setFloat(int   parameterIndex, float x)    

指定參數(shù)設(shè)置為給定的float值    


setString(int   parameterIndex, String x)    

將指定參數(shù)設(shè)置為給定的String值    


setDate(int   parameterIndex, Date x)    

將指定參數(shù)設(shè)置為給定的Date值    


addBatch()    

將一組參數(shù)添加到此PreparedStatement對象的批處理命令中    


setCharacterStream(parameterIndex,   reader, length) 

將指定的輸入流寫入數(shù)據(jù)庫的文本字段

setBinaryStream(parameterIndex,   x, length) 

將二進(jìn)制的輸入流數(shù)據(jù)寫入到二進(jìn)制字段中


需要注意的是,上表中的setDate()方法可以設(shè)置日期內(nèi)容,但參數(shù)Date的類型是java.sq.Date,而不是java.util.Date。

 

6、CallableStatement接口

CallableStatement是PreparedStatement的子接口,用于執(zhí)行SQL存儲過程。在Callablestatement按接口中,提供了一些基本操作的方法,具體下表所示:

    


registerOutParameter(int parameterIndex,int sqlType)

按順序位置將OUT參數(shù)注冊為SQL類型。其中,parameterIndex表示順序位置,sqlType表示SQL類型

setNull(String parameter Name, int sqlType)

將指定參數(shù)設(shè)置為SQL類型的NULL    


setString(String parameterName, String x)

查詢最后一個讀取的OUT參數(shù)是否為SQL類型的NULL

wasNull()

查詢最后一個讀取的OUT參數(shù)是否為SQL類型的NULL

getlnt(int parameterIndex)

以Java語言中int值的形式獲取指定的數(shù)據(jù)庫中INTEGER類型參數(shù)的值
 

需要注意的是,由于 CallableStatement接口繼承PreparedStatement,PreparedStatement接口又繼承了 Statement,因此CallableStatement接口中除了擁有自己特有的方法,也同時擁有了這兩個父接口中的方法。


7、ResultSet接口

ResultSet接口表示 select查詢語句得到的結(jié)果集,該結(jié)果集封裝在一個邏輯表格中。在 ResultSet接口內(nèi)部有一個指向表格數(shù)據(jù)行的游標(biāo),ResultSet對象初始化時,游標(biāo)在表格的第一行之前。下表中列舉了ResultSet接口中的常用方法。

1579081951330_06ResultSet.jpg

getString(int columnIndex)

用于獲取指定字段的String類型的值,參數(shù)columnIndex代表字段的索引

getString(String columnName)    

用于獲取指定字段的String類型的值,參數(shù)column   Name代表字段的名稱

getInt(int columnIndex)    

用于獲取指定字段的int類型的值,參數(shù)columnIndex代表字段的索引

getInt(String columnName)

用于獲取指定字段的int類型的值,參數(shù)columnName代表字段的名稱

getDate(int columnIndex)

用于獲取指定字段的Date類型的值,參數(shù)columnIndex代表字段的索引

getDate(String columnName)

用于獲取指定字段的Date類型的值,參數(shù)column   Name代表字段的名稱    


next()

將游標(biāo)從當(dāng)前位置向下移一行    


absolute(int row)

將游標(biāo)移動到此Resultset對象的指定行    


afterLast()

將游標(biāo)移動到此ResultSet對象的末尾,即最后一行之后    


beforeFirst()

將游標(biāo)移動到此Resultset對象的開頭,即第一行之前

previous()
將游標(biāo)移動到此ResultSet對象的上一行

last()

將游標(biāo)移動到此ResultSet對象的最    

從上表中可以看出,ResultSet接口中定義了大量的getXxx()方法,采用哪種getXxx()方法取決于字段的數(shù)據(jù)類型。程序既可以通過字段的名稱來獲取指定數(shù)據(jù),也可以通過字段的索引來獲取指定的數(shù)據(jù),字段的索引是從1開始編號的。


3、實(shí)現(xiàn)第一個JDBC程序

通過前面的學(xué)習(xí),我們對JDBC及其常用API有了大致的了解,接下來就開始介紹JDBC編程,JDBC編程大致按照以下幾個步驟進(jìn)行。

(1) 加載并注冊數(shù)據(jù)庫驅(qū)動,具體方式如下。

DriverManager.registerDriver(Driver driver);


(2) 通過Driver Manager獲取數(shù)據(jù)庫連接,具體方式如下。

Connection conn= DriverManager.getConnection(String url, String user, String pass);

從上述方式可以看出,getConnection()方法中有三個參數(shù),它們分別表示數(shù)據(jù)庫url、登錄數(shù)據(jù)庫的用戶名和密碼。數(shù)據(jù)庫山通常遵循如下形式的寫法。

jdbc:subprotocol:subname

 

上面的URL寫法中jdbc部分是固定的,subprotocol指定鏈接達(dá)到特定數(shù)據(jù)庫的驅(qū)動程序,而subname部分則很不固定,也沒有什么規(guī)律,不同數(shù)據(jù)庫的形式可能存在較大差異,一Mysql數(shù)據(jù)庫為例,其形式如下:

jdbc:mysql://hostname:port/databasename


(3)通過Connection對象獲取Statement對象。Connection創(chuàng)建Statement的方式有如下三種。

① createStatement(): 創(chuàng)建基本的Statement對象

② prepareStatement(): 創(chuàng)建PreparedStatement對象。

③ preparCall(): 創(chuàng)建CallableStatement對象。

以創(chuàng)建基本的Statement對象為例,具體方式如下。

Statement stmt=conn.createStatement();

(4)使用Statement執(zhí)行SQL語句。所有的Statement都有如下三種方法來執(zhí)行語句。

①execute():可以執(zhí)行任何SQL語句。

②executeQuery():通常執(zhí)行查詢語句,執(zhí)行后返回代表結(jié)果集的Resultset對象。

③executeUpdate():主要用于執(zhí)行DML和DDL語句。執(zhí)行DML語句,如INSERT、UPDATE或 DELETE時,返回受SQL語句影響的行數(shù),執(zhí)行DDL語句返回0。

以executeQuer()方法為例,具體方式如下。

//執(zhí)行SQL語句,獲取結(jié)果集ResulSet

ResultSet rs=stmt.executQuery(sql);


(5)操作ResultSet結(jié)果集。如果執(zhí)行的SQL語句是查詢語句,執(zhí)行結(jié)果將返回Resultset對象,該對象里保存了SQL語句查詢的結(jié)果。程序可以通過操作該ResultSet對象來取出查詢結(jié)果。 ResultSet對象提供的方法主要可以分為以下兩類。

①next()、previous()、first()、last()、beforeFirst()、afterLast()、absolute()等移動記錄指針的方法

②getXxx()獲取指針指向行,特定列的值。

(6)回收數(shù)據(jù)庫資源。關(guān)閉數(shù)據(jù)庫連接,釋放資源,包括關(guān)閉ResultSet、Statement和Connection等資源。

至此,JDBC編程的大致步驟已經(jīng)完成,為了幫助讀者快速學(xué)習(xí)如何開發(fā)JDBC程序,接下來,編寫第一個JDBC程序,改程序從user表中讀取數(shù)據(jù),并將結(jié)果結(jié)果打印在控制臺,具體步驟入戲所示。

1、搭建實(shí)驗(yàn)環(huán)境

CREATE DATABASE chapter01;

USE chapter01;

CREATE TABLE users(

      id INT PRIMARY KEY AUTO_INCREMENT,

      name VARCHAR(40),

      password VARCHAR(40),

      email VARCHAR(60),

      birthday DATE

)CHARACTER SET utf8 COOLLATE utf8_genneral_ci;

 

數(shù)據(jù)庫和表創(chuàng)建成功后,再向users表中插入三條數(shù)據(jù),SQL語句如下所示。

INSERT INTO users(NAME,PASSWORD,email,birthday)

VALUES('zs','123456','zs@sina.com','1980-12-04');

INSERT INTO users(NAME,PASSWORD,email,birthday)

VALUES('lisi',123456,1isi@sina.com,'1981-12-04');

INSERT INTO users(NAME,PASSWORD,email,birthday)

VALUES('wangwu',123456,'wangwu@sina.com','1979-12-04');


2、導(dǎo)入數(shù)據(jù)庫驅(qū)動

新建Java工程chapter01,將要訪問的數(shù)據(jù)庫驅(qū)動文件添加到classpath中。由于應(yīng)用程序訪問的是MySQL數(shù)據(jù)庫,因此,將MySQL的數(shù)據(jù)庫驅(qū)動文件mysql-connector-java-5.0.8-bin.jar添加到classpath中即可。

3、編寫JDBC程序

在工程chapter01中,新建Java類Example01,該類用于讀取數(shù)據(jù)庫中的users表,并將結(jié)果輸出,如例下面案例所示。

package cn.itcast.jdbc.example;

import java.sql.Connection;

import java.sql.DriverManager;

import java.sql.ResultSet;

import java.sql.SQLException;

import java.sql.Statement;

import java.sql.Date;

public class Example01 {

    public static void main(String[] args) throws SQLException {

        //1.注冊數(shù)據(jù)庫的驅(qū)動

        DriverManager.registerDriver(new com.mysql.jdbc.Driver());

        //2.通過 DriverManager獲取數(shù)據(jù)庫連接

        String url="jdbc:mysql://localhost:3306/chapter01";

        String usernames="root";

        String password="itcast";

        Connection conn=DriverManager.getConnection(url, username, password);

        //3.通過 Connection對象獲取 Statement對象

        Statement stmt= conn.createStatement();

        //4.使用 Statement執(zhí)行SQL語句

        String sql="select * from users";

        ResultSet rs=stmt.executeQuery(sql);

        //5、操作 ResultSet結(jié)果集

        System.out.println("id|name|password|email|birthday");

        while (rs.next()) {

            int id=rs.getInt("id");     //通過列名獲取指定字段的值

            String name=rs.getString("name");

            String psw=rs.getString("password");

            String email=rs.getString("email");

            Date birthday=rs.getDate("birthday");

            System.out.println(id+"|"+name+"|"+psw+"|"+email+"|"+birthday); 

        }

        //6.回收數(shù)據(jù)庫

        rs.close();

        stmt.close();

        conn.close();

    }

}

程序執(zhí)行后,會講從users表中讀取到的數(shù)據(jù)打印到控制臺。

 

在上面案例中演示了JDBC訪問數(shù)據(jù)庫的步驟。首先注冊MySQL的數(shù)據(jù)庫驅(qū)動器類,通過 DriverManager獲取一個Connection對象,然后使用Connection對象創(chuàng)建了一個Statement對象,Statement對象能夠通過executeQuery()方法執(zhí)行SQL語句,并返回結(jié)果集ResultSet對象。最后,通過遍歷Resultset對象便可得到最終的查詢結(jié)果需要注意的是,在實(shí)現(xiàn)第一個JDBC程序時,還有兩個方面需要改進(jìn),具體如下。


1、注冊驅(qū)動

在注冊數(shù)據(jù)庫驅(qū)動時,雖然DriverManager.registerDriver(new com. mysql.jdbc.Driver())方法可以完成,但會使數(shù)據(jù)庫驅(qū)動被注冊兩次。這是因?yàn)镈river類的源碼中,已經(jīng)在靜態(tài)代碼塊中完成了數(shù)據(jù)庫驅(qū)動的注冊。所以,為了避免數(shù)據(jù)庫驅(qū)動被重復(fù)注冊,只需要在程序中加載驅(qū)動類即可,具體加載方式如下所示。

Class.forName("com.mysqk.jdbc.Driver");

2、釋放資源

由于數(shù)據(jù)庫資源非常寶貴,數(shù)據(jù)庫允許的并發(fā)訪問連接數(shù)量有限,因此,當(dāng)數(shù)據(jù)庫資源使用完畢后,一定要記得釋放資源。為了保證資源的釋放,在Java程序中,應(yīng)該將最終必須要執(zhí)行的操作放在finally代碼塊中,具體方式如下。

 

if(rs!=null) {

    try {

        rs.close();

    }catch (SQLException e) {

        e.printStackTrace();

    }

    rs=null;

}

if(stmt!=null) {

    try {

        stmt.close();

    }catch (SQLException e) {

        e.printStackTrace();

    }

    stmt=null;

}

if(conn!=null) {

    try {

        conn.close();

    } catch (SQLException e) {

        e.printStackTrace();

    }

    conn=null;

}

 

1577370495235_學(xué)IT就到黑馬程序員.gif


猜你喜歡:

畢向東Java基礎(chǔ)入門視頻教程下載

JDK下載安裝與環(huán)境變量配置圖文教程

分享到:
在線咨詢 我要報名
和我們在線交談!