JDBC連接數(shù)據(jù)庫(kù)的流程
是Sun 公司制定的一個(gè)可以用Java 語(yǔ)言連接數(shù)據(jù)庫(kù)的技術(shù)。一、JDBC 基礎(chǔ)知識(shí)JDBC (Java Data Base Connectivity,java數(shù)據(jù)庫(kù)連接)是一種用于執(zhí)行SQL 語(yǔ)句的
是Sun 公司制定的一個(gè)可以用Java 語(yǔ)言連接數(shù)據(jù)庫(kù)的技術(shù)。
一、JDBC 基礎(chǔ)知識(shí)
JDBC (Java Data Base Connectivity,java數(shù)據(jù)庫(kù)連接)是一種用于執(zhí)行SQL 語(yǔ)句的Java API ,可以為多種關(guān)系數(shù)據(jù)庫(kù)提供統(tǒng)一訪(fǎng)問(wèn),它由一組用Java 語(yǔ)言編寫(xiě)的類(lèi)和接口組成。JDBC 為數(shù)據(jù)庫(kù)開(kāi)發(fā)人員提供了一個(gè)標(biāo)準(zhǔn)的API ,據(jù)此可以構(gòu)建更高級(jí)的工具和接口,使數(shù)據(jù)庫(kù)開(kāi)發(fā)人員能夠用純 Java API 編寫(xiě)數(shù)據(jù)庫(kù)應(yīng)用程序,并且可跨平臺(tái)運(yùn)行,并且不受數(shù)據(jù)庫(kù)供應(yīng)商的限制。
1、跨平臺(tái)運(yùn)行:這是繼承了Java 語(yǔ)言的“一次編譯,到處運(yùn)行”的特點(diǎn);
2、不受數(shù)據(jù)庫(kù)供應(yīng)商的限制:巧妙在于JDBC 設(shè)有兩種接口,一個(gè)是面向應(yīng)用程序?qū)?,其作用是使得開(kāi)發(fā)人員通過(guò)SQL 調(diào)用數(shù)據(jù)庫(kù)和處理結(jié)果,而不需要考慮數(shù)據(jù)庫(kù)的提供商;另一個(gè)是驅(qū)動(dòng)程序?qū)樱幚砼c具體驅(qū)動(dòng)程序的交互,JDBC 驅(qū)動(dòng)程序可以利用JDBC API 創(chuàng)建Java 程序和數(shù)據(jù)源之間的橋梁。應(yīng)用程序只需要編寫(xiě)一次,便可以移到各種驅(qū)動(dòng)程序上運(yùn)行。Sun 提供了一個(gè)驅(qū)動(dòng)管理器,數(shù)據(jù)庫(kù)供應(yīng)商——如MySQL 、Oracle ,提供的驅(qū)動(dòng)程序滿(mǎn)足驅(qū)動(dòng)管理器的要求就可以被識(shí)別,就可以正常工作。所以JDBC 不受數(shù)據(jù)庫(kù)供應(yīng)商的限制。
JDBC API可以作為連接Java 應(yīng)用程序與各種關(guān)系數(shù)據(jù)庫(kù)的紐帶,在帶來(lái)方便的同時(shí)也有負(fù)面影響,以下是JDBC 的優(yōu)、缺點(diǎn)。優(yōu)點(diǎn)如下:
操作便捷:JDBC 使得開(kāi)發(fā)人員不需要再使用復(fù)雜的驅(qū)動(dòng)器調(diào)用命令和函數(shù);
可移植性強(qiáng):JDBC 支持不同的關(guān)系數(shù)據(jù)庫(kù),所以可以使同一個(gè)應(yīng)用程序支持多個(gè)數(shù)據(jù)庫(kù)的訪(fǎng)問(wèn),只要加載相應(yīng)的驅(qū)動(dòng)程序即可;
通用性好:JDBC-ODBC 橋接驅(qū)動(dòng)器將JDBC 函數(shù)換成ODBC ;
面向?qū)ο螅嚎梢詫⒊S玫腏DBC 數(shù)據(jù)庫(kù)連接封裝成一個(gè)類(lèi),在使用的時(shí)候直接調(diào)用即可。
缺點(diǎn)如下:
訪(fǎng)問(wèn)數(shù)據(jù)記錄的速度受到一定程度的影響;
更改數(shù)據(jù)源困難:JDBC 可支持多種數(shù)據(jù)庫(kù),各種數(shù)據(jù)庫(kù)之間的操作必有不同,這就給更改數(shù)據(jù)源帶來(lái)了很大的麻煩
二、JDBC 連接數(shù)據(jù)庫(kù)的流程及其原理
1、在開(kāi)發(fā)環(huán)境中加載指定數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序。例如,接下來(lái)的實(shí)驗(yàn)中,使用的數(shù)據(jù)庫(kù)是Oracle ,所以需要去下載Oracle 支持JDBC 的驅(qū)動(dòng)程序(其實(shí)這個(gè)地方并不需要去官網(wǎng)上下載jdbc 驅(qū)動(dòng),本地安裝的Oracle 中就有,是一個(gè)ojdbc14.jar 的文件) ;而開(kāi)發(fā)環(huán)境是MyEclipse ,將下載得到的驅(qū)動(dòng)程序加載進(jìn)開(kāi)發(fā)環(huán)境中(具體示例的時(shí)候會(huì)講解如何加載) 。
2、在Java 程序中加載驅(qū)動(dòng)程序。在Java 程序中,可以通過(guò) “Class.forName(“指定數(shù)據(jù)庫(kù)的驅(qū)動(dòng)程序”) ” 方式來(lái)加載添加到開(kāi)發(fā)環(huán)境中的驅(qū)動(dòng)程序,例如加載Oracle 的數(shù)據(jù)驅(qū)動(dòng)程序的代碼為: Class.forName(“oracle.jdbc.driver.OracleDriver ”)
1
,3、創(chuàng)建數(shù)據(jù)連接對(duì)象:通過(guò)DriverManager 類(lèi)創(chuàng)建數(shù)據(jù)庫(kù)連接對(duì)象Connection 。DriverManager 類(lèi)作用于Java 程序和JDBC 驅(qū)動(dòng)程序之間,用于檢查所加載的驅(qū)動(dòng)程序是否可以建立連接,然后通過(guò)它的getConnection 方法,根據(jù)數(shù)據(jù)庫(kù)的URL 、用戶(hù)名和密碼,創(chuàng)建一個(gè)JDBC Connection 對(duì)象。如:Connection connection = DriverManager.geiConnection(“連接數(shù)據(jù)庫(kù)的URL", "用戶(hù)名", "密碼”) 。其中,URL=協(xié)議名 IP地址(域名) 端口 數(shù)據(jù)庫(kù)名稱(chēng);用戶(hù)名和密碼是指登錄數(shù)據(jù)庫(kù)時(shí)所使用的用戶(hù)名和密碼, 具體示例創(chuàng)建Oracle 的數(shù)據(jù)庫(kù)連接代碼如下: conn=DriverManager.getConnection(url, user, password);
4、創(chuàng)建Statement 對(duì)象:Statement 類(lèi)的主要是用于執(zhí)行靜態(tài) SQL 語(yǔ)句并返回它所生成結(jié)果的對(duì)象。通過(guò)Connection 對(duì)象的 createStatement()方法可以創(chuàng)建一個(gè)Statement 對(duì)象。例如:Statement statament = connection.createStatement(); 具體示例創(chuàng)建Statement 對(duì)象代碼如下:
Statement statamentMySQL =connectMySQL.createStatement();
5、調(diào)用Statement 對(duì)象的相關(guān)方法執(zhí)行相對(duì)應(yīng)的 SQL 語(yǔ)句:通過(guò)execuUpdate()方法用來(lái)數(shù)據(jù)的更新,包括插入和刪除等操作,例如向staff 表中插入一條數(shù)據(jù)的代碼:
statement.excuteUpdate( "INSERT INTO staff(name, age, sex,address, depart, worklen,wage)" " VALUES ('Tom1', 321, 'M', 'china','Personnel','3','3000' ) ") ;
通過(guò)調(diào)用Statement 對(duì)象的executeQuery()方法進(jìn)行數(shù)據(jù)的查詢(xún),而查詢(xún)結(jié)果會(huì)得到 ResulSet 對(duì)象,ResulSet 表示執(zhí)行查詢(xún)數(shù)據(jù)庫(kù)后返回的數(shù)據(jù)的集合,ResulSet 對(duì)象具有可以指向當(dāng)前數(shù)據(jù)行的指針。通過(guò)該對(duì)象的next()方法,使得指針指向下一行,然后將數(shù)據(jù)以列號(hào)或者字段名取出。如果當(dāng)next()方法返回null ,則表示下一行中沒(méi)有數(shù)據(jù)存在。使用示例代碼如下:
ResultSet resultSel = statement.executeQuery( "select * from staff" );
6、關(guān)閉數(shù)據(jù)庫(kù)連接:使用完數(shù)據(jù)庫(kù)或者不需要訪(fǎng)問(wèn)數(shù)據(jù)庫(kù)時(shí),通過(guò)Connection 的close() 方法及時(shí)關(guān)閉數(shù)據(jù)連接。
三、JDBC 應(yīng)用示例實(shí)驗(yàn)
實(shí)驗(yàn) 步驟:
S1、下載ojdbc14.jar 驅(qū)動(dòng)文件,并將該文件放到你的項(xiàng)目中去;
S2、在MyEclipse 中的項(xiàng)目中添加Oracle 驅(qū)動(dòng)程序:在項(xiàng)目名上右鍵-> Build Path ->Add External Archiver 然后選擇你剛才放在項(xiàng)目中的文件, 點(diǎn)確定即可。
S3、打開(kāi)Oracle 的各項(xiàng)服務(wù),并在Oracle 中建一張表。
S4、編寫(xiě)MyEclipse 與Oracle 的連接程序:
[cpp] view plaincopyprint?import java.sql.Connection; import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.* ;
2
,public class JDBC_Test {
//orcl為oracle 數(shù)據(jù)庫(kù)中的數(shù)據(jù)庫(kù)名,localhost 表示連接本機(jī)的oracle 數(shù)據(jù)庫(kù) //1521為連接的端口號(hào)
private static String url="jdbc:oracle:thin:@localhost:1521:orcl";
//system為登陸oracle 數(shù)據(jù)庫(kù)的用戶(hù)名
private static String user="system";
//manager為用戶(hù)名system 的密碼
private static String password="manager";
public static Connection conn;
public static PreparedStatement ps;
public static ResultSet rs;
public static Statement st ;
//連接數(shù)據(jù)庫(kù)的方法
public void getConnection(){
try {
//初始化驅(qū)動(dòng)包
Class.forName("oracle.jdbc.driver.OracleDriver");
//根據(jù)數(shù)據(jù)庫(kù)連接字符,名稱(chēng),密碼給conn 賦值
conn=DriverManager.getConnection(url, user, password);
} catch (Exception e) {
// TODO: handle exception
e.printStackTrace();
}
}
//測(cè)試能否與oracle 數(shù)據(jù)庫(kù)連接成功
public static void main(String[] args) {
JDBC_Test basedao=new JDBC_Test();
basedao.getConnection();
if(conn==null){
System.out.println("與oracle 數(shù)據(jù)庫(kù)連接失敗!");
}else{
System.out.println("與oracle 數(shù)據(jù)庫(kù)連接成功!");
}
}
}
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.* ;
3
,public class JDBC_Test {
//orcl為oracle 數(shù)據(jù)庫(kù)中的數(shù)據(jù)庫(kù)名,localhost 表示連接本機(jī)的oracle 數(shù)據(jù)庫(kù) //1521為連接的端口號(hào)
private static String url="jdbc:oracle:thin:@localhost:1521:orcl";
//system為登陸oracle 數(shù)據(jù)庫(kù)的用戶(hù)名 private static String user="system"; //manager為用戶(hù)名system 的密碼 private static String password="manager"; public static Connection conn; public static PreparedStatement ps; public static ResultSet rs; public static Statement st ; //連接數(shù)據(jù)庫(kù)的方法 public void getConnection(){ try { //初始化驅(qū)動(dòng)包 Class.forName("oracle.jdbc.driver.OracleDriver"); } //根據(jù)數(shù)據(jù)庫(kù)連接字符,名稱(chēng),密碼給conn 賦值 conn=DriverManager.getConnection(url, user, password); } catch (Exception e) { // TODO: handle exception e.printStackTrace(); } //測(cè)試能否與oracle 數(shù)據(jù)庫(kù)連接成功 public static void main(String[] args) { JDBC_Test basedao=new JDBC_Test(); basedao.getConnection(); if(conn==null){ System.out.println("與oracle 數(shù)據(jù)庫(kù)連接失??!"); }else{
System.out.println("與oracle 數(shù)據(jù)庫(kù)連接成功!");
}
}
}
S5、如果上述的連接已經(jīng)建立,就可以利用JDBC 中的Java API 對(duì)數(shù)據(jù)庫(kù)進(jìn)行操作了,具體的查詢(xún),插入,刪除,更新操作如下:
[cpp] view plaincopyprint?代碼轉(zhuǎn)載自:http://blog.csdn.net/cxwen78/article/details/6863696
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
4
,import java.sql.SQLException;
import java.sql.Statement;
public class JDBC_Test {
// 創(chuàng)建靜態(tài)全局變量
static Connection conn;
static Statement st;
public static void main(String[] args) {
insert(); //插入添加記錄
update(); //更新記錄數(shù)據(jù)
delete(); //刪除記錄
query(); //查詢(xún)記錄并顯示
}
/* 插入數(shù)據(jù)記錄,并輸出插入的數(shù)據(jù)記錄數(shù)*/
public static void insert() {
conn = getConnection(); // 首先要獲取連接,即連接到數(shù)據(jù)庫(kù)
try {
String sql = "INSERT INTO staff(name, age, sex,address, depart, worklen,wage)" " VALUES ('Tom1', 32, 'M', 'china','Personnel','3','3000')"; // 插入數(shù)據(jù)的sql 語(yǔ)句
st = (Statement) conn.createStatement(); // 創(chuàng)建用于執(zhí)行靜態(tài)sql 語(yǔ)句的Statement 對(duì)象
int count = st.executeUpdate(sql); // 執(zhí)行插入操作的sql 語(yǔ)句,并返回插入數(shù)據(jù)的個(gè)數(shù)
System.out.println("向staff 表中插入 " count " 條數(shù)據(jù)"); //輸出插入操作的處理結(jié)果
conn.close(); //關(guān)閉數(shù)據(jù)庫(kù)連接
} catch (SQLException e) {
System.out.println("插入數(shù)據(jù)失敗" e.getMessage());
}
}
/* 更新符合要求的記錄,并返回更新的記錄數(shù)目*/
public static void update() {
5
,conn = getConnection(); //同樣先要獲取連接,即連接到數(shù)據(jù)庫(kù)
try {
String sql = "update staff set wage='2200' where name = 'lucy'";// 更新數(shù)據(jù)的sql 語(yǔ)句
st = (Statement) conn.createStatement(); //創(chuàng)建用于執(zhí)行靜態(tài)sql 語(yǔ)句的Statement 對(duì)象,st 屬局部變量
int count = st.executeUpdate(sql);// 執(zhí)行更新操作的sql 語(yǔ)句,返回更新數(shù)據(jù)的個(gè)數(shù)
System.out.println("staff表中更新 " count " 條數(shù)據(jù)"); //輸出更新操作的處理結(jié)果
conn.close(); //關(guān)閉數(shù)據(jù)庫(kù)連接
} catch (SQLException e) {
System.out.println("更新數(shù)據(jù)失敗");
}
}
/* 查詢(xún)數(shù)據(jù)庫(kù),輸出符合要求的記錄的情況*/
public static void query() {
conn = getConnection(); //同樣先要獲取連接,即連接到數(shù)據(jù)庫(kù)
try {
String sql = "select * from staff"; // 查詢(xún)數(shù)據(jù)的sql 語(yǔ)句
st = (Statement) conn.createStatement(); //創(chuàng)建用于執(zhí)行靜態(tài)sql 語(yǔ)句的Statement 對(duì)象,st 屬局部變量
ResultSet rs = st.executeQuery(sql); //執(zhí)行sql 查詢(xún)語(yǔ)句,返回查詢(xún)數(shù)據(jù)的結(jié)果集
System.out.println("最后的查詢(xún)結(jié)果為:");
while (rs.next()) { // 判斷是否還有下一個(gè)數(shù)據(jù)
// 根據(jù)字段名獲取相應(yīng)的值
String name = rs.getString("name");
int age = rs.getInt("age");
String sex = rs.getString("sex");
String address = rs.getString("address");
String depart = rs.getString("depart");
String worklen = rs.getString("worklen");
String wage = rs.getString("wage");
6
,//輸出查到的記錄的各個(gè)字段的值
System.out.println(name " " age " " sex " " address
" " depart " " worklen " " wage);
}
conn.close(); //關(guān)閉數(shù)據(jù)庫(kù)連接
} catch (SQLException e) {
System.out.println("查詢(xún)數(shù)據(jù)失敗");
}
}
/* 刪除符合要求的記錄,輸出情況*/
public static void delete() {
conn = getConnection(); //同樣先要獲取連接,即連接到數(shù)據(jù)庫(kù)
try {
String sql = "delete from staff where name = 'lili'";// 刪除數(shù)據(jù)的sql 語(yǔ)句 st = (Statement) conn.createStatement(); //創(chuàng)建用于執(zhí)行靜態(tài)sql 語(yǔ)句的Statement 對(duì)象,st 屬局部變量
int count = st.executeUpdate(sql);// 執(zhí)行sql 刪除語(yǔ)句,返回刪除數(shù)據(jù)的數(shù)量
System.out.println("staff表中刪除 " count " 條數(shù)據(jù)n"); //輸出刪除操作的處理結(jié)果
conn.close(); //關(guān)閉數(shù)據(jù)庫(kù)連接
} catch (SQLException e) {
System.out.println("刪除數(shù)據(jù)失敗");
}
}
/* 獲取數(shù)據(jù)庫(kù)連接的函數(shù)*/
public static Connection getConnection() {
Connection con = null; //創(chuàng)建用于連接數(shù)據(jù)庫(kù)的Connection 對(duì)象
try {
Class.forName("com.mysql.jdbc.Driver");// 加載Mysql 數(shù)據(jù)驅(qū)動(dòng)
con = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/myuser", "root", "root");// 創(chuàng)建數(shù)據(jù)連接
} catch (Exception e) {
System.out.println("數(shù)據(jù)庫(kù)連接失敗" e.getMessage());
}
return con; //返回所建立的數(shù)據(jù)庫(kù)連接
}
}
7