JDBC(Java DataBase Connection)

1.1JDBC概述

JDBC(Java?Data?Base?Connectivity,java數(shù)據(jù)庫(kù)連接)是一種用于執(zhí)行SQL語(yǔ)句的Java?API狸相,可以為多種關(guān)系數(shù)據(jù)庫(kù)提供統(tǒng)一訪問刮吧,它由一組用Java語(yǔ)言編寫的類和接口組成盒件。是Java訪問數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)規(guī)范

JDBC提供了一種基準(zhǔn),據(jù)此可以構(gòu)建更高級(jí)的工具和接口,使數(shù)據(jù)庫(kù)開發(fā)人員能夠編寫數(shù)據(jù)庫(kù)應(yīng)用程序昂灵。

JDBC需要連接驅(qū)動(dòng),驅(qū)動(dòng)是兩個(gè)設(shè)備要進(jìn)行通信舞萄,滿足一定通信數(shù)據(jù)格式眨补,數(shù)據(jù)格式由設(shè)備提供商規(guī)定,設(shè)備提供商為設(shè)備提供驅(qū)動(dòng)軟件倒脓,通過軟件可以與該設(shè)備進(jìn)行通信撑螺。

1.2JDBC原理

Java提供訪問數(shù)據(jù)庫(kù)規(guī)范稱為JDBC,而生產(chǎn)廠商提供規(guī)范的實(shí)現(xiàn)類稱為驅(qū)動(dòng)崎弃。


JDBC是接口甘晤,驅(qū)動(dòng)是接口的實(shí)現(xiàn)含潘,沒有驅(qū)動(dòng)將無法完成數(shù)據(jù)庫(kù)連接,從而不能操作數(shù)據(jù)庫(kù)线婚!每個(gè)數(shù)據(jù)庫(kù)廠商都需要提供自己的驅(qū)動(dòng)遏弱,用來連接自己公司的數(shù)據(jù)庫(kù),也就是說驅(qū)動(dòng)一般都由數(shù)據(jù)庫(kù)生成廠商提供塞弊。

1.3JDBC開發(fā)步驟

1.注冊(cè)驅(qū)動(dòng).

2.獲得連接.

3.獲得語(yǔ)句執(zhí)行平臺(tái)

4.執(zhí)行sql語(yǔ)句

5.處理結(jié)果

6.釋放資源.

1.3.1導(dǎo)入驅(qū)動(dòng)jar包

創(chuàng)建lib目錄漱逸,用于存放當(dāng)前項(xiàng)目需要的所有jar包

選擇jar包,右鍵執(zhí)行build?path?/?Add?to?Build?Path

1.3.2API詳解:注冊(cè)驅(qū)動(dòng)

代碼:Class.forName("com.mysql.jdbc.Driver");

JDBC規(guī)范定義驅(qū)動(dòng)接口:java.sql.Driver游沿,MySql驅(qū)動(dòng)包提供了實(shí)現(xiàn)類:com.mysql.jdbc.Driver

DriverManager工具類饰抒,提供注冊(cè)驅(qū)動(dòng)的方法registerDriver(),方法的參數(shù)是java.sql.Driver诀黍,所以我們可以通過如下語(yǔ)句進(jìn)行注冊(cè):

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

以上代碼不推薦使用袋坑,存在兩方面不足

1.硬編碼,后期不易于程序擴(kuò)展和維護(hù)

2.驅(qū)動(dòng)被注冊(cè)兩次眯勾。

通常開發(fā)我們使用Class.forName()加載一個(gè)使用字符串描述的驅(qū)動(dòng)類枣宫。

如果使用Class.forName()將類加載到內(nèi)存,該類的靜態(tài)代碼將自動(dòng)執(zhí)行咒精。

通過查詢com.mysql.jdbc.Driver源碼镶柱,我們發(fā)現(xiàn)Driver類“主動(dòng)”將自己進(jìn)行注冊(cè)

public?class?Driver?extends?NonRegisteringDriver?implements?java.sql.Driver?{

static?{

try?{

java.sql.DriverManager.registerDriver(new?Driver());

}?catch?(SQLException?E)?{

throw?new?RuntimeException("Can't?register?driver!");

}

}

……

}

1.3.3API詳解:獲得鏈接

