JDBC實(shí)戰(zhàn)教程(一)
一.什么是JDBC
JDBC(Java Data Base Connectivity,java數(shù)據(jù)庫連接)是一種用于執(zhí)行SQL語句的Java API,可以為多種關(guān)系數(shù)據(jù)庫提供統(tǒng)一訪問,它由一組用Java語言編寫的類和接口組成。JDBC提供了一種基準(zhǔn),據(jù)此可以構(gòu)建更高級(jí)的工具和接口,使數(shù)據(jù)庫開發(fā)人員能夠編寫數(shù)據(jù)庫應(yīng)用程序,同時(shí),JDBC也是個(gè)商標(biāo)名
二.JDBC編程步驟
- 下載所需數(shù)據(jù)庫jar包并導(dǎo)入項(xiàng)目
- 加載驅(qū)動(dòng)程序
- 獲取數(shù)據(jù)庫連接
- 創(chuàng)建Statement/PreparedStatement對(duì)象
- 執(zhí)行SQL語句并處理結(jié)果集(ResultSet)
- 關(guān)閉結(jié)果集、關(guān)閉Statement或者PreparedStatement、關(guān)閉數(shù)據(jù)庫連接(Connection)
一. 下載數(shù)據(jù)庫jar包并導(dǎo)入項(xiàng)目
- 創(chuàng)建Java項(xiàng)目
- 在項(xiàng)目下建名為lib一個(gè)文件夾用來放置數(shù)據(jù)庫jar包,并把jar包添加進(jìn)項(xiàng)目構(gòu)建路徑
二. 加載驅(qū)動(dòng)程序
//模式1:Class.forName(dirverClass);
//加載mysql驅(qū)動(dòng)
try {
Class.forName("com.mysql.jdbc.Driver");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
//模式2: System.setProperty(key,value);
//加載驅(qū)動(dòng)
System.setProperty("jdbc.drivers","com.mysql.jdbc.Driver");
//模式3: DriverManager.registerDriver(driverInstance);
DriverManager.registerDriver(new Driver());
三. 獲取數(shù)據(jù)庫連接
//URL模式: jdbc協(xié)議:數(shù)據(jù)庫類型://ip地址:數(shù)據(jù)庫服務(wù)端口號(hào)/數(shù)據(jù)庫名稱?其他參數(shù)
String url = "jdbc:mysql://127.0.0.1:3306/jdbcDatabase?useSSL=false";
String user = "root";
String password = "root";
//獲取數(shù)據(jù)庫連接方式一
Connection con = DriverManage.getConnection(url,user,password);
//獲取數(shù)據(jù)庫連接方式二
MysqlDataSource dataSource = new MysqlDataSource();
dataSource.setUser(user);
dataSource.setPassword(password);
dataSource.setURL(url);
Connection conn = dataSource.getConnection();
四. 創(chuàng)建Statement/PreparedStatement對(duì)象
Statement 對(duì)象用于執(zhí)行不帶參數(shù)的簡單 SQL 語句;PreparedStatement 對(duì)象用于執(zhí)行帶或不帶 IN 參數(shù)的預(yù)編譯 SQL 語句;CallableStatement 對(duì)象用于執(zhí)行對(duì)數(shù)據(jù)庫已存在的存儲(chǔ)過程的調(diào)用。
Statement 接口提供了執(zhí)行語句和獲取結(jié)果的基本方法。PreparedStatement 接口添加了處理 IN 參數(shù)的方法;而 CallableStatement 添加了處理 OUT 參數(shù)的方法。
Statement stmt = con.createStatement();
//靜態(tài)SQL語句,靜態(tài)SQL語句拼接時(shí)可能會(huì)出現(xiàn)[SQL注入](http://baike.baidu.com/link?url=TMixdmoTQFa0cPCrWpPe2cUAA-6HEuKrKu6eeawgyt2MDL93TO1xdBumRkkbTphUB89MjRFx3SLqOAZ2jZgqeMEj5Y7i11YOK3rmOMFj733)
String sql = "select * from company where name like '%科技%'";
boolean isExcute = stmt.excute(sql);
PreparedStatement接口繼承Statement,并與之在兩方面有所不同:PreparedStatement 實(shí)例包含已編譯的 SQL 語句。這就是使語句“準(zhǔn)備好”。包含于 PreparedStatement 對(duì)象中的 SQL 語句可具有一個(gè)或多個(gè) IN 參數(shù)。IN參數(shù)的值在 SQL 語句創(chuàng)建時(shí)未被指定。相反的,該語句為每個(gè) IN 參數(shù)保留一個(gè)問號(hào)(“?”)作為占位符。每個(gè)問號(hào)的值必須在該語句執(zhí)行之前,通過適當(dāng)?shù)膕etXXX 方法來提供。
由于 PreparedStatement 對(duì)象已預(yù)編譯過,所以其執(zhí)行速度要快于 Statement 對(duì)象。因此,多次執(zhí)行的 SQL 語句經(jīng)常創(chuàng)建為 PreparedStatement 對(duì)象,以提高效率。作為 Statement 的子類,PreparedStatement 繼承了 Statement 的所有功能。另外它還添加了一整套方法,用于設(shè)置發(fā)送給數(shù)據(jù)庫以取代 IN 參數(shù)占位符的值。同時(shí),三種方法 execute、 executeQuery 和 executeUpdate 已被更改以使之不再需要參數(shù)。這些方法的 Statement 形式(接受 SQL 語句參數(shù)的形式)不應(yīng)該用于 PreparedStatement 對(duì)象
String sql = "select * from order where code = ? or order_time = ?";
PreparedStatement pstmt = con.preparedStatement(sql);
pstmt.setString(1,"b009_a789_u345_800");
pstmt.setString(2,"2017-04-09");
boolean isExcute = pstmt.excute();
五. 執(zhí)行SQL語句并處理結(jié)果集(ResultSet)
ResultSet rs = pstmt.excuteQuery();
//ResultSet結(jié)果集是通過移動(dòng)游標(biāo)來定位結(jié)果集中是否有記錄,游標(biāo)初始位置位于結(jié)果集表頭,通過next()方法來移動(dòng)游標(biāo)
while(rs.next()){
System.out.println(rs.getString(1)+rs.getInt(2)+rs.getString(3));
}
六. 關(guān)閉結(jié)果集、關(guān)閉Statement或者PreparedStatement、關(guān)閉數(shù)據(jù)庫連接(Connection)
//關(guān)閉結(jié)果集
rs.close();
//關(guān)閉statement
pstmt.close();
//關(guān)閉數(shù)據(jù)庫連接
con.close();
附源碼
package com.zhq.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
public class JdbcLearn {
public static void main(String[] args) {
Connection con = null;
ResultSet rs = null;
PreparedStatement st = null;
try {
//加載驅(qū)動(dòng)
Class.forName("com.mysql.jdbc.Driver");
//獲取數(shù)據(jù)庫連接
String url = "jdbc:mysql://127.0.0.1:3306/qingke";
String user = "root";
String password = "root";
con = DriverManager.getConnection(url, user, password);
String sql = "select * from company where name like ?";
//創(chuàng)建Statement對(duì)象
st = con.prepareStatement(sql);
//設(shè)置SQL語句中占位符的值
st.setString(1,"%科技有限公司%");
//執(zhí)行SQL語句并處理結(jié)果集
rs = st.executeQuery();
while(rs.next()){
System.out.println(rs.getString(1)+rs.getInt(2)+rs.getString(3));
}
} catch (ClassNotFoundException | SQLException e) {
e.printStackTrace();
} finally {
//關(guān)閉結(jié)果集、關(guān)閉Statement或者PreparedStatement、關(guān)閉數(shù)據(jù)庫連接
if (rs != null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(st != null){
try {
st.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if (con != null){
try {
con.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}
}
}