1 什么是JDBC
JDBC(Java DataBase Connectivity)就是Java數(shù)據(jù)庫連接莱没,說白了就是用Java語言來操作數(shù)據(jù)庫。原來我們操作數(shù)據(jù)庫是在控制臺(tái)使用SQL語句來操作數(shù)據(jù)庫,JDBC是用Java語言向數(shù)據(jù)庫發(fā)送SQL語句逐哈。
2 JDBC原理
早期SUN公司的天才們想編寫一套可以連接天下所有數(shù)據(jù)庫的API吗冤,但是當(dāng)他們剛剛開始時(shí)就發(fā)現(xiàn)這是不可完成的任務(wù),因?yàn)楦鱾€(gè)廠商的數(shù)據(jù)庫服務(wù)器差異太大了嘲碧。后來SUN開始與數(shù)據(jù)庫廠商們討論稻励,最終得出的結(jié)論是,由SUN提供一套訪問數(shù)據(jù)庫的規(guī)范(就是一組接口)愈涩,并提供連接數(shù)據(jù)庫的協(xié)議標(biāo)準(zhǔn)望抽,然后各個(gè)數(shù)據(jù)庫廠商會(huì)遵循SUN的規(guī)范提供一套訪問自己公司的數(shù)據(jù)庫服務(wù)器的API出現(xiàn)至非。SUN提供的規(guī)范命名為JDBC,而各個(gè)廠商提供的糠聪,遵循了JDBC規(guī)范的荒椭,可以訪問自己數(shù)據(jù)庫的API被稱之為驅(qū)動(dòng)!
[圖片上傳失敗...(image-9f19a1-1515415470578)]
JDBC是接口舰蟆,而JDBC驅(qū)動(dòng)才是接口的實(shí)現(xiàn)趣惠,沒有驅(qū)動(dòng)無法完成數(shù)據(jù)庫連接!每個(gè)數(shù)據(jù)庫廠商都有自己的驅(qū)動(dòng)身害,用來連接自己公司的數(shù)據(jù)庫味悄。
當(dāng)然還有第三方公司專門為某一數(shù)據(jù)庫提供驅(qū)動(dòng),這樣的驅(qū)動(dòng)往往不是開源免費(fèi)的塌鸯!
3 JDBC核心類(接口)介紹
JDBC中的核心類有:DriverManager侍瑟、Connection、Statement丙猬,和ResultSet涨颜!
DriverManger(驅(qū)動(dòng)管理器)的作用有兩個(gè):
l 注冊驅(qū)動(dòng):這可以讓JDBC知道要使用的是哪個(gè)驅(qū)動(dòng);
l 獲取Connection:如果可以獲取到Connection茧球,那么說明已經(jīng)與數(shù)據(jù)庫連接上了庭瑰。
Connection對(duì)象表示連接,與數(shù)據(jù)庫的通訊都是通過這個(gè)對(duì)象展開的:
l Connection最為重要的一個(gè)方法就是用來獲取Statement對(duì)象抢埋;
l Statement是用來向數(shù)據(jù)庫發(fā)送SQL語句的弹灭,這樣數(shù)據(jù)庫就會(huì)執(zhí)行發(fā)送過來的SQL語句
l void executeUpdate(String sql):執(zhí)行更新操作(insert、update揪垄、delete等)穷吮;
l ResultSet executeQuery(String sql):執(zhí)行查詢操作,數(shù)據(jù)庫在執(zhí)行查詢后會(huì)把查詢結(jié)果饥努,查詢結(jié)果就是ResultSet捡鱼;
ResultSet對(duì)象表示查詢結(jié)果集,只有在執(zhí)行查詢操作后才會(huì)有結(jié)果集的產(chǎn)生肪凛。結(jié)果集是一個(gè)二維的表格堰汉,有行有列。操作結(jié)果集要學(xué)習(xí)移動(dòng)ResultSet內(nèi)部的“行光標(biāo)”伟墙,以及獲取當(dāng)前行上的每一列上的數(shù)據(jù):
l boolean next():使“行光標(biāo)”移動(dòng)到下一行翘鸭,并返回移動(dòng)后的行是否存在;
l XXX getXXX(int col):獲取當(dāng)前行指定列上的值戳葵,參數(shù)就是列數(shù)就乓,列數(shù)從1開始,而不是0。
4 Hello JDBC
下面開始編寫第一個(gè)JDBC程序
介紹eclipse的相關(guān)知識(shí)
單元測試junit
4.1 導(dǎo)入****mysql****數(shù)據(jù)庫的驅(qū)動(dòng)****jar****包:
mysql-connector-java-5.1.39-bin.jar生蚁;
4.2 注冊驅(qū)****動(dòng)
看清楚了噩翠,注冊驅(qū)動(dòng)就只有一句話:Class.forName(“com.mysql.jdbc.Driver”),下面的內(nèi)容都是對(duì)這句代碼的解釋邦投。今后我們的代碼中伤锚,與注冊驅(qū)動(dòng)相關(guān)的代碼只有這一句。
DriverManager類的registerDriver()方法的參數(shù)是java.sql.Driver志衣,但java.sql.Driver是一個(gè)接口屯援,實(shí)現(xiàn)類由mysql驅(qū)動(dòng)來提供,mysql驅(qū)動(dòng)中的java.sql.Driver接口的實(shí)現(xiàn)類為com.mysql.jdbc.Driver念脯!那么注冊驅(qū)動(dòng)的代碼如下:
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
上面代碼雖然可以注冊驅(qū)動(dòng)狞洋,但是出現(xiàn)硬編碼(代碼依賴mysql驅(qū)動(dòng)jar包),如果將來想連接Oracle數(shù)據(jù)庫绿店,那么必須要修改代碼的吉懊。并且其實(shí)這種注冊驅(qū)動(dòng)的方式是注冊了兩次驅(qū)動(dòng)!
JDBC中規(guī)定假勿,驅(qū)動(dòng)類在被加載時(shí)借嗽,需要自己“主動(dòng)”把自己注冊到DriverManger中,下面我們來看看com.mysql.jdbc.Driver類的源代碼:
com.mysql.jdbc.Driver.java
|
public classDriver extendsNonRegisteringDriver implements java.sql.Driver {
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
……
}
|
com.mysql.jdbc.Driver類中的static塊會(huì)創(chuàng)建本類對(duì)象废登,并注冊到DriverManager中淹魄。這說明只要去加載com.mysql.jdbc.Driver類郁惜,那么就會(huì)執(zhí)行這個(gè)static塊堡距,從而也就會(huì)把com.mysql.jdbc.Driver注冊到DriverManager中,所以可以把注冊驅(qū)動(dòng)類的代碼修改為加載驅(qū)動(dòng)類兆蕉。
Class.forName(“com.mysql.jdbc.Driver”);
4.3 獲取連接
獲取連接需要兩步羽戒,一是使用DriverManager來注冊驅(qū)動(dòng),二是使用DriverManager來獲取Connection對(duì)象虎韵。
獲取連接的也只有一句代碼:
DriverManager.getConnection(url,username,password)易稠,
其中username和password是登錄數(shù)據(jù)庫的用戶名和密碼,如果我沒說錯(cuò)的話包蓝,你的mysql數(shù)據(jù)庫的用戶名和密碼分別是:root驶社、123。
url查對(duì)復(fù)雜一點(diǎn)测萎,它是用來找到要連接數(shù)據(jù)庫“網(wǎng)址”亡电,就好比你要瀏覽器中查找百度時(shí),也需要提供一個(gè)url硅瞧。下面是mysql的url:
jdbc:mysql://localhost:3306/mydb1
JDBC規(guī)定url的格式由三部分組成份乒,每個(gè)部分中間使用冒號(hào)分隔。
l 第一部分是jdbc,這是固定的或辖;
l 第二部分是數(shù)據(jù)庫名稱瘾英,那么連接mysql數(shù)據(jù)庫,第二部分當(dāng)然是mysql了颂暇;
l 第三部分是由數(shù)據(jù)庫廠商規(guī)定的缺谴,我們需要了解每個(gè)數(shù)據(jù)庫廠商的要求,mysql的第三部分分別由數(shù)據(jù)庫服務(wù)器的IP地址(localhost)耳鸯、端口號(hào)(3306)瓣赂,以及DATABASE名稱(mydb1)組成。
下面是獲取連接的語句:
Connection con = DriverManager.getConnection(“jdbc:mysql://localhost:3306/web08”,”root”,”root”);
還可以在url中提供參數(shù):
jdbc:mysql://localhost:3306/web08?useUnicode=true&characterEncoding=UTF8
useUnicode參數(shù)指定這個(gè)連接數(shù)據(jù)庫的過程中片拍,使用的字節(jié)集是Unicode字節(jié)集煌集;
characherEncoding參數(shù)指定穿上連接數(shù)據(jù)庫的過程中,使用的字節(jié)集編碼為UTF-8編碼捌省。請注意苫纤,mysql中指定UTF-8編碼是給出的是UTF8,而不是UTF-8纲缓。要小心了卷拘!
4.4 獲取****Statement
在得到Connectoin之后,說明已經(jīng)與數(shù)據(jù)庫連接上了祝高,下面是通過Connection獲取Statement對(duì)象的代碼:
Statement stmt = con.createStatement();
Statement是用來向數(shù)據(jù)庫發(fā)送要執(zhí)行的SQL語句的栗弟!
4.5 發(fā)送****SQL****查詢語句
String sql = “select * from user”;
ResultSet rs = stmt.executeQuery(sql);
請注意,執(zhí)行查詢使用的不是executeUpdate()方法工闺,而是executeQuery()方法乍赫。executeQuery()方法返回的是ResultSet,ResultSet封裝了查詢結(jié)果陆蟆,我們稱之為結(jié)果集雷厂。
4.6 讀取****結(jié)果集中的數(shù)據(jù)
ResultSet就是一張二維的表格,它內(nèi)部有一個(gè)“行光標(biāo)”叠殷,光標(biāo)默認(rèn)的位置在“第一行上方”改鲫,我們可以調(diào)用rs對(duì)象的next()方法把“行光標(biāo)”向下移動(dòng)一行,當(dāng)?shù)谝淮握{(diào)用next()方法時(shí)林束,“行光標(biāo)”就到了第一行記錄的位置像棘,這時(shí)就可以使用ResultSet提供的getXXX(int col)方法來獲取指定列的數(shù)據(jù)了:
rs.next();//光標(biāo)移動(dòng)到第一行
rs.getInt(1);//獲取第一行第一列的數(shù)據(jù)
當(dāng)你使用rs.getInt(1)方法時(shí),你必須可以肯定第1列的數(shù)據(jù)類型就是int類型壶冒,如果你不能肯定缕题,那么最好使用rs.getObject(1)。在ResultSet類中提供了一系列的getXXX()方法依痊,比較常用的方法有:
Object getObject(int col)
String getString(int col)
int getInt(int col)
double getDouble(int col)
4.7 關(guān)閉
與IO流一樣避除,使用后的東西都需要關(guān)閉怎披!關(guān)閉的順序是先得到的后關(guān)閉,后得到的先關(guān)閉瓶摆。
rs.close();
stmt.close();
con.close();
4.8 完成查詢操作****代碼
|
public staticConnection getConnection() throws Exception {
Class.forName("com.mysql.jdbc.Driver");
String url = "jdbc:mysql://localhost:3306/web08";
return DriverManager.getConnection(url, "root", "root");
}
|
|
@Test
public voidquery() throws Exception {
Connection con = getConnection();
Statement stmt = con.createStatement();
String sql = "select * from user";
ResultSet rs = stmt.executeQuery(sql);
while(rs.next()) {
String username = rs.getString(1);
String password = rs.getString(2);
System.out.println(username + ", " + password);
}
}
|
e="msSOp@7??