數據庫編程技術總結


數據庫部分 全書總結:

MYSQL:

dbs 數據庫系統

bdms 數據庫管理系統
bda 數據庫管理員
db 數據庫

dba通過dbms來操作db!

關系型數據庫(MySQL MySQLServer Oracle)和非關系型數據庫

登錄mysql

mysql -h主機地址 -u用戶名 -p密碼


查詢所有的數據庫
show databases;

創建數據庫
create database [if not exists ] 數據庫名稱;

刪除數據庫
drop database [if exists ] 數據庫名稱;


結構語言分類
DDL(數據定義語言) create drop alter 創建刪除以及修改數據庫,表,存儲過程,觸發器,索引....

DML(數據操作語言) insert delete update 用來操作數據庫中的數據

DQL(數據查詢語言) select 用來查詢數據庫中的數據

DCL(數據控制語言) grant(授權) revoke(撤銷)

TCL(事務控制語言) begin savepoint (設置回滾點) rollback commit

grant 查詢 to 用戶名;
revoke 查詢 from 用戶名;

crud(增刪改查)

 

創建用戶
create user 用戶名@‘地址’ identified by ‘密碼’;


給用戶授權
01. grant all on *.* to 用戶名;
02. grant all on *.* to 用戶名@‘地址’;
命令:GRANT privileges ON databasename.tablename TO 'username'@'host'

說明: privileges - 用戶的操作權限,如SELECT , INSERT , UPDATE 等(詳細列表見該文最后面).如果要授予所的權限則使用ALL.;databasename - 數據庫名,tablename-表名,如果要授予該用戶對所有數據庫和表的相應操作權限則可用*表示, 如*.*.

例子: GRANT SELECT, INSERT ON test.user TO 'pig'@'%';
GRANT ALL ON *.* TO 'pig'@'%';

注意:用以上命令授權的用戶不能給其它用戶授權,如果想讓該用戶可以授權,用以下命令:
GRANT privileges ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION;

刷新系統權限
flush privileges;

刪除用戶
所有的用戶都存儲在mysql數據庫中的user表中

01. delete from mysql.user where user='t13';
02. delete from mysql.user where user='t13' and host='localhost';


邏輯運算符

and && 與
or || 或
not ! 非


USE 切換到指定的數據庫
如果沒有切換數據庫,需要在表名前面加上數據庫名稱!
USE mysql;
SELECT `host`,`user` FROM `user`;


數據類型

int double
在mysql中使用的是decimal(a,b)

a指定指定小數點左邊和右邊可以存儲的十進制數字的最大個數,最大精度38。
b指定小數點右邊可以存儲的十進制數字的最大個數。小數位數必須是從 0 到 a之間的值。默認小數位數是 0

在oracle中經常 使用 **** number ****

 

 

char 固定長度 例子: 性別 是 char類型 長度是10 但是我們的實際輸入的長度是2, 那么存儲的時候也是10個空間! 資源浪費

varchar 可變長度 例子: 性別 是 char類型 長度是10 但是我們的實際輸入的長度是2, 那么存儲的時候也是2個空間!

日期格式

date yyyy-MM-dd
datetime yy-MM-dd hh:mm:ss
time hh:mm:ss
timestamp 1970到現在 yyyyMMddhhmmss
year yyyy 1901

 

 

約束類型

主鍵約束 primary key (pk) 用於設置表的主鍵,用來確保該行的唯一性
外鍵 foreign key (fk) 用於建立表與表之間的關系
非空約束 not null 字段不允許為空
默認約束 default 字段的默認值
唯一約束 unique key(uk) 字段的值是唯一的可以是null,但只能有一個
自動增長 auto_increment 設置列的自動增長(標識列),通常用於設置主鍵

 

 

 

創建表

如果是關鍵字 那么使用反引號 `` esc下面的鍵

create table [if not exists] 表名(
字段1 數據類型 [約束,索引,注釋],
字段2 數據類型 [約束,索引,注釋],
字段3 數據類型 [約束,索引,注釋]
)[表類型][表字符集][注釋]


有符號類型 和 無符號類型


有符號類型 :可以取負值
無符號類型:默認是0! 0--類型的長度


ZEROFILL屬性:如果位數不夠,前面用零補齊!

若某數值字段指定了ZEROFILL屬性,
將自動添加UNSIGNED屬性!

創建學生表

CREATE TABLE IF NOT EXISTS student(
studentNo INT(4) NOT NULL PRIMARY KEY COMMENT '學號',
loginPwd VARCHAR(20) NOT NULL COMMENT '密碼',
studentName VARCHAR(50) NOT NULL COMMENT '姓名',
sex CHAR(2) NOT NULL DEFAULT'男' COMMENT '性別',
gradeID INT(4) UNSIGNED COMMENT '年級編號',
phone VARCHAR(50) COMMENT '電話',
address VARCHAR(255) DEFAULT'地址不詳' COMMENT '地址',
bornDate DATETIME COMMENT '出生日期',
email VARCHAR(50) COMMENT '郵箱賬號',
identityCard VARCHAR(18) UNIQUE KEY COMMENT '身份證號'
)COMMENT='學生表';


修改表中的數據

-- 修改表名 把 student表名 改成 stu
ALTER TABLE student RENAME AS stu;

-- 給表中增加 微信 字段 不為空 唯一
ALTER TABLE student ADD wechat VARCHAR(20) UNIQUE KEY;

-- 修改表中 微信 字段的長度為50
ALTER TABLE student MODIFY wechat VARCHAR(50);

-- 刪除表中 微信 字段
ALTER TABLE student DROP wechat;

-- 修改studentName字段的名稱為 stuName
ALTER TABLE student CHANGE `name` stuName VARCHAR(20);


創建subject(科目表)

CREATE TABLE IF NOT EXISTS `subject`(
subjectNo INT(4) AUTO_INCREMENT PRIMARY KEY COMMENT '課程編號',
subjectName VARCHAR(50) COMMENT '課程名稱',
classHour INT(4) COMMENT '學時',
gradeID INT(4) COMMENT '年級編號'
)COMMENT='科目表' CHARSET='utf8';

遇到的問題
在使用AUTO_INCREMENT 必須和PRIMARY KEY 聯合使用!

標識列 是 自增列!
主鍵是 唯一!


創建年級表

CREATE TABLE IF NOT EXISTS grade(
gradeID INT(4) COMMENT '年級編號',
gradeName VARCHAR(10) COMMENT '年級名稱'
)COMMENT='年級表';

添加主鍵的語法
ALTER TABLE 表名 ADD CONSTRAINT 主鍵名
PRIMARY KEY 表名(主鍵字段);


