JDBC
一啼染、JDBC介紹【Java DataBase Connectivity】
JDBC規(guī)范定義接口雄家,具體的實(shí)現(xiàn)由各大數(shù)據(jù)庫(kù)廠商來實(shí)現(xiàn)般又。
JDBC是Java訪問關(guān)系型數(shù)據(jù)庫(kù)的標(biāo)準(zhǔn)規(guī)范接口敛劝,真正怎么操作數(shù)據(jù)庫(kù)還需要具體的實(shí)現(xiàn)類,也就是數(shù)據(jù)庫(kù)驅(qū)動(dòng)绊序,數(shù)據(jù)庫(kù)驅(qū)動(dòng)由數(shù)據(jù)庫(kù)廠商提供對(duì)應(yīng)的jar包硕舆。每個(gè)數(shù)據(jù)庫(kù)廠商根據(jù)自家數(shù)據(jù)庫(kù)的通信格式編寫好自己數(shù)據(jù)庫(kù)的驅(qū)動(dòng)。所以我們只需要使用多態(tài)方式調(diào)用 JDBC 接口中的方法即可骤公。
1. 使用JDBC的好處
- 調(diào)用JDBC接口中的方法抚官,即可開發(fā)訪問數(shù)據(jù)庫(kù)的程序。
- 使用同一套 Java 代碼阶捆,進(jìn)行少量的修改就可以訪問其他 JDBC 支持的數(shù)據(jù)庫(kù)
2. 使用JDBC開發(fā)使用到的包
包 | 說明 |
---|---|
java.sql | 所有與JDBC訪問數(shù)據(jù)庫(kù)相關(guān)的接口和類 |
javax.sql | 數(shù)據(jù)庫(kù)擴(kuò)展包凌节,提供數(shù)據(jù)庫(kù)額外的功能。如:連接池 |
數(shù)據(jù)庫(kù)的驅(qū)動(dòng) | 由各大數(shù)據(jù)庫(kù)廠商提供趁猴,需要額外去下載刊咳,是對(duì)JDBC接口實(shí)現(xiàn)的類 |
3. JDBC的核心API
通過數(shù)據(jù)庫(kù)廠商提供的DriverManager類彪见,使用接口以多態(tài)的形式調(diào)用對(duì)應(yīng)的實(shí)現(xiàn)類儡司!
接口或類 | 作用 |
---|---|
DriverManager類 | 管理和注冊(cè)數(shù)據(jù)庫(kù)驅(qū)動(dòng);得到數(shù)據(jù)庫(kù)連接對(duì)象Connection 的實(shí)現(xiàn)類 |
Connection接口 | 一個(gè)連接對(duì)象余指,可用于創(chuàng)建Statement和PreparedStatement對(duì)象 |
Statement接口 | 一個(gè)SOL語(yǔ)句對(duì)象捕犬,用于將SQL語(yǔ)句發(fā)送給數(shù)據(jù)庫(kù)服務(wù)器 |
PreparedStatement接口 | 一個(gè)SQL語(yǔ)句對(duì)象,是Statement的子接口 |
ResultSet接口 | 用于封裝數(shù)據(jù)庫(kù)查詢的結(jié)果集酵镜,返回給客戶端Java程序 |
- 使用時(shí)需要相關(guān)jar導(dǎo)入包添加成庫(kù)碉碉!
右鍵工程--new Directory 文件夾 lib--復(fù)制jar包到此路徑下--右擊該包--Add as Library...
4. 加載和注冊(cè)驅(qū)動(dòng)
加載注冊(cè)驅(qū)動(dòng)就是手動(dòng)通過類加載器將驅(qū)動(dòng)類com.mysql.jdbc.Driver.class文件【內(nèi)部會(huì)加載其他相關(guān)聯(lián)的.class文件<DriverManager.registerDriver(new Driver())注冊(cè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)>】加載到JVM的方法區(qū),以便使用淮韭!
加載和注冊(cè)驅(qū)動(dòng)的方法 | 描述 |
---|---|
Class.forName(數(shù)據(jù)庫(kù)驅(qū)動(dòng)實(shí)現(xiàn)類) | 加載和注冊(cè)數(shù)據(jù)庫(kù)驅(qū)動(dòng)垢粮,數(shù)據(jù)庫(kù)驅(qū)動(dòng)有mysql廠商提供,"com.mysql.jdbc.Driver" |
Class.forName("com.mysql.jdbc.Driver");
從 JDBC3 開始靠粪,目前已經(jīng)普遍使用的版本蜡吧『硫荆可以不用注冊(cè)驅(qū)動(dòng)而直接使用。Class.forName這句話可以省略昔善。
二元潘、DriverManager類
- DriverManager作用:
- 管理和注冊(cè)驅(qū)動(dòng)
- 創(chuàng)建數(shù)據(jù)庫(kù)的連接
1.類中的方法
-
Connection getConnection(String url,String user,String password)
:通過連接字符串,用戶名君仆,密碼來得到數(shù)據(jù)庫(kù)的連接對(duì)象翩概。 -
Connection getConnection(String url,Properties info)
:通過連接字符串,屬性對(duì)象來得到連接對(duì)象返咱。
2.使用JDBC連接數(shù)據(jù)庫(kù)的四個(gè)參數(shù)
- 用戶名:登錄的用戶名
- 密碼:登錄的密碼
-
連接字符串URL:不同的數(shù)據(jù)庫(kù)URL是不同的钥庇,mysql的寫法
jdbc:mysql://localhost:3306/數(shù)據(jù)庫(kù)[?參數(shù)名=參數(shù)值]
- 連接數(shù)據(jù)庫(kù)的URL地址格式:
協(xié)議名:子協(xié)議://服務(wù)器名或者IP地址:端口號(hào)/數(shù)據(jù)庫(kù)名?參數(shù)=參數(shù)值
-
MySQL寫法
jdbc:mysql://localhost:3306/test?參數(shù)=參數(shù)值
--|--------|----------|----------|-------|
協(xié)議-子協(xié)議 主機(jī)IP: 端口 數(shù)據(jù)庫(kù) -
簡(jiǎn)寫形式【必須是本地服務(wù)器,端口號(hào)是3306】
jdbc:mysql:///數(shù)據(jù)庫(kù)名
亂碼的處理
如果數(shù)據(jù)庫(kù)出現(xiàn)亂碼洛姑,可以指定參數(shù): ?characterEncoding=utf8上沐,表示讓數(shù)據(jù)庫(kù)以 UTF-8 編碼來處理數(shù)據(jù)。
jdbc:mysql://localhost:3306/數(shù)據(jù)庫(kù)?characterEncoding=utf8
3.案例演示
- 使用用戶名楞艾、密碼参咙、RUL得到連接對(duì)象
String url = "jdbc:mysql://localhost:3306/jdbclearn";
Connection connection = DriverManager.getConnection(url,"root","abc123");
System.out.println(connection);
connection.close();
- 使用屬性文件和url得到連接對(duì)象
String url = "jdbc:mysql://localhost:3306/jdbclearn";
Properties info = new Properties();
info.setProperty("user", "root");
info.setProperty("password", "abc123");
Connection connection = DriverManager.getConnection(url,info);
System.out.println(connection);
connection.close();
三、Connection接口
Connection接口作用: 具體的實(shí)現(xiàn)由數(shù)據(jù)庫(kù)的廠商實(shí)現(xiàn)硫眯,代表一個(gè)連接對(duì)象蕴侧。
1.Connection接口中的方法
-
Statement createStatement()
: 創(chuàng)建一條SQL語(yǔ)句對(duì)象
四、Statement接口
1.JDBC訪問數(shù)據(jù)庫(kù)的步驟
- 注冊(cè)和加載驅(qū)動(dòng)(可以省略)两入。
- 獲取連接對(duì)象Connection【登錄】净宵。
- 通過Connection獲取Statement對(duì)象【獲得SQL執(zhí)行代理對(duì)象】。
- 返回結(jié)果集裹纳。
- 釋放資源择葡。
2.Statement接口中的方法:
-
int executeUpdate(String sql)
:- 用于發(fā)送DML語(yǔ)句,增刪改的操作,
insert
,update
,delete
- 參數(shù):SQL語(yǔ)句
- 返回值:返回對(duì)數(shù)據(jù)庫(kù)影響的行數(shù)
- 用于發(fā)送DML語(yǔ)句,增刪改的操作,
-
ResultSet executeQuery(String sql)
:- 用于發(fā)送DQL語(yǔ)句剃氧,執(zhí)行查詢的操作敏储。
select
- 參數(shù):SQL語(yǔ)句
- 返回值:查詢的結(jié)果集
- 用于發(fā)送DQL語(yǔ)句剃氧,執(zhí)行查詢的操作敏储。
-
boolean execute(String sql)
: 可執(zhí)行任意sql,基本不用朋鞍!
3.釋放資源
- 需要釋放的對(duì)象:
- ResultSet結(jié)果集已添、
- Statement語(yǔ)句、
- Connection連接
- 釋放原則:
- 先開的后關(guān)滥酥,后開的先關(guān)更舞!
- ResultSet -> Statement -> Connection
- 放置的位置:
finally
代碼塊
五、執(zhí)行DDL操作
- 使用 JDBC 在 MySQL 的數(shù)據(jù)庫(kù)中創(chuàng)建一張學(xué)生表
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
/**
* 創(chuàng)建一張學(xué)生表
*/
public class CreateTableStudent {
public static void main(String[] args) {
// 創(chuàng)建連接
Connection conn = null;
Statement statement = null;
try {
// 獲得連接對(duì)象
conn = DriverManager.getConnection("jdbc:mysql:///jdbclearn", "root", "abc123");
// 獲得語(yǔ)句代理對(duì)象
statement = conn.createStatement();
// 發(fā)送SQL語(yǔ)句給服務(wù)器
Integer res = statement.executeUpdate(
"create table student (" +
"id int primary key auto_increment," +
"name varchar(20) not null," +
"gender boolean," +
"birthday date)"
);
// DDL沒有返回值坎吻!
System.out.println("創(chuàng)建成功res:" + res);
} catch (SQLException e){ e.printStackTrace();
} finally {
// 釋放資源
if(statement != null){ try { statement.cancel(); } catch (SQLException e){ e.printStackTrace(); } }
if(conn != null) { try { conn.close(); } catch (SQLException e){ e.printStackTrace(); } }
}
}
}
六缆蝉、執(zhí)行DML操作
- 向?qū)W生表中添加 4 條記錄,主鍵是自動(dòng)增長(zhǎng)
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.sql.Statement;
public class InsertSomeData {
public static void main(String[] args) {
// 創(chuàng)建連接對(duì)象
Connection connection = null;
Statement statement = null;
try {
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbclearn","root", "abc123");
statement = connection.createStatement();
Integer res = statement.executeUpdate(
"insert into student value" +
"(null,'孫悟空',1,'1993-03-24')," +
"(null,'白骨精',0,'1995-03-24')," +
"(null,'豬八戒',1,'1903-03-24')," +
"(null,'嫦娥',0,'1993-03-11');"
);
System.out.println("數(shù)據(jù)插入成功,供插入了" + res + "條數(shù)據(jù)刊头。");
} catch (SQLException e) {
e.printStackTrace();
} finally {
if(statement != null){ try { statement.close(); } catch (SQLException e){ e.printStackTrace(); }}
if(connection != null){ try { connection.close(); } catch (SQLException e){ e.printStackTrace(); } }
}
}
}
七贝搁、執(zhí)行DQL操作
ResultSet接口
作用: 封裝數(shù)據(jù)庫(kù)查詢的結(jié)果集,對(duì)結(jié)果集進(jìn)行遍歷芽偏,取出每一條記錄雷逆。
1.接口中的方法
-
boolean next()
:- 游標(biāo)向下移動(dòng)一行。
- 返回boolean類型污尉,如果還有下一條記錄膀哲,返回true,否則返回false。
-
數(shù)據(jù)類型 getXxx()
: 每個(gè)類型都重載方法被碗,方法簽名有兩種某宪,如下- 通過字段名,參數(shù)是String類型锐朴,返回不同的類型兴喂。
- 通過列號(hào),參數(shù)是整數(shù)焚志,從1開始衣迷。返回不同的類型。
2.以字段名簽名為例酱酬,介紹這些方法:【另一種方式就是根據(jù)int類型的索引<從1開始>獲取對(duì)應(yīng)位置的值】
-
boolean getBoolean(String col)
:以Java中boolean形式獲取此ResultSet對(duì)象的當(dāng)前行中指定列的值壶谒。 -
byte getByte(String col)
:以Java中byte形式... -
short getShort(String col
:以Java中short形式... -
long getLong(String col)
:以Java中l(wèi)ong形式... -
float getFloat(String col)
:以Java中float形式... -
double getDouble(String col)
:以Java中double形式... -
String getString(col)
:以Java中String形式...
3.常用數(shù)據(jù)類型轉(zhuǎn)換表
SQL 類型 | Jdbc 對(duì)應(yīng)方法 | 返回類型 |
---|---|---|
BIT(1) bit(n) | getBoolean() | boolean |
TINYINT | getByte() | byte |
SMALLINT | getShort() | short |
INT | getInt() | int |
BIGINT | getLong() | long |
CHAR,VARCHAR | getString() | String |
Text(Clob) Blob | getClob getBlob() | Clob Blob |
DATE | getDate() | java.sql.Date 只代表日期 |
TIME | getTime() | java.sql.Time 只表示時(shí)間 |
TIMESTAMP | getTimestamp() | java.sql.Timestamp 同時(shí)有日期和時(shí)間 |
java.sql.Date
、Time
膳沽、Timestamp(時(shí)間戳)
汗菜,三個(gè)共同父類是:java.util.Date
4.ResultSet接口中的注意事項(xiàng)
- 如果光標(biāo)在第一行之前,使用 rs.getXX()獲取列值挑社,報(bào)錯(cuò):Before start of result set
- 如果光標(biāo)在最后一行之后陨界,使用 rs.getXX()獲取列值,報(bào)錯(cuò):After end of result set
- 使用完畢以后要關(guān)閉結(jié)果集 ResultSet痛阻,再關(guān)閉 Statement菌瘪,再關(guān)閉 Connection
5.小試牛刀
- 查詢student表中所有學(xué)員的信息
import java.sql.*;
public class GetMsgFromStudent {
public static void main(String[] args) {
// 創(chuàng)建連接、執(zhí)行录平、結(jié)果集 對(duì)象
Connection connection = null;
Statement statement = null;
ResultSet rs = null;
try {
// 獲得連接對(duì)象
connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/jdbclearn","root", "abc123");
statement = connection.createStatement();
rs = statement.executeQuery("select * from student;");
// 遍歷結(jié)果集麻车,讀取每一條記錄信息缀皱。
while (rs.next()) {
int id = rs.getInt("id");
String name = rs.getString("name");
boolean gender = rs.getBoolean("gender");
Date birthday = rs.getDate("birthday");
System.out.println("編號(hào):" + id + " 姓名:" + name
+ " 性別:" + (gender?"男":"女") + " 生日:" + birthday);
}
} catch (SQLException e) { e.printStackTrace();
} finally {
if(rs != null){ try { rs.close(); } catch (SQLException e){ e.printStackTrace(); } }
if(statement != null) { try { statement.close(); } catch (SQLException e) { e.printStackTrace(); } }
if(connection != null) { try { connection.close(); } catch (SQLException e){ e.printStackTrace(); } }
}
}
}