1.JDBC簡(jiǎn)介
JDBC= Java DataBase Connectivity,java數(shù)據(jù)庫(kù)連接。
可用于執(zhí)行SQL語(yǔ)句的Java API,JDBC提供了一種基準(zhǔn),據(jù)此可以構(gòu)建更加高級(jí)的的工具和接口。
JDBC的唯一作用:與數(shù)據(jù)庫(kù)交互。
已經(jīng)包含在了JDK之中。
JDBC API是執(zhí)行SQL語(yǔ)句的工具,JDBC允許對(duì)不同的平臺(tái),不同的數(shù)據(jù)庫(kù)采用相同的編程接口來(lái)執(zhí)行SQL語(yǔ)句。
3.JDBC的增強(qiáng)
目標(biāo):
1)預(yù)編譯sql處理(防止sql注入)
2)批處理
3)插入數(shù)據(jù)
4)事物
5)JDBC綜合練習(xí)
預(yù)編譯SQL處理
JDBC驅(qū)動(dòng)包
|--Statement 執(zhí)行SQL命令
|--CallableStatement 執(zhí)行存儲(chǔ)過(guò)程
|--PreparedStatement 預(yù)編譯SQL語(yǔ)句執(zhí)行
使用預(yù)編譯SQL語(yǔ)句的命令對(duì)象,好處:
1)避免了頻繁SQL拼接(可以使用占位符)
2)可以防止sql注入
Statement不能防止SQL注入,connection的prepareStatement(sql)就可以防止sql注入
// 創(chuàng)建stmt對(duì)象
//stmt = connection.createStatement();
// 使用pstmt對(duì)象
pstmt = connection.prepareStatement(sql);
// 執(zhí)行查詢
set = pstmt.executeQuery();
存儲(chǔ)過(guò)程:
DELIMITER $$
CREATE PROCEDURE proc_login()
BEGIN
SELECT * FROM admin;
END $$
eg:
// 創(chuàng)建執(zhí)行過(guò)程的stmt對(duì)象
CallableStatement cstmt = con.prepareCall("CALL proc_login");
事務(wù)編程
事務(wù):
事務(wù)指的是邏輯上的一組操作,組成這組操作的各個(gè)單元,要不全部成功,要不全部不成功。
事務(wù)的特征(ACID):
原子性,是一個(gè)最小的邏輯操作單元。
持久性,事物一旦提交成功,對(duì)數(shù)據(jù)的更改會(huì)反映到數(shù)據(jù)庫(kù)中。
隔離性,事物與事物之間是隔離的。
一致性,事物必須使數(shù)據(jù)庫(kù)從一個(gè)一致性狀態(tài)變換到另外一個(gè)一致性狀態(tài)。
案例:
注意:創(chuàng)建一個(gè)connection的時(shí)候,會(huì)自動(dòng)開(kāi)啟一個(gè)隱式事物。
注意:Navicat中如何修改已經(jīng)建好的MySQL表的編碼格式
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;
需求:張三給李四轉(zhuǎn)賬
設(shè)計(jì):賬戶表
技術(shù):
|-- Connection
void setAutoCommit(boolean autoCommit);設(shè)置事物是否自動(dòng)提交。 如果設(shè)置為false,表示手動(dòng)提交事物。手動(dòng)提交事務(wù)。
void commit(); 手動(dòng)提交事務(wù)。
void rollback(); 回滾(出現(xiàn)異常的時(shí)候,所有已經(jīng)執(zhí)行成功的代碼需要回退到事務(wù)開(kāi)始之前的狀態(tài)。)
savepoint setSavepoint(String name)
代碼:
// 1.轉(zhuǎn)賬,沒(méi)有使用事務(wù)
public void trans() {
String sql_zs = "UPDATE account SET money=money-100 WHERE accountName='zhangsan';";
String sql_ls = "UPDATE account SET money=money+100 WHERE accountName='李四';";
try {
System.out.println("0");
/* 第一次執(zhí)行SQL */
con = JdbcUtil.getConnection(); // 開(kāi)啟隱式事物
con.setAutoCommit(false); // 設(shè)置手動(dòng)提交
pstmt = con.prepareStatement(sql_zs);
pstmt.executeUpdate();
System.out.println("a");
/* 第二次執(zhí)行SQL */
pstmt = con.prepareStatement(sql_ls);
pstmt.executeUpdate();
System.out.println("b");
} catch (Exception e) {
e.printStackTrace();
try {
con.rollback();
} catch (SQLException e1) {
e1.printStackTrace();
}
}finally {
try {
con.commit();
} catch (SQLException e) {
e.printStackTrace();
}
JdbcUtil.closeAll(con, pstmt, null);
}
}
綜合案例:
需求分析:
登錄,注冊(cè),注銷
登錄成功
顯示所有員工
設(shè)計(jì):
數(shù)據(jù)庫(kù)設(shè)計(jì):
Admin:存放所有的登錄用戶
Employee"存放所有的員工信息
系統(tǒng)設(shè)計(jì):
a. 系統(tǒng)結(jié)構(gòu)
分層:基于mvc模式的分層
b.項(xiàng)目用到的共用組件,類(JdbcUtil)

