謙虛其心捧韵,宏大其量
上午主要學(xué)習(xí)了JDBC
JDBC(Java DataBase Connectivity,即java數(shù)據(jù)庫(kù)連接)是一種用于執(zhí)行SQL語(yǔ)句的Java API,可以為多種關(guān)系數(shù)據(jù)庫(kù)提供統(tǒng)一訪問(wèn),它由一組用Java語(yǔ)言編寫(xiě)的類(lèi)和接口組成磺平。JDBC提供了一種基準(zhǔn)段标,據(jù)此可以構(gòu)建更高級(jí)的工具和接口,使數(shù)據(jù)庫(kù)開(kāi)發(fā)人員能夠編寫(xiě)數(shù)據(jù)庫(kù)應(yīng)用程序可款。
(JDBC用socket技術(shù)實(shí)現(xiàn) 是典型的兩個(gè)進(jìn)程之間的通信)
基于昨天學(xué)的MySQL知識(shí)
http://www.reibang.com/p/c98059693e5d
在itcast數(shù)據(jù)庫(kù)中建立的student表:
在MyEclispse中建立Web項(xiàng)目:
下載老師給的mysql-connector-java-5.1.30.jar文件
http://pan.baidu.com/s/1bp1tb7h
(用于連接java和mysql數(shù)據(jù)庫(kù)關(guān)鍵文件)
選中文件 (左上角):
復(fù)制文件后直接粘貼到 Web工程中WebRoot\WEB-INF\lib文件夾下:
安裝的MySQL數(shù)據(jù)庫(kù)為服務(wù)器端(左)
打開(kāi)的MySQL命令行是客戶端程序(右):
我們?cè)诳蛻舳?shell)下輸入指令:
傳給MySQL服務(wù)器端后 其接收指令——解釋指令——執(zhí)行指令——返回給shell結(jié)果
Java 所有的API都是為了讓我們方便編程設(shè)計(jì)的育韩,讓程序員不用再去考慮很復(fù)雜的問(wèn)題,但要知道其原理闺鲸! JDBC就是一種用于執(zhí)行SQL語(yǔ)句的Java API筋讨。
使用JDBC來(lái)操作數(shù)據(jù)庫(kù)用到的類(lèi):
1 Connection 連接 (接頭人)
2 Statement 語(yǔ)句 (送信的)
3 ResultSet 結(jié)果集 (查詢(xún)需要)
連接遍歷數(shù)據(jù)庫(kù)的大致步驟:
遍歷打印數(shù)據(jù)庫(kù)中數(shù)據(jù) 代碼:
import java.sql.DriverManager;
import java.sql.ResultSet;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
public class TestJDBC {
public static void main(String[] args) throws Exception {
// 第一步 先加載注冊(cè)JDBC的驅(qū)動(dòng)類(lèi)
Class.forName("com.mysql.jdbc.Driver");
// 第二步 提供JDBC連接的url
String url = "jdbc:mysql://localhost:3306/itcast";
String username = "root";
String password = "root";
// 第三步 創(chuàng)建數(shù)據(jù)庫(kù)的連接(利用驅(qū)動(dòng)器管理器DriverManager的getConnection方法)
Connection conn = (Connection) DriverManager.getConnection(url, username, password);
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
Statement stmt = (Statement) conn.createStatement();
// 第五步 執(zhí)行sql語(yǔ)句
ResultSet rs = stmt.executeQuery("select * from student");
// 第六步 循環(huán)遍歷處理結(jié)果
while(rs.next()) {
System.out.println(rs.getString("name"));
System.out.println(rs.getFloat("grade"));
}
// 第七步 關(guān)閉JDBC對(duì)象
rs.close();
stmt.close();
conn.close();
}
}
注:
第一步 加載注冊(cè)JDBC的驅(qū)動(dòng)類(lèi) Class.forName("com.mysql.jdbc.Driver"); 不同數(shù)據(jù)庫(kù)不一樣(這里用的是mysql) 需要其他數(shù)據(jù)庫(kù)的話 直接去查即可
stmt.executeQuery 返回一個(gè)結(jié)果集 用于查詢(xún)
關(guān)鍵語(yǔ)句:
ResultSet rs = stmt.executeQuery("select * from student");
另外要注意第七步關(guān)閉順序(反著來(lái))
上面代碼版本異常處理為main函數(shù)處拋出:
public static void main(String[] args) throws Exception { }
這種做法不好,若后面代碼中間一旦異常停止
則其后面的代碼不會(huì)執(zhí)行翠拣。
改進(jìn)的版本:(增加try catch)
import java.sql.*;
public class TestJDBC {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
// 第一步 先加載JDBC的驅(qū)動(dòng)類(lèi)
Class.forName("com.mysql.jdbc.Driver");
// 第二步 提供JDBC連接的url
String url = "jdbc:mysql://localhost:3306/itcast";
String username = "root";
String password = "root";
// 第三步 創(chuàng)建數(shù)據(jù)庫(kù)的連接
conn = DriverManager.getConnection(url, username, password);
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
stmt = conn.createStatement();
// 第五步 執(zhí)行sql語(yǔ)句 獲取結(jié)果集合
rs = stmt.executeQuery("select * from student");
// 第六步 循環(huán)遍歷結(jié)果集 處理
while(rs.next()) {
System.out.println(rs.getString("name"));
System.out.println(rs.getFloat("grade"));
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
// 還要進(jìn)行寫(xiě)入日志操作
}catch(SQLException e) {
e.printStackTrace();
System.out.println("SQLException");
}finally{
try{
// 第七步 關(guān)閉JDBC對(duì)象 釋放資源
rs.close();
stmt.close();
conn.close();
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
首先是try后兩個(gè)catch分支 分別處理不同異常版仔,try catch后的finally里執(zhí)行關(guān)閉JDBC對(duì)象操作(此更符合事件處理邏輯)
又考慮到對(duì)象rs stmt為空關(guān)閉會(huì)導(dǎo)致異常
改進(jìn)finally中處理辦法:
...
}finally{
try{
// 第七步 關(guān)閉JDBC對(duì)象
if(rs != null) {
rs.close();
}
if(stmt != null) {
stmt.close();
}
if(conn != null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
最終較完美代碼:
import java.sql.*;
public class TestJDBC {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
try{
// 第一步 先加載JDBC的驅(qū)動(dòng)類(lèi)
Class.forName("com.mysql.jdbc.Driver");
// 第二步 提供JDBC連接的url
String url = "jdbc:mysql://localhost:3306/itcast";
String username = "root";
String password = "root";
// 第三步 創(chuàng)建數(shù)據(jù)庫(kù)的連接
conn = DriverManager.getConnection(url, username, password);
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
stmt = conn.createStatement();
// 第五步 執(zhí)行sql語(yǔ)句
rs = stmt.executeQuery("select * from student");
// 第六步 循環(huán)遍歷處理結(jié)果
while(rs.next()) {
System.out.println(rs.getString("name"));
System.out.println(rs.getFloat("grade"));
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
// 還要進(jìn)行寫(xiě)入異常操作
}catch(SQLException e) {
e.printStackTrace();
System.out.println("SQLException");
}finally{
try{
// 第七步 關(guān)閉JDBC對(duì)象 釋放資源
if(rs != null) {
rs.close();
}
if(stmt != null) {
stmt.close();
}
if(conn != null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
也可以再優(yōu)化一下結(jié)構(gòu):
import java.sql.*;
public class TestJDBC22 {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
ResultSet rs = null;
String Driver = "com.mysql.jdbc.Driver";
// 對(duì)應(yīng) 第二步
String url = "jdbc:mysql://localhost:3306/itcast";
String username = "root";
String password = "root";
try{
// 第一步 先加載JDBC的驅(qū)動(dòng)類(lèi)
Class.forName(Driver);
// 第二步 提供JDBC連接的url
// 第三步 創(chuàng)建數(shù)據(jù)庫(kù)的連接
conn = DriverManager.getConnection(url, username, password);
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
stmt = conn.createStatement();
// 第五步 執(zhí)行sql語(yǔ)句
rs = stmt.executeQuery("select * from student");
// 第六步 循環(huán)遍歷處理結(jié)果
while(rs.next()) {
System.out.println(rs.getString("name"));
System.out.println(rs.getFloat("grade"));
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
// 還要進(jìn)行寫(xiě)入異常操作
}catch(SQLException e) {
e.printStackTrace();
System.out.println("SQLException");
}finally{
try{
// 第七步 關(guān)閉JDBC對(duì)象 釋放資源
if(rs != null) {
rs.close();
}
if(stmt != null) {
stmt.close();
}
if(conn != null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
重要說(shuō)明:
將:
import java.sql.DriverManager;
import java.sql.ResultSet;
import com.mysql.jdbc.Connection;
import com.mysql.jdbc.Statement;
...
改為:
import java.sql.*;
...
則代碼中很多不用強(qiáng)轉(zhuǎn)類(lèi)型:
不遍歷的話 則大致步驟:
數(shù)據(jù)插入操作代碼:
import java.sql.*;
public class Test {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
// 第一步 先加載JDBC的驅(qū)動(dòng)類(lèi)
Class.forName("com.mysql.jdbc.Driver");
// 第二步 提供JDBC連接的url
String url = "jdbc:mysql://localhost:3306/itcast";
String username = "root";
String password = "root";
// 第三步 創(chuàng)建數(shù)據(jù)庫(kù)的連接
conn = DriverManager.getConnection(url, username, password);
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
stmt = conn.createStatement();
// 第五步 執(zhí)行sql語(yǔ)句
String sql = "insert into student values(0,'七月',23,'男')";
stmt.executeUpdate(sql);
}catch(ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
// 還要進(jìn)行寫(xiě)入日志等操作 所以要分開(kāi)兩個(gè)異常類(lèi)別 都要 catch
}catch(SQLException e) {
e.printStackTrace();
System.out.println("SQLException");
}finally{
try{
// 第六步 關(guān)閉JDBC對(duì)象
if(stmt != null) {
stmt.close();
}
if(conn != null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
批量插入方法:
import java.sql.*;
public class Test {
public static void main(String[] args) {
Connection conn = null;
Statement stmt = null;
try{
// 第一步 先加載JDBC的驅(qū)動(dòng)類(lèi)
Class.forName("com.mysql.jdbc.Driver");
// 第二步 提供JDBC連接的url
String url = "jdbc:mysql://localhost:3306/itcast";
String username = "root";
String password = "root";
// 第三步 創(chuàng)建數(shù)據(jù)庫(kù)的連接
conn = DriverManager.getConnection(url, username, password);
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
stmt = conn.createStatement();
// 第五步 執(zhí)行sql語(yǔ)句
String sql = "insert into student values(0,'七月1',23,'男')";
String sq2 = "insert into student values(0,'八月1',32,'男')";
stmt.addBatch(sql);
stmt.addBatch(sq2);
stmt.executeBatch();
}catch(ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
// 還要進(jìn)行寫(xiě)入日志等操作 所以要分開(kāi)兩個(gè)異常類(lèi)別 都要 catch
}catch(SQLException e) {
e.printStackTrace();
System.out.println("SQLException");
}finally{
try{
// 第六步 關(guān)閉JDBC對(duì)象
if(stmt != null) {
stmt.close();
}
if(conn != null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
此方法中關(guān)鍵語(yǔ)句:
// 執(zhí)行sql語(yǔ)句
String sql = "insert into student values(0,'七月1',23,'男')";
String sq2 = "insert into student values(0,'八月1',32,'男')";
stmt.addBatch(sql);
stmt.addBatch(sq2);
stmt.executeBatch();
用Statement對(duì)象中的addBatch() 函數(shù)方法將SQL命令語(yǔ)句都添加到Batch中 然后用executeBatch() 方法整體將Batch 中的語(yǔ)句提交給數(shù)據(jù)庫(kù)管理系統(tǒng)。
添加兩條數(shù)據(jù)成功:
注:
我們可以使用Statement對(duì)象用來(lái)做測(cè)試 但是在生產(chǎn)環(huán)境下一定要考慮使用 PreparedStatement(見(jiàn)下)
下午
學(xué)習(xí)了 PreparedStatement 對(duì)象误墓,用其可以使得update數(shù)據(jù)更靈活:
import java.sql.*;
public class Test {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 第一步 先加載JDBC的驅(qū)動(dòng)類(lèi)
Class.forName("com.mysql.jdbc.Driver");
// 第二步 提供JDBC連接的url
String url = "jdbc:mysql://localhost:3306/itcast";
String username = "root";
String password = "root";
// 第三步 創(chuàng)建數(shù)據(jù)庫(kù)的連接
conn = DriverManager.getConnection(url, username, password);
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
String sql = "insert into student values(?,?,?,?)";
pstmt = conn.prepareStatement(sql);
// 第五步 執(zhí)行sql語(yǔ)句
pstmt.setInt(1,8);
pstmt.setString(2,"nihao");
pstmt.setFloat(3, 55);
pstmt.setString(4,"男");
pstmt.executeUpdate();
}catch(ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
// 還要進(jìn)行寫(xiě)入日志等操作 所以要分開(kāi)兩個(gè)異常類(lèi)別 都要 catch
}catch(SQLException e) {
e.printStackTrace();
System.out.println("SQLException");
}finally{
try{
// 第六步 關(guān)閉JDBC對(duì)象
if(pstmt != null) {
pstmt.close();
}
if(conn != null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
PreparedStatement 批量insert數(shù)據(jù):
import java.sql.*;
public class TestJDBC {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
try{
// 第一步 先加載JDBC的驅(qū)動(dòng)類(lèi)
Class.forName("com.mysql.jdbc.Driver");
// 第二步 提供JDBC連接的url
String url = "jdbc:mysql://localhost:3306/itcast";
String username = "root";
String password = "root";
// 第三步 創(chuàng)建數(shù)據(jù)庫(kù)的連接
conn = DriverManager.getConnection(url, username, password);
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
String sql = "insert into student values(?,?,?,?)";
pstmt = conn.prepareStatement(sql);
// 第五步 執(zhí)行sql語(yǔ)句
pstmt.setInt(1,9);
pstmt.setString(2,"9");
pstmt.setFloat(3, 55);
pstmt.setString(4,"男");
pstmt.addBatch();
pstmt.setInt(1,10);
pstmt.setString(2,"10");
pstmt.setFloat(3, 68);
pstmt.setString(4,"男");
pstmt.addBatch();
pstmt.executeBatch();
}catch(ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
// 還要進(jìn)行寫(xiě)入日志等操作 所以要分開(kāi)兩個(gè)異常類(lèi)別 都要 catch
}catch(SQLException e) {
e.printStackTrace();
System.out.println("SQLException");
}finally{
try{
// 第六步 關(guān)閉JDBC對(duì)象
if(pstmt != null) {
pstmt.close();
}
if(conn != null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
PreparedStatement 查詢(xún):
import java.sql.*;
public class Test {
public static void main(String[] args) {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
try{
// 第一步 先加載JDBC的驅(qū)動(dòng)類(lèi)
Class.forName("com.mysql.jdbc.Driver");
// 第二步 提供JDBC連接的url
String url = "jdbc:mysql://localhost:3306/itcast";
String username = "root";
String password = "root";
// 第三步 創(chuàng)建數(shù)據(jù)庫(kù)的連接
conn = DriverManager.getConnection(url, username, password);
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
String sql = "select * from student";
pstmt = conn.prepareStatement(sql);
// 第五步 執(zhí)行sql語(yǔ)句 獲取結(jié)果集合
rs = pstmt.executeQuery();
// 第六步 循環(huán)遍歷處理結(jié)果
while(rs.next()){
System.out.println(rs.getInt("id"));
System.out.println(rs.getString("name"));
System.out.println(rs.getInt("age"));
}
}catch(ClassNotFoundException e) {
e.printStackTrace();
System.out.println("ClassNotFoundException");
// 還要進(jìn)行寫(xiě)入日志等操作 所以要分開(kāi)兩個(gè)異常類(lèi)別 都要 catch
}catch(SQLException e) {
e.printStackTrace();
System.out.println("SQLException");
}finally{
try{
// 第七步 關(guān)閉JDBC對(duì)象
if(pstmt != null) {
pstmt.close();
}
if(conn != null) {
conn.close();
}
}catch(SQLException e) {
e.printStackTrace();
}
}
}
}
注意PreparedStatement 和 Statement 創(chuàng)建一個(gè)statement對(duì)象(第4步) 和 執(zhí)行sql語(yǔ)句(第5步)語(yǔ)句的區(qū)別:
Statement:
String sql = "select * from student";
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
stmt = conn.createStatement();
// 第五步 執(zhí)行sql語(yǔ)句
rs = stmt.executeQuery(sql);
PreparedStatement:
String sql = "select * from student";
// 第四步 創(chuàng)建一個(gè)statement對(duì)象
pstmt = conn.prepareStatement(sql);
// 第五步 執(zhí)行sql語(yǔ)句 獲取結(jié)果集合
rs = pstmt.executeQuery();
PreparedStatement優(yōu)勢(shì)絕不僅僅是更靈活的參數(shù)化查詢(xún)
請(qǐng)參見(jiàn):PreparedStatement VS Statement
拓展閱讀:
1 - 通過(guò)JDBC進(jìn)行簡(jiǎn)單的增刪改查(以MySQL為例)
2 - JDBC詳解
世界上所有的追求都是因?yàn)闊釔?ài)
一枚愛(ài)編碼 愛(ài)生活 愛(ài)分享的IT信徒
— hongXkeX