-- 給年級表中id設置成主鍵
ALTER TABLE grade ADD CONSTRAINT pk_grade_gradeID PRIMARY KEY(gradeID);


創建成績表

CREATE TABLE IF NOT EXISTS result(
studentNo INT(4) NOT NULL PRIMARY KEY COMMENT '學號',
subjectNo INT(4) NOT NULL COMMENT '課程編號',
examDate DATETIME NOT NULL COMMENT '考試日期 ',
studentResult INT(4) NOT NULL COMMENT '考試成績'
)COMMENT='成績表' charset='utf8' engine=InnoDB;

 

 

外鍵的語法:
ALTER TABLE 表名 ADD CONSTRAINT 外鍵名
FOREIGN KEY(外鍵字段)
REFERENCES 關聯表名(關聯字段);

 

創建student表和grade表的關系

學生應該屬於某個年級

外鍵必須建立在 從表上!

ALTER TABLE student ADD CONSTRAINT fk_student_grade
FOREIGN KEY(gradeID)
REFERENCES grade(gradeID);


問題: 前提已經建立了 主外鍵關系


如果說有三個年級,編號分別是 1 2 3
那么也有三個學生 對應的關系是
第1個學生 1年級
第2個學生 2年級
第3個學生 2年級


01.有沒有這種情況 有個學生的年級編號是4 ??
主表中沒有數據! 從表無法創建!

02.可不可以刪除年級表2年級或者1年級???
不能刪除!因為從表中還有關聯數據!


03.如果我們非得刪除年級 怎么辦??
先把從表中的關聯數據刪除 ,之后再刪除主表中的數據!

聯合主鍵
將多列設置成主鍵!


-- 給成績表設置聯合主鍵
ALTER TABLE result ADD PRIMARY KEY pk_result (studentno,subjectno,examdate);

 


mysql數據庫中常用的兩種 存儲 引擎

MyISAM InnoDB
事務處理 不支持 支持
外鍵約束 不支持 支持
全文索引 支持 不支持


使用的場景:

MyISAM:不能使用事務,空間小,適合查詢!
InnoDB:多適用於增刪改,安全性高!事務的並發處理!

-- 查詢當前默認的存儲引擎
SHOW VARIABLES LIKE 'storage_engine%';
-- 修改存儲引擎
-- 找到安裝路徑下面的my.ini文件
-- 加入 default-storage-engine=InnoDB


數據庫表的存儲位置

InnoDB類型的文件
*.frm :表結構定義文件(存放的是表的元數據,與存儲引擎無關)
*.ibd : 數據文件(存放數據,字段的值)

MyISAM類型的文件
*.frm :表結構定義文件
*.MYD :數據文件
*.MYI :索引文件

 

 

DML和DQL 增刪改查

 

SELECT * FROM grade

新增 insert

-- 向年級表中新增3條數據
INSERT INTO grade(gradeID,gradeName) VALUES(4,'4年級');
INSERT INTO grade(gradeID,gradeName) VALUES(5,'5年級');
INSERT INTO grade(gradeID,gradeName) VALUES(6,'6年級');

-- 刪除 456
DELETE FROM grade WHERE gradeID>3;
DELETE FROM grade WHERE gradeID=4 OR gradeID=5 OR gradeID=6;
DELETE FROM grade WHERE gradeID IN (4,5,6);

-- 同時插入多條數據 oracle數據庫不支持
INSERT INTO grade(gradeID,gradeName)
VALUES(4,'4年級'),(5,'5年級'),(6,'6年級');


-- 修改gradeID=1的年級名稱為 one
UPDATE grade SET gradeName='one'
WHERE gradeID=1

-- delete 刪除表中所有的數據
DELETE FROM grade;

 

delete 和 truncate的區別
01.delete

begin (開啟事務)
select * from grade;(查詢年級表中所有的數據)
delete from grade; (刪除年級表中所有的數據)
select * from grade;(查詢年級表中所有的數據,沒有數據)
rollback; (事務回滾)
select * from grade;(查詢年級表中所有的數據,刪除的數據恢復)
commit (提交事務)


02.truncate

begin (開啟事務)
select * from grade;(查詢年級表中所有的數據)
truncate table grade; (刪除年級表中所有的數據)
select * from grade;(查詢年級表中所有的數據,沒有數據)
rollback; (事務回滾)
select * from grade;(查詢年級表中所有的數據,沒有數據)
commit (提交事務)


區別:
01.delete后面可以拼接where條件,刪除指定的行!
truncate只能刪除表中所有的數據!不能有where!

02.delete可以回滾,數據庫可以恢復!
truncate 不能事務混滾,數據不可以恢復!

03.truncate執行效率高!

 

事務的特性 ACID

事務:一條或者多條sql語句的集合!

原子性 (Atomicity):在事務中的操作,要么都執行,要么都不執行!
一致性(Consistency):事務必須保證數據庫從一個一致性的狀態變成另一個一致性的狀態!
隔離性(Isolation):每個事務之間互不干擾!哪怕是並發執行也不干擾!
持久性(Durability):事務一旦被改變,那么對數據庫中數據的影響是永久性的!

 

 

查詢

將查詢結果保存到 新表中!
create table newStudent
(select stuName,address from student)

view (視圖) :不占物理空間!

 

使用 具體的列 代替 *

select * from student;

select stuName,age ,address from student;


使用別名

SELECT gradeID AS 年級編號,gradeName '年級 名稱' FROM grade;

格式
01. 列名 AS 別名
02. 列名 別名
03. 如果別名中有特殊符號,必須把 別名用 單引號 引起來!


查詢年級表中 id不等於1的數據 <> !=
SELECT gradeID,gradeName
FROM grade
WHERE gradeid <> 1

 



+ 必須是相同的數據類型,能轉換成2進制的數據!
如果有一個列是null 整體返回null!

我們通常使用 concat來做合並
SELECT CONCAT(loginPwd,',',studentNAME) AS 合並列 FROM STUDENT

 

使用is null 的時候 要確保 查詢的列 可以為空!

null:
01.標識 空值
02.不是0,也不是空串""
03.只能出現在定義 允許為null的字段
04.只能使用is null 或者is not null 進行比較!


SELECT * FROM student
WHERE loginPwd IS NULL


聚合函數

count() 查詢某個字段在表中占的行數
max()查詢某個字段的最大值
min()查詢某個字段的最小值
sum()查詢某個字段的和
avg()查詢某個字段的平均值