代碼:Connection?con?=?DriverManager.getConnection

(“jdbc:mysql://localhost:3306/mydb”,”root”,”root”);

獲取連接需要方法DriverManager.getConnection(url,username,password),三個(gè)參數(shù)分別表示模叙,url需要連接數(shù)據(jù)庫(kù)的位置(網(wǎng)址)user用戶名password密碼

url比較復(fù)雜歇拆,下面是mysql的url:

jdbc:mysql://localhost:3306/mydb

JDBC規(guī)定url的格式由三部分組成,每個(gè)部分中間使用冒號(hào)分隔范咨。

l第一部分是jdbc故觅,這是固定的;

l第二部分是數(shù)據(jù)庫(kù)名稱渠啊,那么連接mysql數(shù)據(jù)庫(kù)输吏,第二部分當(dāng)然是mysql了;

l第三部分是由數(shù)據(jù)庫(kù)廠商規(guī)定的替蛉,我們需要了解每個(gè)數(shù)據(jù)庫(kù)廠商的要求贯溅,mysql的第三部分分別由數(shù)據(jù)庫(kù)服務(wù)器的IP地址(localhost)、端口號(hào)(3306)躲查,以及DATABASE名稱(mydb)組成它浅。

1.3.4API詳解:獲得語(yǔ)句執(zhí)行平臺(tái)

String?sql?=?"某SQL語(yǔ)句";

獲取Statement語(yǔ)句執(zhí)行平臺(tái):Statement?stmt?=?con.createStatement();

常用方法:

nint?executeUpdate(String?sql);?--執(zhí)行insert?update?delete語(yǔ)句.

nResultSet?executeQuery(String?sql);?--執(zhí)行select語(yǔ)句.

nboolean?execute(String?sql);?--執(zhí)行select返回true執(zhí)行其他的語(yǔ)句返回false.

1.3.5API詳解:處理結(jié)果集(執(zhí)行insert、update镣煮、delete無需處理)

ResultSet實(shí)際上就是一張二維的表格姐霍,我們可以調(diào)用其boolean?next()方法指向某行記錄,當(dāng)?shù)谝淮握{(diào)用next()方法時(shí),便指向第一行記錄的位置镊折,這時(shí)就可以使用ResultSet提供的getXXX(int?col)方法(與索引從0開始不同個(gè)胯府,列從1開始)來獲取指定列的數(shù)據(jù):

rs.next();//指向第一行

rs.getInt(1);//獲取第一行第一列的數(shù)據(jù)

常用方法:

nObject?getObject(intindex)/?Object?getObject(String?name)獲得任意對(duì)象

nString?getString(intindex)/?Object?getObject(String?name)獲得字符串

nint?getInt(intindex)/?Object?getObject(String?name)獲得整形

ndouble?getDouble(intindex)/?Object?getObject(String?name)獲得雙精度浮點(diǎn)型

1.3.6API詳解:釋放資源

與IO流一樣,使用后的東西都需要關(guān)閉恨胚!關(guān)閉的順序是先得到的后關(guān)閉骂因,后得到的先關(guān)閉。

rs.close();

stmt.close();

con.close();

1.4SQL注入問題

假設(shè)有登錄案例SQL語(yǔ)句如下:

SELECT?*?FROM用戶表WHERE?NAME?=用戶輸入的用戶名AND?PASSWORD?=用戶輸?shù)拿艽a;

此時(shí)与纽,當(dāng)用戶輸入正確的賬號(hào)與密碼后侣签,查詢到了信息則讓用戶登錄。但是當(dāng)用戶輸入的賬號(hào)為XXX密碼為:XXX’OR‘a(chǎn)’=’a時(shí)急迂,則真正執(zhí)行的代碼變?yōu)椋?/p>

SELECT?*?FROM用戶表WHERE?NAME?=‘XXX’AND?PASSWORD?=’XXX’OR’a’=’a’;

此時(shí)影所,上述查詢語(yǔ)句時(shí)永遠(yuǎn)可以查詢出結(jié)果的。那么用戶就直接登錄成功了僚碎,顯然我們不希望看到這樣的結(jié)果猴娩,這便是SQL注入問題。

為此勺阐,我們使用PreparedStatement來解決對(duì)應(yīng)的問題卷中。

