一、概念
1姜性、jdbc: java database connectivity 即java與數(shù)據(jù)庫的連接
2、角色分類
服務(wù)器 (db): a)氨菇、接收 sql b)门驾、執(zhí)行 sql c)奶是、返回結(jié)果
客戶端 (java):a)、接收數(shù)據(jù) b)初嘹、組裝sql c)屯烦、發(fā)送SQL(與數(shù)據(jù)庫建立聯(lián)系) d)驻龟、分析結(jié)果
3翁狐、面向接口編程
java 制定標(biāo)準(zhǔn) 露懒,不同的數(shù)據(jù)庫廠商實現(xiàn) 接口即可懈词。java 中提供的接口 java.sql.* 包下坎弯,常用接口如下
接口名稱 作用
java.sql.Connection 連接
java.sql.Statement 靜態(tài)處理塊
java.sql.PreparedStatement 預(yù)處理塊
java.sql.ResultSet 結(jié)果集
java.sql.ResultSetMetaData 結(jié)果集元信息
oracle廠商實現(xiàn)接口 (jar)
F:\app\Administrator\product\11.2.0\dbhome_1\jdbc\lib\ojdbc6.jar 視安裝路徑而定
二译暂、jdbc 步驟
1秧秉、jdbc 步驟類比寄快遞
1象迎、選擇快遞公司
加載驅(qū)動(完整路徑)
2、與快遞公司建立聯(lián)系(電話號碼 唯一信息)
建立連接(url 用戶名 密碼)
3汪厨、快遞員 收包裹 創(chuàng)建處理塊 Statement PreparedStatement
4劫乱、打包 投遞
執(zhí)行: execute(ddl) int executeUpdate(dml) ResultSet executeQuery(select)
5衷戈、簽收
分析結(jié)果 :ddl -->沒有異常 dml--->>0 select-->分析 結(jié)果集
6殖妇、打發(fā)走人 釋放資源 核
核心為拼接 SQL谦趣、分析結(jié)果前鹅、操作結(jié)果
- 導(dǎo)包
在項目中新建一個source folder文件夾烦租,名字為lib
將oracle里的實現(xiàn)接口jar包(app\Administrator\product\11.2.0\dbhome_1\jdbc\lib\ojdbc6.jar 視安裝路徑而定)復(fù)制到lib文件夾中
選擇ojdbc6.jar右鍵選擇add build path
- 建立連接
1)叉橱、連接字符串
驅(qū)動: oracle.jdbc.driver.OracleDriver
url: jdbc:oracle:thin:@db 服務(wù)器地址:端口:實例
連接 url:jdbc:oracle:thin:@localhost:1521:orcl
用戶名與密碼:如 scott tiger
2、簡單的JDBC步驟
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class Demo01 {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加載驅(qū)動(選擇數(shù)據(jù)庫)
Class.forName("oracle.jdbc.driver.OracleDriver");
//2.獲取連接(連接數(shù)據(jù)庫)
Connection con=DriverManager.getConnection("jdbc:oracle:thin:@localhost:1521:xe", "SCOTT", "TIGER");
//3.獲取靜態(tài)處理塊(構(gòu)建一個執(zhí)行和發(fā)送SQL 語句的對象)
Statement state =con.createStatement();
//4.創(chuàng)建SQL語句
String str ="select ename,empno from emp";
//5.創(chuàng)建結(jié)果集
ResultSet result=state.executeQuery(str);
//6.獲取結(jié)果
while (result.next()) {
String ename=result.getString(1);
long empno=result.getLong(2);
System.out.println(ename+"->"+empno);
}
//關(guān)閉資源
result.close();
state.close();
con.close();
}
}
3者蠕、處理塊
- 靜態(tài)處理塊
Statement 是 Java 執(zhí)行數(shù)據(jù)庫操作的一個重要接口窃祝,用于在已經(jīng)建立數(shù)據(jù)庫連
接的基礎(chǔ)上,向數(shù)據(jù)庫發(fā)送要執(zhí)行的 SQL 語句踱侣。Statement 對象粪小,用于執(zhí)行不帶參數(shù)
的簡單 SQL 語句。
執(zhí)行靜態(tài) SQL 語句并返回它所生成結(jié)果的對象抡句。
1)探膊、創(chuàng)建 : 連接.Connection.createStatement()
2)、執(zhí)行 :
ddl -->execute(dd語句) -- 通常不會在代碼中執(zhí)行
dml -->executeUpdate(dml語句)
select -->executeQuery(select)
3)待榔、特點:處理 不變的靜態(tài)的 sql 語句
優(yōu)點: 直接查看sql 逞壁,方便處理錯誤
缺點:性能不高 拼接 sql 麻煩 可能存在 sql 注入
- 預(yù)處理塊
PreparedStatement 接口繼承了 Statement,并與之在兩方面有所不同:有人主張锐锣,在 JDBC 應(yīng)用中斤彼,如果你已經(jīng)是稍有水平開發(fā)者蟋恬,你就應(yīng)該始終以PreparedStatement 代替 Statement.也就是說渗勘,在任何時候都不要使用 Statement。由于 PreparedStatement 對象已預(yù)編譯過璧疗,所以其執(zhí)行速度要快于 Statement 對象。因此,多次執(zhí)行的 SQL 語句經(jīng)常創(chuàng)建為 PreparedStatement 對象,以提高效率。
1)爹谭、創(chuàng)建:創(chuàng)建:連接.prepareStatement(sql)
2)腹泌、執(zhí)行:
存在? ,先填充參數(shù)再執(zhí)行
ddl -->execute()
dml -->executeUpdate()
select -->executeQuery()
3)、特點 :處理 不變的靜態(tài)的 sql 語句 |可變的 sql 語句 帶 ? 的 sql
優(yōu)點:性能高,方便編寫sql 不存在sql注入 安全
缺點:不能直接打印sql語句 不方便處理錯誤
預(yù)處理塊實例
public static boolean update(String name, String pwd ) {
Connection con = null;
ResultSet result = null;
PreparedStatement ps = null;
// 準(zhǔn)備SQL語句
String sql = "update t_user set uname=?,pwd=?";
// 創(chuàng)建連接
try {
con = DBUtils.getConnection();
// 創(chuàng)建預(yù)處理塊
ps = con.prepareStatement(sql);
// 更新數(shù)據(jù)
ps.setString(1, name);
ps.setString(2, pwd);
// 執(zhí)行更新并返回結(jié)果
int num = ps.executeUpdate();
if (num <= 0) {
System.out.println("修改失敗");
} else {
System.out.println("修改成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.close(con, ps, result);
}
return false;
}
6蒙袍、使用預(yù)處理塊
public static boolean update(String name, String pwd ) {
Connection con = null;
ResultSet result = null;
PreparedStatement ps = null;
// 準(zhǔn)備SQL語句
String sql = "update t_user set uname=?,pwd=?";
// 創(chuàng)建連接
try {
con = DBUtils.getConnection();
// 創(chuàng)建預(yù)處理塊
ps = con.prepareStatement(sql);
// 更新數(shù)據(jù)
ps.setString(1, name);
ps.setString(2, pwd);
// 執(zhí)行更新并返回結(jié)果
int num = ps.executeUpdate();
if (num <= 0) {
System.out.println("修改失敗");
} else {
System.out.println("修改成功");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.close(con, ps, result);
}
return false;
}
7佩抹、使用Properties配置文件
public static void main(String[] args) {
// 獲取配置文件
Properties pro = new Properties();
Connection con = null;
PreparedStatement pre = null;
ResultSet result = null;
String ename = null;
long empno = 0;
try {
// 加載配置文件
// db.properties為當(dāng)前src路徑下放入鍵值對數(shù)據(jù)的文件
pro.load(Thread.currentThread().getContextClassLoader().getResourceAsStream("db.properties"));
// 加載驅(qū)動
Class.forName(pro.getProperty("driver"));
// 創(chuàng)建連接
con = DriverManager.getConnection(pro.getProperty("url"), pro.getProperty("name"), pro.getProperty("pwd"));
// 創(chuàng)建sql語句
String sql = "select ename,empno from emp where ename=?";
// 獲取處理塊
pre = con.prepareStatement(sql);
// 站位
pre.setString(1, "SMITH");
// 獲取結(jié)果
result = pre.executeQuery();
if (result.next()) {
ename = result.getString(1);
empno = result.getLong(2);
System.out.println(empno + "--->" + ename);
}
} catch (IOException e) {
e.printStackTrace();
} catch (SQLException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} finally {
try {
if (result != null) {
result.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (pre != null) {
pre.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
try {
if (con != null) {
con.close();
}
} catch (SQLException e) {
e.printStackTrace();
}
}
}
8奥洼、自定義通用的操作數(shù)據(jù)庫的類
/*
* 通用的操作數(shù)據(jù)庫的類
*/
public class Base<T> {
// 更新數(shù)據(jù)
public boolean update(String str, Object[] obj) {
boolean flag = false;
Connection con = null;
PreparedStatement state = null;
con = DBUtils.getConnection();
try {
state = con.prepareStatement(str);
for (int i = 0; i < obj.length; i++) {
state.setObject(i + 1, obj[i]);
}
int num = state.executeUpdate();
if (num > 0) {
flag = true;
System.out.println("操作成功");
} else {
System.out.println("操作失敗");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
DBUtils.close(con, state);
}
return flag;
}
// 查找數(shù)據(jù)
public List<T> search(String sql,Object[] obj,Class<T> cls){
List<T> list=new ArrayList() ;
Connection con=null;
ResultSet result=null;
PreparedStatement state=null;
//獲取連接
con=DBUtils.getConnection();
try {
//獲取預(yù)處理塊
state=con.prepareStatement(sql);
//循環(huán)寫入站位
if(obj!=null) {
for (int i = 0; i < obj.length; i++) {
state.setObject(i + 1, obj[i]);
}
}
//執(zhí)行
result=state.executeQuery();
//ResultSetMetaData類可用于獲取關(guān)于 ResultSet 對象中列的類型和屬性信息的對象
ResultSetMetaData rsmd=state.getMetaData();
//判斷結(jié)果
//獲取結(jié)果數(shù)量
int count=rsmd.getColumnCount();
System.out.println(count);
while(result.next()) {
//創(chuàng)建用來存放記錄的對象
T t=cls.newInstance();
for (int i = 0; i < count; i++) {
//獲取字段名
String colName=rsmd.getColumnLabel(i+1);
System.out.println(colName);
//獲取字段數(shù)據(jù)
Object value=result.getObject(i+1);
System.out.println(colName);
//獲取字段數(shù)據(jù)類型
Field field= cls.getDeclaredField(colName);
//開啟權(quán)限
field.setAccessible(true);
field.set(t, value);
field.setAccessible(false);
System.out.println(t);
}
//添加元素
list.add(t);
System.out.println("操作成功");
}
} catch (SQLException e) {
e.printStackTrace();
} catch (InstantiationException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (NoSuchFieldException e) {
e.printStackTrace();
} catch (SecurityException e) {
e.printStackTrace();
}finally {
DBUtils.close(con, state,result);
}
System.out.println(list);
return list;
}
}
測試
String sql="insert into t_user values(?,?)";
Base<User> base=new Base<User>();
//String[] obj= {"趙鐵柱","qwer"};
//base.update(sql, obj);
sql="select uname \"uname\",pwd \"pwd\" from t_user";
List list=base.search(sql, null, User.class);
System.out.println(list);