-- 查詢成績表的總成績
SELECT SUM(studentResult) FROM result;
-- 查詢成績的平均值
SELECT AVG(studentResult) FROM result;
-- 查詢成績的最高分
SELECT MAX(studentResult) FROM result;
-- 查詢成績的最低分
SELECT MIN(studentResult) FROM result;
-- 查詢有成績的總數
SELECT COUNT(studentResult) FROM result;


常用的字符函數


-- concat(str1,str2...strN) 連接字符串

SELECT CONCAT('h','el','lo') FROM DUAL;

-- insert(str,begin,length,newStr) 替換字符串
-- str初始的字符串 begin 開始的位置 從1開始
-- length 替換長度 newStr替換的字符串

SELECT INSERT('hello',2,3,'55555') FROM DUAL;

-- subString(str,begin,length) 截取字符串

SELECT SUBSTRING('hello',2,3) FROM DUAL;

-- lower(str)轉換成小寫
-- upper(str)轉換成大寫

 

 

 


dual 我們稱之為 偽表!

在mysql中是一個擺設

select 9*9;
select 9*9 from dual;

select * from dual; 報錯


oracle中 必須使用 from dual;
select 9*9 from dual; 正確的
select 9*9 ; 錯誤


dual是一個只有一行一列的表!
只能查詢! 不能對 dual進行增刪改!

 

和並列

DROP TABLE IF EXISTS `testa`;

CREATE TABLE `testa` (
`name` varchar(20) DEFAULT NULL,
`subject` varchar(20) DEFAULT NULL,
`score` double DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

 

insert into `testa`(`name`,`subject`,`score`) values ('張三','語文',80),('李四','語文',90),('王五','語文',70),('張三','數學',60),('李四','數學',98),('王五','數學',100);


-- 需要成績和科目 在一列 顯示 根據name分組
SELECT
`name` AS 姓名,
GROUP_CONCAT(`subject`,':',score) AS 成績
FROM testa
GROUP BY `name`;


-- 常用的日期和時間函數

-- 獲取 年月日
SELECT CURDATE() FROM DUAL;
-- 獲取 時分秒
SELECT CURTIME() FROM DUAL;
-- 獲取 年月日 時分秒
SELECT NOW() FROM DUAL;
-- 獲取年份
SELECT YEAR(NOW()) FROM DUAL;
SELECT YEAR(CURDATE()) FROM DUAL;
-- 獲取小時
SELECT HOUR(NOW()) FROM DUAL;
SELECT HOUR(CURTIME()) FROM DUAL;
-- 獲取分鍾
SELECT MINUTE(NOW()) FROM DUAL;
SELECT MINUTE(CURTIME()) FROM DUAL;
-- 獲取當前日期是本年的第幾周
SELECT WEEK(NOW()) FROM DUAL;

-- 獲取兩個日期之間的天數
SELECT DATEDIFF(NOW(),'2015-06-01') FROM DUAL;

-- 獲取給定日期之后的日期
SELECT ADDDATE(NOW(),30) FROM DUAL;



-- 天花板函數
SELECT CEIL(3.0) FROM DUAL;
SELECT CEIL(3.1) FROM DUAL;

SELECT FLOOR(3.9) FROM DUAL;

-- 返回0-1之間的隨機數
SELECT RAND() FROM DUAL;

-- 四舍五入
SELECT ROUND(2.4) FROM DUAL;



-- 查詢所有年級編號為1的學員信息,按學號升序排序
SELECT * FROM student
WHERE GradeID=1
ORDER BY Studentno ASC;

-- 顯示前4條記錄
SELECT * FROM student
WHERE GradeID=1
ORDER BY Studentno ASC
LIMIT 0,4;
-- 每頁4條,顯示第2頁,即從第5條記錄開始顯示4條數據
SELECT * FROM student
WHERE GradeID=1
ORDER BY Studentno ASC
LIMIT 4,4


-- 子查詢 【from后面跟子查詢 必須用別名】
-- 把一個查詢的結果 當成另一個查詢的 字段,條件或者表!

SELECT studentName FROM student

-- 只能通過student 表 查詢出 學生對應的 年級名稱

-- 01. 先查詢出 學生 武松 對應的 年級編號
SELECT GradeID FROM student WHERE studentName='武松'

-- 02.根據年級編號 取 年級名稱
SELECT gradeName FROM grade WHERE GradeID=???

SELECT gradeName FROM grade WHERE GradeID
=(SELECT GradeID FROM student WHERE studentName='武松')


-- 查詢年級編號是1或者2 的 所有學生列表
SELECT * FROM student WHERE gradeId IN(1,2)

-- 查詢 年級名稱是 大一或者大二的所有學生信息
-- 學生表 中沒有 年級名稱 但是有年級編號
-- 01.根據 年級名稱 查詢出 編號

SELECT gradeID FROM grade WHERE gradeName IN('大一','大二');
-- 02.再根據id查詢學生信息
SELECT * FROM student WHERE
gradeID
IN (SELECT gradeID FROM grade WHERE gradeName IN('大一','大二'))

-- 查詢參加 最近一次 高等數學-1 考試成績的學生的最高分和最低分

-- 01. 發現成績表中 沒有 科目名稱 只有編號!根據名稱取編號

SELECT SubjectNo FROM `subject` WHERE
subjectName='高等數學-1'

-- 02.查詢最近一次 高等數學-1 考試的時間

SELECT MAX(ExamDate) FROM result
WHERE
SubjectNo=(SELECT SubjectNo FROM `subject` WHERE
subjectName='高等數學-1')

-- 所有最近考試的成績
SELECT * FROM result
WHERE ExamDate='2013-11-11 16:00:00'

-- 03.開始獲取最高分和 最低分
SELECT MAX(studentResult) AS 最高分,
MIN(studentResult) AS 最低分
FROM result
WHERE SubjectNo=(SELECT SubjectNo FROM `subject` WHERE
subjectName='高等數學-1')
AND ExamDate=
(SELECT MAX(ExamDate) FROM result
WHERE
SubjectNo=(SELECT SubjectNo FROM `subject` WHERE
subjectName='高等數學-1'))

 


-- 查詢 高等數學-1 考試成績是 60 分的 學生信息

-- 01.根據 科目名稱 獲取 科目編號
SELECT SubjectNo FROM `subject`
WHERE SubjectName='高等數學-1'

-- 02.根據編號 查詢 所有的學生編號
SELECT studentNo FROM result
WHERE SubjectNo=(SELECT SubjectNo FROM `subject`
WHERE SubjectName='高等數學-1')
AND StudentResult=60; -- 成績=60

-- 03.查詢學生信息
SELECT * FROM student
WHERE studentNo IN
(SELECT studentNo FROM result
WHERE SubjectNo=(SELECT SubjectNo FROM `subject`
WHERE SubjectName='高等數學-1')
AND StudentResult=60)


-- 使用in替換 等於(=)的子查詢語句!
-- in后面的子查詢可以返回多條記錄!


-- not in :不在某個范圍之內

-- 查詢未參加 “高等數學-1” 課程最近一次考試的在讀學生名單
-- 01.根據 科目名稱 獲取 科目編號

SELECT SubjectNo FROM `subject`
WHERE SubjectName='高等數學-1'

-- 02.獲取最近一次考試時間
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=
(SELECT SubjectNo FROM `subject`
WHERE SubjectName='高等數學-1')

-- 03.查詢沒參加的學生編號
SELECT studentNo,StudentName FROM student
WHERE studentNo NOT IN
(
SELECT StudentNo FROM result
WHERE SubjectNo=
(SELECT SubjectNo FROM `subject`
WHERE SubjectName='高等數學-1')
AND ExamDate=
(SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=
(SELECT SubjectNo FROM `subject`
WHERE SubjectName='高等數學-1'))
)


高級查詢


SELECT * FROM `grade`INNER JOIN `student`
笛卡爾積 :兩個表數據的乘積!


兩個表的內連接
SELECT * FROM `grade`INNER JOIN `student`
ON grade.`GradeID`=student.`GradeId`

on 兩個表通過那一列建立關聯關系

-- exists的使用
-- 01. 用於檢測表,數據庫等等 是否存在
-- 02. 檢查子查詢中是否會返回一行數據!其實子查詢並不返回任何數據!
值返回 true或者false!


SELECT * FROM Student WHERE EXISTS(SELECT NULL)
SELECT * FROM Student WHERE EXISTS(SELECT 9*9)
SELECT * FROM Student WHERE EXISTS(SELECT StudentName FROM student)


SELECT * FROM Student
WHERE EXISTS(SELECT studentName FROM Student WHERE studentName='張三')

SELECT * FROM Student WHERE studentName IN(SELECT studentName FROM Student)

-- in 效果等同於 =any
SELECT * FROM Student WHERE
studentName =ANY(SELECT studentName FROM Student)


-- all 大於子查詢語句中的 最大值 >(1,2,3) >3
SELECT * FROM student
WHERE studentNo>ALL
(SELECT studentNo FROM student WHERE studentNo IN(1003,1004,1005))

-- any 大於子查詢語句中的 最小值 >(1,2,3) >1
SELECT * FROM student
WHERE studentNo>ANY
(SELECT studentNo FROM student WHERE studentNo IN(1003,1004,1005))

-- some 和any功能一樣
SELECT * FROM student
WHERE studentNo>SOME
(SELECT studentNo FROM student WHERE studentNo IN(1003,1004,1005))


-- 檢查“高等數學-1” 課程最近一次考試成績
-- 如果有 80分以上的成績,顯示分數排在前5名的學員學號和分數

-- 不使用exists


-- 01.查詢“高等數學-1” 課程 對應的編號
SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'

-- 02.查詢最近的考試成績
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1')

-- 03. 在02的基礎上 加條件 成績大於80
SELECT * FROM result
WHERE ExamDate=
(SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'))
AND StudentResult>80

-- 04.優化
SELECT studentNo,StudentResult FROM result
WHERE ExamDate=
(SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'))
AND StudentResult>80
ORDER BY StudentResult DESC
LIMIT 0,5

 

-- 使用exists
-- 檢查“高等數學-1” 課程最近一次考試成績
-- 如果有 80分以上的成績,顯示分數排在前5名的學員學號和分數

-- 01.查詢“高等數學-1” 課程 對應的編號
SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'

-- 02.查詢最近的考試成績
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1')


-- 03.查詢學號和成績
SELECT StudentNo,StudentResult FROM result
WHERE EXISTS
(
SELECT * FROM result
WHERE subjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1')
)
AND StudentResult>80
)
AND subjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1')
)
ORDER BY StudentResult DESC
LIMIT 0,5

 


-- not exists

-- 檢查“高等數學-1”課程最近一次考試成績
-- 如果全部未通過考試(60分及格),認為本次考試偏難,計算的該次考試平均分加5分


-- 01.查詢“高等數學-1” 課程 對應的編號
SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'

-- 02.查詢最近的考試成績
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1')

 

-- 03.查詢成績大於60的 反着來
SELECT StudentResult FROM result
WHERE StudentResult>60
AND SubjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1')
)

 