1.5API詳解:預(yù)處理對(duì)象

使用PreparedStatement預(yù)處理對(duì)象時(shí),建議每條sql語(yǔ)句所有的實(shí)際參數(shù)渊抽,都使用逗號(hào)分隔蟆豫。

String?sql?=?"insert?into?sort(sid,sname)?values(?,?)";;

PreparedStatement預(yù)處理對(duì)象代碼:

PreparedStatement?psmt?=?conn.prepareStatement(sql)

常用方法:

1.執(zhí)行SQL語(yǔ)句:

lint?executeUpdate();?--執(zhí)行insert?update?delete語(yǔ)句.

lResultSet?executeQuery();?--執(zhí)行select語(yǔ)句.

lboolean?execute();?--執(zhí)行select返回true?執(zhí)行其他的語(yǔ)句返回false.

2.設(shè)置實(shí)際參數(shù)

lvoidsetXxx(intindex,Xxxxx)?將指定參數(shù)設(shè)置為給定Java的xx值。在將此值發(fā)送到數(shù)據(jù)庫(kù)時(shí)懒闷,驅(qū)動(dòng)程序?qū)⑺D(zhuǎn)換成一個(gè)?SQLXxx類型值十减。

例如:

setString(2,?"家用電器")把SQL語(yǔ)句中第2個(gè)位置的占位符??替換成實(shí)際參數(shù)"家用電器"

1.6預(yù)處理對(duì)象executeUpdate方法

通過預(yù)處理對(duì)象的executeUpdate方法愤估,完成記錄的insert\update\delete語(yǔ)句的執(zhí)行帮辟。操作格式統(tǒng)一如下:

1.注冊(cè)驅(qū)動(dòng)

2.獲取連接

3.獲取預(yù)處理對(duì)象

4.?SQL語(yǔ)句占位符設(shè)置實(shí)際參數(shù)

5.執(zhí)行SQL語(yǔ)句

6.釋放資源

1.6.1插入記錄:insert

l實(shí)現(xiàn)向分類表中插入指定的新分類

publicvoiddemo01()throwsException?{

//?1注冊(cè)驅(qū)動(dòng)

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

//?2獲取連接

Connectionconn=?DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root");

//?3獲得預(yù)處理對(duì)象

Stringsql="insert?into?sort(sname)?values(?)";

PreparedStatementstat=conn.prepareStatement(sql);

//?4SQL語(yǔ)句占位符設(shè)置實(shí)際參數(shù)

stat.setString(1,"奢侈品");

//?5執(zhí)行SQL語(yǔ)句

intline=stat.executeUpdate();

System.out.println("新添加記錄數(shù):"+line);

//6釋放資源

stat.close();

conn.close();

}

1.6.2更新記錄:update

l實(shí)現(xiàn)更新分類表中指定分類ID所對(duì)應(yīng)記錄的分類名稱

publicvoiddemo02()throwsException?{

//?1注冊(cè)驅(qū)動(dòng)

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

//?2獲取連接

Connectionconn=?DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root");

//?3獲得預(yù)處理對(duì)象中

Stringsql="update?sort?set?sname=??where?sid=?";

PreparedStatementstat=conn.prepareStatement(sql);

//?4SQL語(yǔ)句占位符設(shè)置實(shí)際參數(shù)

stat.setString(1,"數(shù)碼產(chǎn)品");

stat.setInt(2,?1);

//?5執(zhí)行SQL語(yǔ)句

intline=stat.executeUpdate();

System.out.println("更新記錄數(shù):"+line);

//6釋放資源

stat.close();

conn.close();

}

1.6.3刪除記錄:delete

l實(shí)現(xiàn)刪除分類表中指定分類ID的記錄

publicvoiddemo03()throwsException?{

//?1注冊(cè)驅(qū)動(dòng)

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

//?2獲取連接

Connectionconn=?DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root");

//?3獲得預(yù)處理對(duì)象

Stringsql="delete?from?sort?where?sid=?";

PreparedStatementstat=conn.prepareStatement(sql);

//?4SQL語(yǔ)句占位符設(shè)置實(shí)際參數(shù)

stat.setInt(1,?1);

//?5執(zhí)行SQL語(yǔ)句

intline=stat.executeUpdate();

System.out.println("刪除記錄數(shù):"+line);

//6釋放資源

stat.close();

conn.close();

}

