好快,已經是12月份了,11月5日開的班。就快學習一個月了,總學習時間是四個月。過年休息9天,這樣到明年3月14日課程就結束了。好好學習,回去找個好工作!
今日是JDBC的第一天,JDBC的基礎應用。以后在WEB開發中的使用方式。課程中,方老師上午在講解JDBC基礎的同時做了一個JDBC練習程序,對JDBC的基礎應用。下午,方老師做了一個使用數據庫的WEB應用,用戶注冊、登錄、用戶信息修改。
先讓我們來了解一下JDBC(Java Data Base Connectivity)基礎吧!
我們都知道數據庫都提供一些接口,用戶使用這些接口操作數據庫。這就是數據庫驅動!常見的數據庫有MySQL、Oracle、SQLServer、DB2等,這些數據庫提供的接口都不一樣,難道開發人員使用不同的數據庫就要學習不同的驅動接口嗎?JDBC正是為統一數據庫訪問接口而實現的,SUN公司提出了這一接口。數據庫公司都去實現這一接口。大大方便了,編程人員對數據庫的操作:
在工程中使用JDBC,必須導入相應的JAR包。比如使用MySQL數據庫,必須導入MySQL實現的JDBC jar包??梢缘?a >http://dev.mysql.com/downloads/下載。
使用JDCB進行數據訪問的基本流程,見代碼:
隱藏行號 復制代碼 ? 這是一段程序代碼。
-
import java.sql.Connection;
-
import java.sql.DriverManager;
-
import java.sql.ResultSet;
-
import java.sql.SQLException;
-
import java.sql.Statement;
-
-
public class JDBCTemp {
-
-
public static void main(String[] main) throws Exception {
-
// 1.裝
-
DriverManager.registerDriver(new com.mysql.jdbc.Driver());
-
/*
-
* 因om.mysql.jdbc.Driver在
-
* 上om.mysql.jdbc.Driver,
-
* 所
-
*/
-
Class.forName("com.mysql.jdbc.Driver");
-
// 2.連
-
Connection conn = DriverManager.getConnection(
-
"jdbc:mysql://localhost:3306/databasename", "username",
-
"password");
-
// 3.創QL語tatement對
-
Statement sta = conn.createStatement();
-
// 4.執QL語
-
boolean ok = sta.execute("select * from user;");
-
-
// 5.遍
-
ResultSet rs = null;
-
if(ok){
-
rs = sta.getResultSet();
-
while(rs.next()){
-
rs.getInt(1);
-
//...
-
}
-
}
-
-
// 6.釋esultSet、tatement、onnection這
-
// 必
-
// 下
-
if(rs != null){
-
try {
-
rs.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
rs = null;
-
}
-
-
if(sta != null){
-
try {
-
sta.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
sta = null;
-
}
-
-
if(conn != null){
-
try {
-
conn.close();
-
} catch (SQLException e) {
-
e.printStackTrace();
-
}
-
conn = null;
-
}
-
}
-
}
-
上面的代碼只為演示,繼續向下學習就會發現其中的一些問題。
其中
DriverManager.getConnection("jdbc:mysql://localhost:3306/databasename", "username","password");
|
GetConnection的第一個參數“jdbc:mysql://localhost:3306/databasename
”,它的各段含義如下:
Jdbc:協議
Mysql:子協議
localhost:主機
3306:端口
databasename:數據庫名
常見的URL如下:
Oracle :jdbc:oracle:thin:@localhost:1521:sid
SQLServer:jdbc:microsoft:sqlserver//localhost:1433; DatabaseName=sid
MYSQL:jdbc:mysql://localhost:3306/sid
如果把上面的代碼用于用戶登錄或查詢數據時,會造成一個嚴重的安全漏洞——SQL注入!
例,根據提交的用戶名查找用戶:
"select id,name,password from user where name='"+name+"'";
|
如果用戶提交的用戶名是:“’ or 1=1 or 1=‘”,會發生什么問題?因為在where過濾時使用了or邏輯,其有的1=1返回真,結果可以正常通過驗證。這是一個十分嚴重的安全漏洞!
為此Java為我們提供了PreparedStatement接口,表示預編譯的 SQL 語句的對象。SQL 語句被預編譯并存儲在 PreparedStatement 對象中,然后可以使用此對象多次高效地執行該語句。PreparedStatement的使用:
PreparedStatement ps = conn.prepareStatement("select id,name,password form user where name=? and passowrd=?");
ps.setString(1, name);
ps.setString(2, password);
|
這樣就可以解決SQL注入的漏洞,同時也可以高效的執行SQL語句。上面的使用方法一眼就看出來了,一個“?”對應下邊的ps.setXXX方法,按照“?”先后,對應ps.setXXX第一個參數的索引!
我們使用Statement. execute執行了查詢語句,Statement還有其他以execute開頭的方法,具體針對查詢和增加、刪除、修改的方法,在此就不一一說明了。JDK手冊里邊有詳細說明。
查詢成功后,在Statement對象中,可以獲得記錄集對象ResultSet,查詢的結果全都保存在ResultSet中嗎?仔細想想,好像是。如果有1億條記錄符合查詢條件,同時有1000個用戶調用同一查詢,那服務器不燒了嗎!所以查詢的結果并未保存在ResultSet中,而是保存在數據庫中,ResultSet指向數據庫的引用。這樣很方便也很快捷!那數據庫會不會被充爆了?當然不會,數據本身就保存在數據庫中,數據庫的查詢結果頂多就保存的指向數據的“指針”。
ResultSet對象內部有一個游標,游標初始位置是第一條記錄前。必須調用它的next()方法,才會到第一條記錄,依次向下。如果不存在記錄,或者已經到記錄尾,則返回false。存在記錄返回true。然后我們可以通過調用它的getObject、getInt、getString…方法調用相應的值,如果只使用getObject獲取記錄值,必須使用強轉將它轉換為我們需要的類型。
下面是常用數據類型轉換表(老方整理的,嘿嘿):
SQL類型
|
Jdbc對應方法
|
返回類型
|
BIT
|
getBoolean()
|
Boolean
|
TINYINT
|
getByte()
|
Byte
|
SMALLINT
|
getShort()
|
Short
|
int
|
getInt()
|
Int
|
BIGINT
|
getLong()
|
Long
|
CHAR,VARCHAR,LONGVARCHAR
|
getString()
|
String
|
Text Blob
|
getColb() getBlob()
|
Clob blob
|
DATE
|
getDate()
|
Java.sql.Date
|
TIME
|
getTime()
|
Java.sql.Time
|
TIMESTAMP
|
getTimestamp()
|
Java.sql.Timestamp
|
關于使用JDBC進行CURD的操作比較簡單,因為昨天已經學習了在控制臺有使用這些操作,在此就不多進行復習了。但一定要記住每次使用完數據庫連接時,一定要釋放。一是因為數據庫有同時連接數量限制,二是因為數據連接會占用服務器資源。安全釋放這些連接,參看上邊的釋放代碼。常規的項目開發中,會將對數據庫的操作封裝到一個類中,這樣方便使用。
在常規項目開發中,我們需要編寫操作數據的DAO類。因為對數據庫的一些操作需要處理異常,為了查錯直觀一些。我們在環繞這些異常時,將它們包裝一下再拋出。如何包裝異常?JAVA的包裝類很多,我們的包裝也是通過這個方法實現的。編寫一個繼承處Exception類的子類,然后將接收的異常存到父親類中,我們也可以在自定義類中添加些自己的提示信息。這樣當程序運行時拋出的異常,可以直觀的定位到錯誤類。這是一個十分好的方法,用在其他地方。也有相當的功效!
最后一個問題,數據庫中的中文亂碼問題。其實并不是數據庫的原因 ,因為我們在創建數據庫時可以指定它的編碼為utf8、gb2312或gbk等支持中文的編碼。WEB應用讀寫數據庫時造成的亂碼,主要是由于WEB應用使用的編碼與數據庫使用的編碼不統一。統一一下,就可以解決了!
老方有給大家留作業,今天的作業內容較多。主要是為了練習數據庫的操作和數據庫與WEB的組合應用。之前都是使用XML或配置文件做為偽數據庫與WEB組合練習的,從今天起用上數據庫了。雖然并不是十分興奮,但離框架和項目練習越來越近了,這讓我感覺很好!
以前并未使用JAVA開發過項目,雖然學習JAVA對我已經沒什么難度。但上課這些天來,有時用到IO和集合,還是讓我卡了一下。因為我并未系統的學習過它們,我應該系統的學習一下它們了。越是學習應該越是快樂,越學習應該越是簡單。沒有學習基礎那么枯燥,就圍繞那基礎搞來搞去,用起來了才舒服。因為基礎學習好了,所以感覺應用就簡單的。其實應用并不簡單,即使不說基礎,應用中的模式與框架是相當重要的,有使用過程語言開發的同志,我想對此有很大的感想!
我要學好項目的架構,文檔的編寫與項目管理,這在以后工作中是相當重要的。