-- 04. 如果全部未通過考試,考試平均分加5分
SELECT AVG(StudentResult)+5 FROM result
WHERE NOT EXISTS
(
SELECT StudentResult FROM result
WHERE StudentResult>60
AND SubjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1')
)
)
AND SubjectNo=(
SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1'
)
AND ExamDate=(
SELECT MAX(ExamDate) FROM result
WHERE SubjectNo=(SELECT subjectNo FROM `subject`
WHERE SubjectName='高等數學-1')
)

 

-- 如果有 年級名稱是大二 的學生,就 查詢出 年級名稱是大一的 所有學生信息

-- 01.先查詢出 對應的年級編號
SELECT GradeId FROM grade WHERE GradeName='大一'
SELECT GradeId FROM grade WHERE GradeName='大二'

-- 02.在學生表中是否存在 年級名稱是大二 的學生
SELECT * FROM student WHERE gradeID=(
SELECT GradeId FROM grade WHERE GradeName='大二'
)

-- 03.如果有查詢出 年級名稱是大一的 所有學生信息
SELECT * FROM student
WHERE EXISTS
(
SELECT * FROM student WHERE gradeID=(
SELECT GradeId FROM grade WHERE GradeName='大二'
)
)
AND GradeId=(
SELECT GradeId FROM grade WHERE GradeName='大一'
)

 

-- 使用子查詢的注意事項
-- 01.任何允許使用表達式的地方都可以使用子查詢
-- 02.只出現在子查詢中但是沒有在父查詢中出現的列,結果集中的列不能包含!

sql優化

使用exists 代替 in
使用not exists 代替not in

exists 只返回true或者false.不返回結果集
in 返回結果集

-- 查詢姓李的學生信息 % 代表0或者多個字符 _代表一個字符
SELECT * FROM student WHERE StudentName LIKE '李%'
SELECT * FROM student WHERE StudentName LIKE '李_'

-- 使用in完成上述代碼
SELECT * FROM student WHERE StudentName IN(
SELECT studentName FROM student WHERE StudentName LIKE '李%')
-- in(多條數據--》返回結果集)

-- 使用exists替換
SELECT * FROM student WHERE EXISTS(
SELECT studentName FROM student)
AND StudentName LIKE '李%'
-- exists(有沒有數據)

 


