JDBC
JDBC 是什么
JDBC是Java應(yīng)用程序和數(shù)據(jù)庫之間的通信橋梁,是Java應(yīng)用程序訪問數(shù)據(jù)庫的通道.
- JDBC標(biāo)準(zhǔn)主要有一組接口組成,其好處是統(tǒng)一了各種數(shù)據(jù)訪問方式.
- JDBC接口的實現(xiàn)類稱為數(shù)據(jù)庫驅(qū)動,由各個數(shù)據(jù)庫廠商提供.使用JDBC必須導(dǎo)入這個驅(qū)動!
一定要知道驅(qū)動是什么!!
使用JDBC
JDBC使用步驟:
- 導(dǎo)入JDBC驅(qū)動jar
- 使用Maven可以便捷的導(dǎo)入數(shù)據(jù)庫驅(qū)動.
- 注冊JDBC驅(qū)動
- 參數(shù):“驅(qū)動程序類名”
- Class.forName("驅(qū)動程序名");
- 獲得Connnection對象
- 需要3個參數(shù):url,username,password
- 連接到數(shù)據(jù)庫
- 創(chuàng)建Statement(語句)對象
- conn.createStatement()方法創(chuàng)建對象
- 用于執(zhí)行 SQL 語句
- execute(ddl) 執(zhí)行任何SQL,常用執(zhí)行DDL 數(shù)據(jù)定義語言
- executeUpdate(dml) 執(zhí)行DML 語句,如:insert update delete 數(shù)據(jù)操縱語句
- executeQuery(dql) 執(zhí)行DQL語句,如:select
- 處理SQL執(zhí)行結(jié)果:
- execute(ddl) 如果沒有異常則成功.
- executeUpdate(dml) 返回數(shù)字,表示更新“行”數(shù)量,拋出異常則失敗
- executeQuery(dql) 返回ResultSet(結(jié)果集)對象,代表2維查詢結(jié)果
使用for遍歷處理,如果查詢失敗拋出異常!
- 關(guān)閉數(shù)據(jù)連接!關(guān)閉數(shù)據(jù)連接!關(guān)閉數(shù)據(jù)連接!
- conn.close();
案例:
public class Demo01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
Class.forName("com.mysql.jdbc.Driver");
// System.out.println("OK!");
//鏈接到數(shù)據(jù)庫
String url = "jdbc:mysql://localhost:3306/tedustore";
String username = "root";
String password = "admin";
//getConnection() 方法查找并并且嘗試
//鏈接到數(shù)據(jù)庫,如果不成功講拋出異常
Connection conn = DriverManager.getConnection(url, username, password);
System.out.println(conn.getClass());
//輸出conn應(yīng)用對象的實際類型
//證明:驅(qū)動程序提供了Connection接口的實現(xiàn)類
//創(chuàng)建“語句”對象
Statement st = conn.createStatement();
//執(zhí)行SQL(ddl)
String ddl = "create table robin_demo(id int,name varchar(20))";
boolean b = st.execute(ddl);
//返回結(jié)果:true 表示有結(jié)果集
// false 沒有結(jié)果集
// 創(chuàng)建失敗拋出異常
//如何判斷結(jié)果:如果沒有異常,則創(chuàng)建成功
System.out.println(b);
conn.close();
}
}
執(zhí)行 DML 語句 案例:
/**
* 執(zhí)行DML語句
* @author ghang
*
*/
public class Demo02 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//注冊驅(qū)動
Class.forName("com.mysql.jdbc.Driver");
//連接到數(shù)據(jù)庫
String url = "jdbc:mysql://localhost:3306/tedustore";
String username = "root";
String password = "admin";
Connection conn = DriverManager.getConnection(url, username, password);
//創(chuàng)建 Statement
Statement st = conn.createStatement();
//執(zhí)行DML,使用executeUpdate方法
// String dml = "insert into robin_demo(id,name) values(1,'TOM')";
// String dml = "update robin_demo set name='Jerry' where id =1";
String dml = "delete from robin_demo where id=1";
int n = st.executeUpdate(dml);
System.out.println(n);
//關(guān)閉連接!!
conn.close();
//select * from rabin_demo
}
}
處理結(jié)果集ResultSet
ResultSet代表DQL查詢結(jié)果,是2維結(jié)果集.其內(nèi)部維護(hù)了衣蛾讀取數(shù)據(jù)庫的游標(biāo),默認(rèn)情況在,游標(biāo)在第一行數(shù)據(jù)之前,當(dāng)調(diào)用next() 方法時候,游標(biāo)會向下移動,并將返回結(jié)果集中是否包含數(shù)據(jù),如果包含數(shù)據(jù)就返回true。結(jié)果集還提供了很好的getXXX(列名)方法返回結(jié)果集當(dāng)前行中指定列名的數(shù)據(jù).
rs.nexe() 檢查是否有當(dāng)前行
RessultSet rs = st.executeQuery(sql);
原理:
案例:
public class Demo03 {
public static void main(String[] args) throws Exception {
//注冊驅(qū)動
String driver = "com.mysql.jdbc.Driver";
Class.forName(driver);
//連接數(shù)據(jù)庫
String url = "jdbc:mysql://localhost:3306/tedustore";
String user = "root";
String pwd = "admin";
Connection conn = DriverManager.getConnection(url, user, pwd);
//創(chuàng)建Statement
Statement st = conn.createStatement();
//執(zhí)行SQL
String sql = "select id,name from robin_demo";
ResultSet rs = st.executeQuery(sql);
//處理結(jié)果
//rs結(jié)果集中包含一個游標(biāo),游標(biāo)默認(rèn)在結(jié)果集的第一行之前
//rs.next():移動游標(biāo)到下一行
//檢查是否有數(shù)據(jù),如果有返回true,否則false
while(rs.next()) {
//getXXX(列名):返回結(jié)果集當(dāng)前行中指定列名的數(shù)據(jù).
int id = rs.getInt("id");
String name = rs.getString("name");
//輸出查詢結(jié)果
System.out.println(id+","+name);
}
//關(guān)閉連接
conn.close();
}
}
使用Properties 讀取配置文件
Properties 是Java中專門用于讀取配置文的API.
- 其底層就是文本文件IO
- Properties 本身 實現(xiàn) Map接口,內(nèi)部是散列表
- Prpperties限定了key和Value都是String 類型.
Properties 常用API方法:
- load(流) 讀取一個配置文件
- String getProperty(key) 讀取一個屬性值
使用步驟:
- 創(chuàng)建Properties對象
- 利用load方法讀取配置文件
- 利用getProperty查詢屬性文件的內(nèi)容
案例:
在resource 文件夾中添加配置文件:
# db.properties
jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/tedustore
jdbc.username=root
jdbc.password=admin
使用Properties讀取配置文件內(nèi)容:
public class Demo05 {
public static void main(String[] args) throws IOException {
// Properties 就是為了讀取
// *.properties 文件而設(shè)計的API
// 其底層就是文本文件IO
// Properties 本身 實現(xiàn) Map接口
// 內(nèi)部是散列表,限定了key和Value都是String 類型.
//方法:load(流) 將文件就讀取為散列表
//String getProperty(key) 查詢value
//使用步驟
//1. 創(chuàng)建 Properties 對象
Properties cfg = new Properties();
System.out.println(cfg);
System.out.println(cfg.size());
System.out.println(cfg.isEmpty());
//2. 利用loag方法讀取文件
InputStream in = Demo05.class.getClassLoader().getResourceAsStream("db.properties");
cfg.load(in);
System.out.println(cfg);
System.out.println(cfg.size());
//3. 查找文件內(nèi)容,就是讀取文件內(nèi)容
String s = cfg.getProperty("jdbc.driver");
System.out.println(s);
}
}
利用配置文件可以將程序中的參數(shù)保存到配置文件中,修改程序參數(shù)只需要修改配置文件即可。
管理數(shù)據(jù)庫連接
在軟件中數(shù)據(jù)庫連接使用非常頻繁,如果每次都創(chuàng)建連接,
就會造成代碼的大量冗余,常規(guī)的做法是建立數(shù)據(jù)庫連接工具類,
封裝數(shù)據(jù)庫連接過程,統(tǒng)一數(shù)據(jù)庫連接過程,使用時候就可以簡化代碼。
實現(xiàn)步驟:ccc
- 創(chuàng)建數(shù)據(jù)庫連接參數(shù)文件 db.properties
- 創(chuàng)建DbUtils.java 封裝數(shù)據(jù)庫連接方法
- 利用Properties讀取配置文件中的數(shù)據(jù)庫連接參數(shù)
- 創(chuàng)建方法 getConnection 封裝數(shù)據(jù)庫連接過程
3.使用 getConnection 方法
創(chuàng)建配置文件 db.propertes
#jdbc.driver=com.mysql.jdbc.Driver
jdbc.url=jdbc:mysql://localhost:3306/tedustore
jdbc.username=root
jdbc.password=admin
創(chuàng)建DbUtils.java
public class DbUtils {
static String driver;
static String url;
static String username;
static String password;
//讀取文件中的數(shù)據(jù)庫連接參數(shù)
static {
try {
//初始化靜態(tài)
//1. 利用Properties 讀取配置文件
//2. 從配置文件中查找 相應(yīng)參數(shù)值
Properties cfg = new Properties();
InputStream in = DbUtils.class.getClassLoader().getResourceAsStream("db.properties");
cfg.load(in);
System.out.println(cfg);
//初始化 連接參數(shù)
driver = cfg.getProperty("jdbc.driver");
url = cfg.getProperty("jdbc.url");
username = cfg.getProperty("jdbc.username");
password = cfg.getProperty("jdbc.password");
in.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 封裝創(chuàng)建數(shù)據(jù)庫連接的過程
* 簡化數(shù)據(jù)庫連接
*/
public static Connection getConnection() {
try {
Class.forName(driver);
Connection conn = DriverManager.getConnection(url, username, password);
return conn;
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
/**
* 關(guān)閉數(shù)據(jù)庫的連接,封裝復(fù)雜的關(guān)閉過程
*/
public static void close(Connection conn) {
if(conn!=null) {
try {
conn.close();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
說明:
driver url username password 是4個數(shù)據(jù)庫連接參數(shù),因為只需要一份,則定義為靜態(tài)變量.
靜態(tài)代碼塊的目的是從配置文件中獲取4數(shù)據(jù)庫連接參數(shù)的值.
getConnection方法封裝了數(shù)據(jù)庫連接過程
-
close方法封裝了數(shù)據(jù)庫連接關(guān)閉的過程
public class Demo06 { public static void main(String[] args) { Connection conn = null; try { conn = DbUtils.getConnection(); Statement st = conn.createStatement(); String sql = "select * from robin_demo"; ResultSet rs = st.executeQuery(sql); while(rs.next()) { int id = rs.getInt("id"); String name = rs.getString("name"); System.out.println(id+","+name); } rs.close();//釋放查詢結(jié)果 st.close();//釋放語句對象 } catch (Exception e) { e.printStackTrace(); } finally { DbUtils.close(conn); } } }
顯然:使用DbUtils可以簡化JDBC代碼的書寫.
這個代碼在finally中關(guān)閉數(shù)據(jù)庫連接,其好處是可靠關(guān)閉連接.
作業(yè):
- 創(chuàng)建新的Maven項目導(dǎo)入Mysql數(shù)據(jù)庫驅(qū)動
- 獨立編寫數(shù)據(jù)庫連接管理工具類 DbUtils
- 利用DbUtils實現(xiàn)員工表的 插入操作
- 利用DbUtils實現(xiàn)員工表的 修改操作
- 利用DbUtils實現(xiàn)員工表的 刪除操作
- 利用DbUtils實現(xiàn)員工表的 查詢操作