1.7預(yù)處理對(duì)象executeQuery方法

通過預(yù)處理對(duì)象的executeQuery方法,完成記錄的select語(yǔ)句的執(zhí)行玩焰。操作格式統(tǒng)一如下:

1.注冊(cè)驅(qū)動(dòng)

2.獲取連接

3.獲取預(yù)處理對(duì)象

4.?SQL語(yǔ)句占位符設(shè)置實(shí)際參數(shù)

5.執(zhí)行SQL語(yǔ)句

6.處理結(jié)果集(遍歷結(jié)果集合)

7.釋放資源

1.7.1查詢記錄:select

l實(shí)現(xiàn)查詢分類表所有記錄

publicvoiddemo04()throwsException?{

//?1注冊(cè)驅(qū)動(dòng)

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

//?2獲取連接

Connectionconn=?DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root");

//?3獲得預(yù)處理對(duì)象

Stringsql="select?*?from?sort";

PreparedStatementstat=conn.prepareStatement(sql);

//?4SQL語(yǔ)句占位符設(shè)置實(shí)際參數(shù)

//?5執(zhí)行SQL語(yǔ)句

ResultSetrs=stat.executeQuery();

//6處理結(jié)果集(遍歷結(jié)果集合)

while(rs.next()?){

//獲取當(dāng)前行的分類ID

Stringsid=rs.getString("sid");//方法參數(shù)為數(shù)據(jù)庫(kù)表中的列名

//獲取當(dāng)前行的分類名稱

Stringsname=rs.getString("sname");

//顯示數(shù)據(jù)

System.out.println(sid+"-----"+sname);

}

//7釋放資源

rs.close();

stat.close();

conn.close();

}

l實(shí)現(xiàn)查詢分類表中指定分類名稱的記錄

publicvoiddemo05()throwsException?{

//?1注冊(cè)驅(qū)動(dòng)

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

//?2獲取連接

Connectionconn=?DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb","root","root");

//?3獲得預(yù)處理對(duì)象

Stringsql="select?*?from?sort?where?sname=?";

PreparedStatementstat=conn.prepareStatement(sql);

//?4SQL語(yǔ)句占位符設(shè)置實(shí)際參數(shù)

stat.setString(1,"奢侈品");

//5執(zhí)行SQL語(yǔ)句

ResultSetrs=stat.executeQuery();

//6處理結(jié)果集(遍歷結(jié)果集合)

while(rs.next()?){

//獲取當(dāng)前行的分類ID

Stringsid=rs.getString("sid");//方法參數(shù)為數(shù)據(jù)庫(kù)表中的列名

//獲取當(dāng)前行的分類名稱

Stringsname=rs.getString("sname");

//顯示數(shù)據(jù)

System.out.println(sid+"-----"+sname);

}

//7釋放資源

rs.close();

stat.close();

conn.close();

}

1.8JDBC工具類

“獲得數(shù)據(jù)庫(kù)連接”操作由驹,將在以后的增刪改查所有功能中都存在,可以封裝工具類JDBCUtils昔园。提供獲取連接對(duì)象的方法蔓榄,從而達(dá)到代碼的重復(fù)利用。

該工具類提供方法:public?static?Connection?getConn?()默刚。代碼如下:

/*

*?JDBC工具類

*/