-- 統計每門課程平均分各是多少 GROUP BY 列名 分組
SELECT subjectno,AVG(studentresult) FROM result
GROUP BY subjectno

-- 查詢出課程平均分大於60的課程編號 和 平均分

SELECT subjectno,AVG(studentresult) FROM result
GROUP BY subjectno
HAVING AVG(studentresult)>60 -- 分組之后的條件

-- 統計每門課程平均分各是多少 降序排列
SELECT subjectno,AVG(studentresult) FROM result
GROUP BY subjectno
ORDER BY AVG(studentresult) DESC

-- 如果成績相同 再按照 課程編號 升序排序
SELECT subjectno,AVG(studentresult) FROM result
GROUP BY subjectno
ORDER BY AVG(studentresult) DESC,subjectno

-- 分組統計每個年級的 男女人數

SELECT gradeid 年級編號,sex 性別,COUNT(sex) 人數
FROM student
GROUP BY gradeid,sex


-- 創建表
CREATE TABLE IF NOT EXISTS examTest(
id INT(2) NOT NULL,
sex VARCHAR(20)
)

-- 同時新增多條數據
INSERT INTO examTest VALUES(1,'男'),(2,'男'),(3,'女'),(4,NULL);

SELECT sex AS '性別',COUNT(sex) AS '人數' FROM examTest
WHERE sex IS NOT NULL
GROUP BY sex
ORDER BY COUNT(sex) DESC


SELECT sex AS '性別',COUNT(sex) AS '人數' FROM examTest
GROUP BY sex
HAVING sex IS NOT NULL
ORDER BY COUNT(sex) DESC

SELECT sex AS '性別',COUNT(sex) AS '人數' FROM examTest
WHERE sex IN('男','女')
GROUP BY sex
ORDER BY COUNT(sex) DESC

 


-- 創建表
CREATE TABLE IF NOT EXISTS mytable(
`name` VARCHAR(10) NOT NULL,
class INT(4) NOT NULL,
sorce DOUBLE NOT NULL
)
-- 插入數據
INSERT INTO mytable
VALUES
('小黑1',1,88),('小黑2',1,80),
('小黑3',1,68),('小黑4',1,70),
('小黑5',1,98),('小黑6',1,90),
('小白1',2,88),('小白2',2,80),
('小白3',2,68),('小白4',2,70),
('小白5',2,98),('小白6',2,90)

-- 找出表中分數的前三名
SELECT * FROM mytable
ORDER BY sorce DESC
LIMIT 0,3

-- 找出每個班級的前三名
SELECT * FROM mytable t1
WHERE
(
SELECT COUNT(1) FROM mytable t2
WHERE t1.`sorce`<t2.`sorce`
AND t1.class=t2.`class`
)<3
ORDER BY class,sorce DESC

 


內連接 :通過匹配兩個表中公共列,找到 公共的行!

左外連接: 以左表為准,右表中沒有數據返回null

右外連接: 以右表為准,左表中沒有數據返回null

-- 輸出學生姓名以及對應的年級名稱 內連接
SELECT StudentName,GradeName FROM student INNER JOIN grade
ON student.`GradeId`=grade.`GradeID`

-- 隱式內連接
SELECT StudentName,GradeName FROM student,grade
WHERE student.`GradeId`=grade.`GradeID`

-- 查詢 考試 課程編號是1的 學生姓名 以及年級名稱 和科目名稱以及成績
01.
SELECT s.StudentName,GradeName,SubjectName ,studentResult FROM student s
INNER JOIN grade g ON (s.gradeID=g.gradeID)
INNER JOIN `subject` b ON(g.gradeID=b.gradeID)
INNER JOIN result r ON (b.subjectNo=r.subjectNo)
AND s.studentNo=r.studentNo
AND b.subjectNo=1


02.
SELECT StudentName,GradeName,SubjectName ,studentResult FROM
student s,grade g,`subject` b,result r
WHERE s.gradeID=g.gradeID
AND g.gradeID=b.gradeID
AND s.studentNo=r.studentNo
AND b.subjectNo=r.subjectNo
AND b.subjectNo=1

-- 查詢的列 不在同一個表中! 必須使用連接查詢!建立關聯關系!

-- 臨時表只有當前連接可見 隨連接的關閉 自動刪除
-- 臨時表的增刪改 不會影響到 真表
CREATE TEMPORARY TABLE myStudent
(SELECT * FROM student)

SELECT * FROM myStudent
DELETE FROM mystudent -- 臨時表的數據刪除
SELECT * FROM student -- 不會影響到真表

自連接

-- 自連接 把一個表當成多個表來使用 關鍵是 使用別名
SELECT * FROM teacher
-- 查詢 老師3 的姓名和 對應的 導師的姓名
-- t1 老師 t2 導師 老師的導師編號=== 導師的編號
SELECT t1.`name` AS a,t2.`name` AS 導師姓名 FROM teacher t1,teacher t2
WHERE t1.`name`='老師3'
AND t2.id=t1.tid


事務


事務的特性 ACID

事務:一條或者多條sql語句的集合!

原子性 (Atomicity):在事務中的操作,要么都執行,要么都不執行!
一致性(Consistency):事務必須保證數據庫從一個一致性的狀態變成另一個一致性的狀態!
隔離性(Isolation):每個事務之間互不干擾!哪怕是並發執行也不干擾!
持久性(Durability):事務一旦被改變,那么對數據庫中數據的影響是永久性的!


模擬 銀行轉賬!

-- 創建數據庫
CREATE DATABASE myBank;
-- 切換指定的數據庫
USE myBank;
-- 創建表
CREATE TABLE IF NOT EXISTS bank(
customerName VARCHAR(10) NOT NULL COMMENT '用戶名',
currentMoney DECIMAL(10,2) NOT NULL COMMENT '賬戶余額'
);
-- 插入數據
INSERT INTO bank VALUES('小黑',50000),('小白',500000);


-- 小黑 給小白 轉賬10000
-- 修改兩條數據
-- 01.小黑-10000
-- 02.小白+10000


UPDATE bank SET currentMoney=currentMoney-10000
WHERE customerName='小黑';
-- 故意寫錯字段名稱 讓02 報錯
UPDATE bank SET currentMoneysss=currentMoney+10000
WHERE customerName='小白';

-- 開啟事務 START TRANSACTION 或者 BEGIN
-- 01.02 為一個事務
BEGIN
UPDATE bank SET currentMoney=currentMoney-10000
WHERE customerName='小黑';
UPDATE bank SET currentMoneysss=currentMoney+10000
WHERE customerName='小白';
-- 事務回滾 ROLLBACK
-- 提交事務 COMMIT