基于MVC的分層。
分析 -- 設(shè)計(jì) -- 編碼
4.JDBC優(yōu)化
BeanUtils 需要拷貝jar包

BeanUtils組件,它依賴其他的jar包:
1) logging
2)日志
注意:一般缺少日志jar文件報(bào)這個(gè)錯(cuò)

BeanUtils的使用:
BeanUtils.copyProperty(admin, "userName", "jack");
BeanUtils.setProperty(admin, "age", 10); // 注意,這個(gè)值也可以是字符串“10”,會(huì)自動(dòng)轉(zhuǎn)為需要的類型。對(duì)于基本類型的拷貝(賦值),會(huì)自動(dòng)進(jìn)行類型轉(zhuǎn)換。
這2個(gè)方法是一模一樣的。作用是設(shè)置屬性值。屬性名一定是字符串的。
Map對(duì)象populate到對(duì)象中去:
/**
* map數(shù)據(jù)拷貝到對(duì)象中
*/
Admin adminMap = new Admin();
Map<String, Object> map = new HashMap<String, Object>();
map.put("userName", "jack1");
map.put("age", 20);
/**
* 注意:map 中的key要與javaBean的睡醒名稱一致
*/
BeanUtils.populate(adminMap, map);
注意:BeanUtils不能自動(dòng)轉(zhuǎn)日期類型。
BeanUtils.copyProperty(admin, "birth", "1990-09-09");
5.元數(shù)據(jù)
1)簡(jiǎn)介
元數(shù)據(jù):DataBaseMetaData
元數(shù)據(jù):數(shù)據(jù)庫(kù),表,列的定義信息。
Connnection.getDatabaseMetaData()
DataBaseMetaData對(duì)象:
- 在jdbc中獲取數(shù)據(jù)庫(kù)的定義,例如:數(shù)據(jù)庫(kù),表,列的定義信息。
- 在jdbc中可以使用:數(shù)據(jù)庫(kù)元數(shù)據(jù),參數(shù)元數(shù)據(jù),結(jié)果集元數(shù)據(jù)。
DatabaseMetaData使用:
http://blog.csdn.net/anxinliu2011/article/details/7560511

獲取參數(shù)元素:
Connection con = JdbcUtil.getConnection();
// 獲取數(shù)據(jù)庫(kù)元數(shù)據(jù)
DatabaseMetaData metaData = con.getMetaData();
String sql = "SELECT * FROM dept where deptId = ? and deptName = ?";
PreparedStatement pstmt = con.prepareStatement(sql);
// 參數(shù)元數(shù)據(jù)
ParameterMetaData p_metaDate = pstmt.getParameterMetaData();
關(guān)于Dao操作的抽取
Dao操作通用的步驟:
1)獲取連接
2)創(chuàng)建stmt
- 執(zhí)行sql
a. 更新
b. 查詢
4)關(guān)閉/異常
只有第3)步驟不一樣,其他都是一樣的。
所以想創(chuàng)建一個(gè)通用的dao:
a.更新
String sql = "select * from admin";
String sql = "select * from admin where id=? and pwd = ?";
public void update(String sql, ); //
b.查詢