JDBC
什么是JDBC
Java Database Connectivity:Java訪問數(shù)據(jù)庫的解決方案贮缕。
JDBC是Java應(yīng)用程序訪問數(shù)據(jù)庫的里程碑式解決方案。Java研發(fā)者希望用相同的方式訪問不同的數(shù)據(jù)庫,以實現(xiàn)與具體數(shù)據(jù)庫無關(guān)的Java操作界面。
JDBC定義了一套標(biāo)準(zhǔn)接口,即訪問數(shù)據(jù)庫的通用API昵时,不同的數(shù)據(jù)庫廠商根據(jù)各自數(shù)據(jù)庫的特點去實現(xiàn)這些接口。
JDBC接口及數(shù)據(jù)庫廠商實現(xiàn)
JDBC中定義了一些接口:
1椒丧、驅(qū)動管理:
DriverManager
2壹甥、連接接口
Connection
DatabasemetaData
3、語句對象接口
Statement
PreparedStatement
CallableStatement
4壶熏、結(jié)果集接口
ResultSet
ResultSetMetaData
JDBC工作原理
JDBC只定義接口盹廷,具體實現(xiàn)由各個數(shù)據(jù)庫廠商負(fù)責(zé)。
程序員使用時只需要調(diào)用接口久橙,實際調(diào)用的是底層數(shù)據(jù)庫廠商的實現(xiàn)部分俄占。
JDBC訪問數(shù)據(jù)庫的工作過程:
加載驅(qū)動,建立連接
創(chuàng)建語句對象
執(zhí)行SQL語句
處理結(jié)果集
關(guān)閉連接
Driver接口及驅(qū)動類加載
要使用JDBC接口淆衷,需要先將對應(yīng)數(shù)據(jù)庫的實現(xiàn)部分(驅(qū)動)加載進(jìn)來缸榄。
驅(qū)動類加載方式(Oracle):
Class.forName("oracle.jdbc.driver.OracleDriver");
這條語句的含義是:裝載驅(qū)動類,驅(qū)動類通過static塊實現(xiàn)在DriverManager中的“自動注冊”祝拯。
Connection接口
Connection接口負(fù)責(zé)應(yīng)用程序?qū)?shù)據(jù)庫的連接甚带,在加載驅(qū)動之后,使用url佳头、username鹰贵、password三個參數(shù),創(chuàng)建到具體數(shù)據(jù)庫的連接康嘉。
Class.forName("oracle.jdbc.OracleDriver")
//根據(jù)url連接參數(shù)碉输,找到與之匹配的Driver對象,調(diào)用其方法獲取連接
Connection conn = DriverManager.getConnection(
"jdbc:oracle:thin:@192.168.0.26:1521:tarena",
"openlab","open123");
需要注意的是:Connection只是接口亭珍,真正的實現(xiàn)是由數(shù)據(jù)庫廠商提供的驅(qū)動包完成的敷钾。
Statement接口
Statement接口用來處理發(fā)送到數(shù)據(jù)庫的SQL語句對象,通過Connection對象創(chuàng)建肄梨。主要有三個常用方法:
Statement stmt=conn.createStatement();
//1.execute方法阻荒,如果執(zhí)行的sql是查詢語句且有結(jié)果集則返回true,如果是非查詢語句或者沒有結(jié)果集众羡,返回false
boolean flag = stmt.execute(sql);
//2.執(zhí)行查詢語句侨赡,返回結(jié)果集
ResultSetrs = stmt.executeQuery(sql);
//3.執(zhí)行DML語句,返回影響的記錄數(shù)
int flag = stmt.executeUpdate(sql);
ResultSet接口
執(zhí)行查詢SQL語句后返回的結(jié)果集,由ResultSet接口接收羊壹。
常用處理方式:遍歷 / 判斷是否有結(jié)果(登錄)蓖宦。
String sql = "select * from emp";
ResultSetrs = stmt.executeQuery(sql);
while (rs.next()) {
System.out.println(rs.getInt("empno")+",“
+rs.getString("ename") );
}
查詢的結(jié)果存放在ResultSet對象的一系列行中,指針的最初位置在行首舶掖,使用next()方法用來在行間移動,getXXX()方法用來取得字段的內(nèi)容尔店。
處理結(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é)果集游標(biāo)指向當(dāng)前行數(shù)據(jù).
原理:
案例:
/**
* 執(zhí)行DQL 語句
*/
public class Demo03 {
public static void main(String[] args)
throws Exception{
//注冊驅(qū)動
String driver="oracle.jdbc.OracleDriver";;
Class.forName(driver);
//連接數(shù)據(jù)庫
String url="jdbc:oracle:thin:@192.168.201.227:1521:orcl";
String user="openlab";
String pwd="open123";
Connection conn=DriverManager.getConnection(
url, user, pwd);
//創(chuàng)建Statement
Statement st=conn.createStatement();
//執(zhí)行SQL(dql)
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():移動結(jié)果集游標(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)部是散列表
- Properties限定了key和Value都是String 類型.
Properties 常用API方法:
- load(流) 讀取一個配置文件
- String getProperty(key) 讀取一個屬性值
使用步驟:
- 創(chuàng)建Properties對象
- 利用load方法讀取配置文件
- 利用getProperty查詢屬性文件的內(nèi)容
案例, 讀取配置文件:
在resource 文件夾中添加配置文件 db.properties:
# db.properties
jdbc.driver=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.201.227:1521:orcl
jdbc.username=openlab
jdbc.password=open123
使用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\. 利用load方法讀取文件
InputStream in=
Demo05.class.getClassLoader()
.getResourceAsStream("db.properties");
//執(zhí)行以后,將文件內(nèi)容讀取到散列表中了
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)步驟:
創(chuàng)建數(shù)據(jù)庫連接參數(shù)文件 db.properties
-
創(chuàng)建DbUtils.java 封裝數(shù)據(jù)庫連接方法
- 利用Properties讀取配置文件夾中的數(shù)據(jù)庫連接參數(shù)
- 創(chuàng)建方法 getConnection 封裝數(shù)據(jù)庫連接過程
使用 getConnection 方法
創(chuàng)建配置文件 db.properties
# db.properties
jdbc.driver=oracle.jdbc.OracleDriver
jdbc.url=jdbc:oracle:thin:@192.168.201.227:1521:orcl
jdbc.username=openlab
jdbc.password=open123
創(chuàng)建DbUtils.java
public class DbUtils {
static String driver;
static String url;
static String username;
static String password;
//讀取文件中的數(shù)據(jù)庫連接參數(shù)
static{
//初始化靜態(tài)屬性
//1\. 利用Properties 讀取配置文件
//2\. 從配置文件中查找 相應(yīng)參數(shù)值
try{
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();
throw new RuntimeException(e);
}
}
/**
* 封裝創(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);
}
}
//DbUtils.java
/*
* 關(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)閉的過程
DbUtils 的使用:
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)閉連接.
最后眨攘,如果大家對這些內(nèi)容感興趣的話可以持續(xù)關(guān)注我,每天都有更新喔~
當(dāng)然嚣州,需要以往的內(nèi)容也可以找我閱讀哦鲫售,我這里都整合起來了方便大家閱讀,詳情點擊這里!!!