UPDATE bank SET currentMoney=500000
WHERE customerName='小黑';
-- 證明mysql是默認提交事務的!

SET autocommit=0(關閉事務自動提交) | 1(開啟事務自動提交)

-- 關閉事務自動提交
SET autocommit=0;

BEGIN; -- 開啟事務
UPDATE bank SET currentMoney=currentMoney-10000
WHERE customerName='小黑';
UPDATE bank SET currentMoney=currentMoney+10000
WHERE customerName='小白';
COMMIT; -- 手動提交事務
UPDATE bank SET currentMoney=10000;
ROLLBACK; -- 事務回滾

SET autocommit=1; -- 恢復自動提交

 

事務的隔離級別


為什么 引入了 事務隔離級別??

在數據庫操作中,為了有效保證並發讀取數據的正確性,提出的事務隔離級別。

 

更新丟失
兩個事務都同時更新一行數據,一個事務對數據的更新把另一個事務對數據的更新覆蓋了。這是因為系統沒有執行任何的鎖操作,因此並發事務並沒有被隔離開來。
臟讀
一個事務讀取到了另一個事務未提交的數據操作結果。這是相當危險的,因為很可能所有的操作都被回滾。

不可重復讀
不可重復讀(Non-repeatable Reads):一個事務對同一行數據重復讀取兩次,但是卻得到了不同的結果。
包括以下情況:
(1)虛讀:事務T1讀取某一數據后,事務T2對其做了修改,當事務T1再次讀該數據時得到與前一次不同的值。
(2) 幻讀(Phantom Reads):事務在操作過程中進行兩次查詢,第二次查詢的結果包含了第一次查詢中未出現的數據或者缺少了第一次查詢中出現的數據(這里並不要求兩次查詢的SQL語句相同)。這是因為在兩次查詢過程中有另外一個事務插入數據造成的。

 

 

解決方案: 使用事務隔離級別

案例一: 允許臟讀取


-- 查詢mysql默認的事務隔離級別 (可重復讀取 repeatable-read )
SELECT @@tx_isolation;

-- 修改事務 隔離級別
SET tx_isolation='read-uncommitted'; 允許臟讀取,不允許更新丟失


案例二: 禁止更新丟失


在doc窗口中
bengin
update 一張表的數據
不回滾 也不 提交

在 sqlyong中
操作同一張表,發現不允許,在等待!

 


未授權讀取
也稱為讀未提交(Read Uncommitted):允許臟讀取,但不允許更新丟失。如果一個事務已經開始寫數據,則另外一個事務則不允許同時進行寫操作,但允許其他事務讀此行數據。該隔離級別可以通過“排他寫鎖”實現。


授權讀取
也稱為讀提交(Read Committed):允許不可重復讀取,但不允許臟讀取。這可以通過“瞬間共享讀鎖”和“排他寫鎖”實現。讀取數據的事務允許其他事務繼續訪問該行數據,但是未提交的寫事務將會禁止其他事務訪問該行。


可重復讀取(Repeatable Read)
可重復讀取(Repeatable Read):禁止不可重復讀取和臟讀取,但是有時可能出現幻讀數據。這可以通過“共享讀鎖”和“排他寫鎖”實現。讀取數據的事務將會禁止寫事務(但允許讀事務),寫事務則禁止任何其他事務。


序列化(Serializable)
序列化(Serializable):提供嚴格的事務隔離。它要求事務序列化執行,事務只能一個接着一個地執行,不能並發執行。僅僅通過“行級鎖”是無法實現事務序列化的,必須通過其他機制保證新插入的數據不會被剛執行查詢操作的事務訪問到。


隔離級別越高,越能保證數據的完整性和一致性,但是對並發性能的影響也越大。對於多數應用程序,可以優先考慮把數據庫系統的隔離級別設為Read Committed。它能夠避免臟讀取,而且具有較好的並發性能。盡管它會導致不可重復讀、幻讀和第二類丟失更新這些並發問題,在可能出現這類問題的個別場合,可以由應用程序采用悲觀鎖或樂觀鎖來控制。


博文連接 :http://lvwenwen.iteye.com/blog/2045951


視圖:

-- 視圖 是一張虛擬的表
01.表示一張表的部分數據或者是多張表的綜合數據!
02.結構和數據都是建立在對真表的查詢基礎之上的!
03.視圖中存放的數據其實就是對真實表的引用!
對視圖中的數據進行添加,更新刪除都會影響到真實的表!
04.一個真實的表可以創建N個視圖!
05.如果視圖關聯了多表,不允許增 刪!單表可以增刪改
06.視圖一般都是使用查詢!

-- 創建一個視圖 只獲取 學生姓名 編號 以及考試成績
CREATE VIEW view_student_result
AS
SELECT s.studentNo 學生編號,studentName 學生姓名,
studentResult 考試成績
FROM student s,result r
WHERE s.`studentNo`=r.`studentNo`
-- 查詢視圖中的內容
SELECT * FROM view_student_result
-- 查詢mysql數據庫中所有的視圖
SELECT * FROM information_schema.views;
-- 刪除視圖
DROP VIEW view_student_result;

-- 創建一個表的視圖 學生姓名,地址,手機號
CREATE VIEW view_student
AS
SELECT studentName 學生姓名,address 地址,phone 手機號
FROM student

-- 查詢視圖(只是為了查詢(看) 不是為了操作)
虛擬的表 方便 簡潔
存儲的數據是真表的引用 改變試圖數據 真表數據也會改變
單表可以增刪改 多表可以改 不可以增加 刪除
SELECT * FROM view_student

 


-- 索引:是一種有效組合數據的方式!目的就是快速或者某個記錄!
提高了數據庫的檢索速度!
索引是一個文件
mysql索引按存儲類型分2種:
01.B-樹索引(BTREE):INNODB,MyISAM 支持
02.哈希索引 memory


01.普通索引:允許在定義為索引的列中 出現 重復值和空值!
02.唯一索引:索引列不允許出現重復值,但是可以出現一個空值!
03.主鍵索引:創建主鍵的時候,系統會默認創建一個主鍵索引!唯一!不能為空!
04.復合索引:(name+id)只有復合索引左邊的被使用,索引才有效 將我們的多個列組合起來!(name,sid)姓名和身份證號!
05.全文索引:允許值的全文查詢!允許空值和重復值!適合在一個內容比較多的列!text!
06.空間索引:對空間數據類型的列建立的索引!記錄位置的一列設置為空間索引。