publicclassJDBCUtils?{

publicstaticfinalStringDRIVERNAME="com.mysql.jdbc.Driver";

publicstaticfinalStringURL="jdbc:mysql://localhost:3306/mydb";

publicstaticfinalStringUSER="root";

publicstaticfinalStringPASSWORD="root";

static{

try{

Class.forName(DRIVERNAME);

}catch(ClassNotFoundExceptione)?{

System.out.println("數(shù)據(jù)庫(kù)驅(qū)動(dòng)注冊(cè)失斏!!");

}

}

//提供獲取連接的方法

publicstaticConnection?getConn()throwsException?{

//?2.獲得連接

Connectionconn=?DriverManager.getConnection(URL,USER,PASSWORD);

//返回連接

returnconn;

}

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末羡棵,一起剝皮案震驚了整個(gè)濱河市壹若,隨后出現(xiàn)的幾起案子嗅钻,更是在濱河造成了極大的恐慌皂冰,老刑警劉巖店展,帶你破解...
    沈念sama閱讀 221,576評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異秃流,居然都是意外死亡赂蕴,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,515評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門舶胀,熙熙樓的掌柜王于貴愁眉苦臉地迎上來概说,“玉大人,你說我怎么就攤上這事嚣伐√桥猓” “怎么了?”我有些...
    開封第一講書人閱讀 168,017評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵轩端,是天一觀的道長(zhǎng)放典。 經(jīng)常有香客問我,道長(zhǎng)基茵,這世上最難降的妖魔是什么奋构? 我笑而不...
    開封第一講書人閱讀 59,626評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮拱层,結(jié)果婚禮上弥臼,老公的妹妹穿的比我還像新娘。我一直安慰自己根灯,他們只是感情好径缅,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,625評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著箱吕,像睡著了一般芥驳。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茬高,一...
    開封第一講書人閱讀 52,255評(píng)論 1 308
  • 那天兆旬,我揣著相機(jī)與錄音,去河邊找鬼怎栽。 笑死丽猬,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的熏瞄。 我是一名探鬼主播脚祟,決...
    沈念sama閱讀 40,825評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼强饮!你這毒婦竟也來了由桌?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,729評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎行您,沒想到半個(gè)月后铭乾,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,271評(píng)論 1 320
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡娃循,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,363評(píng)論 3 340
  • 正文 我和宋清朗相戀三年炕檩,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片捌斧。...
    茶點(diǎn)故事閱讀 40,498評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡笛质,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出捞蚂,到底是詐尸還是另有隱情妇押,我是刑警寧澤,帶...
    沈念sama閱讀 36,183評(píng)論 5 350
  • 正文 年R本政府宣布姓迅,位于F島的核電站舆吮,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏队贱。R本人自食惡果不足惜色冀,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,867評(píng)論 3 333
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望柱嫌。 院中可真熱鬧锋恬,春花似錦、人聲如沸编丘。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,338評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)嘉抓。三九已至索守,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間抑片,已是汗流浹背卵佛。 一陣腳步聲響...
    開封第一講書人閱讀 33,458評(píng)論 1 272
  • 我被黑心中介騙來泰國(guó)打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留敞斋,地道東北人截汪。 一個(gè)月前我還...
    沈念sama閱讀 48,906評(píng)論 3 376
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像植捎,于是被迫代替她去往敵國(guó)和親衙解。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,507評(píng)論 2 359

推薦閱讀更多精彩內(nèi)容

  • JDBC簡(jiǎn)介 SUN公司為了簡(jiǎn)化焰枢、統(tǒng)一對(duì)數(shù)據(jù)庫(kù)的操作蚓峦,定義了一套Java操作數(shù)據(jù)庫(kù)的規(guī)范舌剂,稱之為JDBC。JDBC...
    奮斗的老王閱讀 1,520評(píng)論 0 51
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法暑椰,類相關(guān)的語(yǔ)法架诞,內(nèi)部類的語(yǔ)法,繼承相關(guān)的語(yǔ)法干茉,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚_t_閱讀 31,662評(píng)論 18 399
  • 1. 簡(jiǎn)介 1.1 什么是 MyBatis 很泊? MyBatis 是支持定制化 SQL角虫、存儲(chǔ)過程以及高級(jí)映射的優(yōu)秀的...
    笨鳥慢飛閱讀 5,527評(píng)論 0 4
  • 1、青梅糖漬發(fā)酵 隨便果的載體青梅依靠大自然的饋贈(zèng)委造,至少發(fā)酵四個(gè)月以上的時(shí)間戳鹅,緩慢但是很有力量。把最奢侈的時(shí)間昏兆,“...
    向日葵ll閱讀 3,104評(píng)論 0 0
  • 今天是六一兒童節(jié)枫虏,似乎不寫點(diǎn)關(guān)于兒童的文章,就對(duì)不起自己幼兒教師的身份爬虱。所以寫下了以下幾點(diǎn)關(guān)于孩子教育的觀點(diǎn)隶债。 ...
    阿寶的育兒寶典閱讀 427評(píng)論 0 2