-- 查詢指定表的索引
SHOW INDEX FROM student;
TABLE:索引所在的表
Non_unique:索引是否唯一 0:唯一 1:不唯一
key_name:索引名稱
seq_in_index:該列在索引中的位置
column_name:定義所用的列名稱
null:該列是否為空
index_type:索引類型


-- 給姓名增加 普通索引
CREATE INDEX index_studentName
ON student(studentName);

-- 給學生姓名和身份證號 增加 組合索引
CREATE INDEX index_name_sid
ON student(studentName,identityCard)


-- 刪除索引
DROP INDEX index_name_sid ON student;

DROP INDEX index_studentName ON student;

-- 創建索引的原則
01.經常被查詢的列
02.經常用作選擇的列
03.經常排序,分組的列
04.經常用作連接的列(主鍵/外鍵)


使用索引時的注意事項:
01.查詢時減少使用*返回全部的列,不要返回不需要的列!
02.索引盡量要少,在字節數小的列上建立索引!
03.where字句中有多個條件表達式的時候,包含索引的列要放在其他表達式之前!
04.在order by的字句中避免使用表達式!


sql 語句的執行 順序

5.查詢 select
1.找表 from
2.條件 where
3.分組 group by
4.條件 having
6.排序 order by
7.分頁 limit

數據庫的恢復和備份

為保證賬戶密碼安全,命令中可不寫密碼,但參數“-p”必須有,回車后根據提示寫密碼!

數據庫的備份

cmd進入命令行

mysqldump -u用戶名 -p 數據庫名稱 >指定的文件


數據庫的恢復

前提是必須要有對應的數據庫

mysql -u用戶名 -p <指定的文件

1. mysql為DOS命令
2.在執行該語句之前,必須在MySQL服務器中創建新數據庫,如果不存在恢復數據庫過程將會出錯

 


軟件項目開發周期中數據庫設計
01.需求分析階段:分析客戶的業務和數據處理需求
02.概要設計階段:設計數據庫的E-R模型圖,確認需求信息的正確和完整
03.詳細設計階段:應用三大范式審核數據庫結構
04.代碼編寫階段:物理實現數據庫,編碼實現應用
05.軟件測試階段:……
06.安裝部署:……


數據庫設計步驟:

01.收集信息
02.標識實體
03.標識每個實體的屬性
04.標識實體之間的關系
E-R圖:

01.矩形 實體
02.橢圓形 屬性
03.菱形 實體與實體的關系

1 : 一對一
1:N: 一對多
M:N: 多對多


必須滿足 三大范式

第一范式確保每列的原子性
第二范式要求每個表只描述一件事情
第三范式要求表中各列必須和主鍵直接相關,不能間接相關


JDBC
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.SQLException;

public class DBHelper {
public static final String url = "jdbc:mysql://127.0.0.1/student";
public static final String name = "com.mysql.jdbc.Driver";
public static final String user = "root";
public static final String password = "root";

public Connection conn = null;
public PreparedStatement pst = null;

public DBHelper(String sql) {
try {
Class.forName(name);//指定連接類型
conn = DriverManager.getConnection(url, user, password);//獲取連接
pst = conn.prepareStatement(sql);//准備執行語句
} catch (Exception e) {
e.printStackTrace();
}
}

public void close() {
try {
this.conn.close();
this.pst.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
}

import java.sql.ResultSet;
import java.sql.SQLException;

public class Demo {

static String sql = null;
static DBHelper db1 = null;
static ResultSet ret = null;

public static void main(String[] args) {
sql = "select *from stuinfo";//SQL語句
db1 = new DBHelper(sql);//創建DBHelper對象

try {
ret = db1.pst.executeQuery();//執行語句,得到結果集
while (ret.next()) {
String uid = ret.getString(1);
String ufname = ret.getString(2);
String ulname = ret.getString(3);
String udate = ret.getString(4);
System.out.println(uid + "\t" + ufname + "\t" + ulname + "\t" + udate );
}//顯示數據
ret.close();
db1.close();//關閉連接
} catch (SQLException e) {
e.printStackTrace();
}
}

}

static void Main(string[] args)
{
string url = "server=127.0.0.1;user=root;database=student;port=3306;password=root;";//指明要連接的數據庫地址,用戶名,數據庫名,端口,密碼
MySqlConnection conn = new MySqlConnection(url);//實例化連接
conn.Open();//打開連接

string sta = "select * from stuinfo";//執行一個簡單的語句
MySqlCommand comm = new MySqlCommand(sta, conn);
MySqlDataReader reader = comm.ExecuteReader();//用MySqlDataReader接收執行結果
while (reader.Read())
{
Console.WriteLine(reader.GetString(0) + " " + reader.GetString(1) + " " + reader.GetString(2) +" " + reader.GetString(3));//讀出查詢的結果
}
Console.ReadKey();
reader.Close();
conn.Close();//關閉連接
}

Java之dao模式詳解及代碼示例

這篇文章主要介紹了Java之dao模式詳解及代碼示例,具有一定參考價值,需要的朋友可以了解下。

什么是dao模式?

DAO(Data Access Object)顧名思義是一個為數據庫或其他持久化機制提供了抽象接口的對象,在不暴露底層持久化方案實現細節的前提下提供了各種數據訪問操作。在實際的開發中,應該將所有對數據源的訪問操作進行抽象化后封裝在一個公共API中。用程序設計語言來說,就是建立一個接口,接口中定義了此應用程序中將會用到的所有事務方法。在這個應用程序中,當需要和數據源進行交互的時候則使用這個接口,並且編寫一個單獨的類來實現這個接口,在邏輯上該類對應一個特定的數據存儲。DAO模式實際上包含了兩個模式,一是Data Accessor(數據訪問器),二是Data Object(數據對象),前者要解決如何訪問數據的問題,而后者要解決的是如何用對象封裝數據。

一、信息系統的開發架構

客戶層-------顯示層-------業務層---------數據層---------數據庫

1.客戶層:客戶層就是客戶端,簡單的來說就是瀏覽器。

2.顯示層:JSP/Servlet,用於給瀏覽器顯示。

3.業務層:對於數據層的原子操作進行整合。

4.數據層:對於數據庫進行的原子操作,增加、刪除等;

二、DAO(Data Access Object)介紹

DAO應用在數據層那塊(對於數據庫進行的原子操作,增加、刪除等;),用於訪問數據庫,對數據庫進行操作的類。

三、DAO設計模式的結構

DAO設計模式一般分為幾個類:

1.VO(Value Object):一個用於存放網頁的一行數據即一條記錄的類,比如網頁要顯示一個用戶的信息,則這個類就是用戶的類。

2.DatabaseConnection:用於打開和關閉數據庫。

3.DAO接口:用於聲明對於數據庫的操作。

4.DAOImpl:必須實現DAO接口,真實實現DAO接口的函數,但是不包括數據庫的打開和關閉。

5.DAOProxy:也是實現DAO接口,但是只需要借助DAOImpl即可,但是包括數據庫的打開和關閉。

6.DAOFactory:工廠類,含有getInstance()創建一個Proxy類。

四、DAO的好處

DAO的好處就是提供給用戶的接口只有DAO的接口,所以如果用戶想添加數據,只需要調用create函數即可,不需要數據庫的操作。

五、DAO包命名

對於DAO,包的命名和類的命名一定要有層次。

1.Emp.Java

package org.vo;

import java.util.*;

public class Emp{

private int empno;

private String ename;

private String job;

private Date hireDate;

private float sal;

public Emp(){

}

public int getEmpno(){

return empno;

}

public void setEmpno(int empno){

this.empno = empno;

}

public String getEname(){

return ename;

}

public void setEname(String ename){

this.ename = ename;

}

public Date getHireDate(){

return hireDate;

}

public void setHireDate(Date hireDate){

this.hireDate = hireDate;

}

public float getSal(){

return sal;

}

public void setSal(float sal){

this.sal = sal;

}

public String getJob(){

return job;

}

public void setJob(String job){

this.job = job;

}

}

2.DatabaseConnection.java

package org.dbc;

import java.sql.*;

public class DatabaseConnection{

private Connection con = null;

private static final String DRIVER = "com.mysql.jdbc.Driver";

private static final String USER = "root";

private static final String URL = "jdbc:mysql://localhost:3306/mldn";

private static final String PASS = "12345";

public DatabaseConnection()throws Exception{

Class.forName(DRIVER);

con = DriverManager.getConnection(URL,USER,PASS);

}

public Connection getConnection()throws Exception{

return con;

}

public void close()throws Exception{

if(con!=null){

con.close();

}

}

}

3.IEmpDAO.java

package org.dao;

import java.util.List;

import org.vo.*;

public interface IEmpDAO{

public boolean doCreate(Emp emp)throws Exception;

public List<Emp> findAll()throws Exception;

public Emp findById(int empno)throws Exception;

}

4.EmpDAOImpl.java

package org.dao.impl;

import org.dao.*;

import java.sql.*;

import org.vo.*;

import java.util.*;

public class EmpDAOImpl implements IEmpDAO{

private Connection con;

private PreparedStatement stat = null;

public EmpDAOImpl(Connection con){

this.con = con;

}

public boolean doCreate(Emp emp)throws Exception{

String sql = "INSERT INTO emp(empno,ename,job,hiredate,sal) VALUES(?,?,?,?,?)";

stat = con.prepareStatement(sql);

stat.setInt(1,emp.getEmpno());

stat.setString(2,emp.getEname());

stat.setString(3,emp.getJob());

stat.setDate(4,new java.sql.Date(emp.getHireDate().getTime()));

stat.setFloat(5,emp.getSal());

int update = stat.executeUpdate();

if(update>0){

return true;

}

else{

return false;

}

}

public List<Emp> findAll()throws Exception{

String sql = "SELECT empno,ename,job,hiredate,sal FROM emp";

stat = con.prepareStatement(sql);

ResultSet rs = stat.executeQuery();

Emp emp = null;

List<Emp> list = new ArrayList<Emp>();

while(rs.next()){

int empno = rs.getInt(1);

String ename = rs.getString(2);

String job = rs.getString(3);

float sal = rs.getFloat(5);

emp = new Emp();

emp.setEmpno(empno);

emp.setEname(ename);

emp.setJob(job);

emp.setHireDate(rs.getDate(4));

emp.setSal(sal);

list.add(emp);

}

return list;

}

public Emp findById(int empno)throws Exception{

String sql = "SELECT empno,ename,job,hiredate,sal FROM emp WHERE empno=?";

stat = con.prepareStatement(sql);

stat.setInt(1,empno);

ResultSet rs = stat.executeQuery();

Emp emp = null;

if(rs.next()){

String ename = rs.getString(2);

String job = rs.getString(3);

float sal = rs.getFloat(5);

emp = new Emp();

emp.setEmpno(empno);

emp.setEname(ename);

emp.setJob(job);

emp.setHireDate(rs.getDate(4));

emp.setSal(sal);

}

return emp;

}

}

5.EmpDAOProxy.java

package org.dao.impl;

import org.dao.*;

import java.sql.*;

import org.vo.*;

import java.util.*;

import org.dbc.*;

public class EmpDAOProxy implements IEmpDAO{

private DatabaseConnection dbc;

private IEmpDAO dao = null;

public EmpDAOProxy()throws Exception{

dbc = new DatabaseConnection();

dao = new EmpDAOImpl(dbc.getConnection());

}

public boolean doCreate(Emp emp)throws Exception{

boolean flag = false;

if(dao.findById(emp.getEmpno())==null){

flag = dao.doCreate(emp);

}

dbc.close();

return flag;

}

public List<Emp> findAll()throws Exception{

List<Emp>list = dao.findAll();

dbc.close();

return list;

}

public Emp findById(int empno)throws Exception{

Emp emp = dao.findById(empno);

dbc.close();

return emp;

}

}

6.DAOFactory.java

package org.dao.factory;

import org.dao.*;

import java.sql.*;

import org.vo.*;

import java.util.*;

import org.dbc.*;

import org.dao.impl.*;

public class DAOFactory{

public static IEmpDAO getInstance(){

IEmpDAO dao = null;

try{

dao = new EmpDAOProxy();

}

catch(Exception e){

e.printStackTrace();

}

return dao;

}

}

7.TestDAO.java

package org.dao.test;

import org.dao.factory.*;

import org.vo.*;

import org.dao.*;

public class TestDAO{

public static void main(String args[])throws Exception{

Emp emp = null;

for(int i=0;i<5;i++){

emp = new Emp();

emp.setEmpno(i);

emp.setEname("xiazdong-"+i);

emp.setJob("stu-"+i);

emp.setHireDate(new java.util.Date());

emp.setSal(500*i);

DAOFactory.getInstance().doCreate(emp);

}

}

}

通過DAO設計模式,可以在JSP中屏蔽了數據庫連接的操作,達到JSP只負責顯示的效果。

 

String sql = "INSERT INTO emp_table(ename,job,sal,hiredate) VALUES(?,?,?,?)";

stat = (PreparedStatement) con.prepareStatement(sql);

stat.setString(1,emp.getEname());

stat.setString(2,emp.getJob());

stat.setFloat(3,emp.getSal());

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM