狂神說Java個人筆記-MySQL


2MySQL

1.連接數據庫

命令行連接!

mysql -uroot -p123456 ---連接數據庫

sc delete mysql; 清空服務

update mysql.user set anthentication_string=password('123456')where user='root' and Host='localhost';--修改用戶密碼
flush privileges; --刷新權限
--所有的語句都是用;結尾
show databases; --查看所有的數據庫
mysql> use school --切換數據庫 use 數據庫名
Database changed
show tables; --查看數據庫中所有的表
describe student(表名); --顯示數據庫中所有的表的信息
create database westos; --創建一個數據庫
exit; --退出連接

--單行注釋(SQL的本來的注釋)
/*   SQL多行注釋
hello
*/

數據庫xxx語言 CRUD 增刪改查!

DDL 定義

DML 操作

DQL 查詢

DCL 控制

2.操作數據庫

操作數據庫》操作數據庫中的表》操作數據庫表的數據

mysql中的關鍵字不區分大小寫

2.1操作數據庫

1.創建數據庫

CREATE DATABASE [if not EXISTS] person; --創建表,語句沒有中括號,中括號中的內容為如果沒有這個表的情況下創建表

 

2.刪除數據庫

DROP DATABASE if exists person;
--如果存在就刪除

3.使用數據庫

--table鍵的上面,如果你的表名或者字段名是一個特殊字符,就需要``括起來
use `school`

4.查看數據庫

show databases --查看所有的數據庫

2.2數據庫的列類型

數值

  • tinyint 十分小的數據 1個字節

  • smallint 較小的數據 2個字節

  • mediumint 中等大小數據 3個字節

  • int 標准的整數 4個字節 常用 int

  • bigint 較大的數據 8個字節

  • float 浮點數 4個字節

  • double 浮點數 8個字節(精度有問題!)

  • decimal 字符串形式的浮點數,用於金融計算的時候,一般用decimal

字符串

  • char 字符串固定大小的 0-255

  • varchar 可變字符串 0-65535 常用的 String

  • tingtest 微型文本 2^8-1

  • text 文本串 2^16-1 保存大文本

時間日期

  • date YYYY--MM-DD 日期

  • time HH:MM:ss 時間格式

  • datetime date YYYY--MM-DD HH:MM:ss 最常用的時間格式

  • timestamp 時間戳 1970.1.1到現在的毫秒數!

  • year 年份表示

null

  • 沒有值,未知

  • ==注意,不要使用NUll進行運算,結果為NUll

2.3數據庫的字段屬性(重點)

Unsigned 無符號:

  • 無符號的整數

  • s聲明了該列不能聲明為負數

zerofill 0填充:

  • 0填充的

  • 不足的位數,使用0來填充,int(3),5 --005

auto_increment自增:

  • 通常理解為自增,自動在上一條記錄的基礎上+1(默認)

  • 通常用來設計唯一的主鍵·index,必須是整數類型

  • 可以自定義設計主鍵自增的起始值和步長

非空 NUll not null

  • 假設設置為 not null,如果不給它賦值,就會報錯!

  • NULL,如果不填寫值,默認就是null!

默認:

  • 設置默認的值!

  • sex,默認值為男,如果不指定該列的值,則會有默認的值!

/* 每一個表,都必須存在以下五個字段!未來做項目用,表示一個記錄存在意義。
id         主鍵
`vestion`   樂觀鎖
is_delete   偽刪除
gmt_create 創建時間
gmt_update 修改時間
*/

 

2.4創建數據庫表(重點)

-- 目標:創建一個school數據庫
-- 創建學生表(列,字段) 使用SQL 創建
-- 學號 int 登陸密碼 varchar(20)姓名,性別varchar(2),出生日期(datetime),家庭住址email
-- 注意點,使用英文(),表的名稱和字段 盡量使用 ``括起來
-- AUTO_INCREMENT 自增
-- 字符串使用 單引號括起來!
-- 所有的語句后面加,(英文的),最后一個不用加
-- PRIMARY KEY(`id`) 主鍵是唯一的
CREATE TABLE `school`.`student` (
`id` INT(4) UNSIGNED ZEROFILL NOT NULL auto_increment COMMENT '學號',
`name` VARCHAR(20) NOT NULL DEFAULT '匿名' COMMENT '姓名',
`pwd` varchar(20) NOT NULL DEFAULT '123456' COMMENT '密碼',
`sex` VARCHAR(2) NOT NULL DEFAULT '男' COMMENT '性別',
`birthday` datetime DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(60) DEFAULT NULL COMMENT '住址',
`email` VARCHAR(50) default NULL COMMENT '郵箱',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT charset=utf8;
/*
格式:
create table `數據庫名`.`表名` (
·字段名· [類型varchar][屬性Unsigned 無符號   ][注釋 comment '學號'],
字段名· [類型varchar][屬性zerofill 0填充][注釋 comment '學號'],
字段名· [類型varchar][屬性 auto_increment自增 ][注釋 comment '學號'],
......
字段名· [類型varchar][屬性][注釋 comment '學號'],
PRIMARY KEY(`id`)
)[設置表類型 默認 ENGINE=INNODB][設置字符集charset=utf8]


*/

 

常用命令

SHOW create TABLE student; --查看student數據表定義的語句
DESC student; --顯示表的結構
SHOW CREATE DATABASE school; --查看創建數據庫的語句

2.5數據表的類型

-- 關於數據庫引擎
/*
INNODB 默認使用
MYISAM 早些年使用的
*/

 

  MYISAM INNODB
事務支持 不支持 支持
數據行鎖定 不支持 支持
外鍵約束 不支持 支持
全文索引 支持 支持(全英文)
表空間大小 較小 較大 約MYISAM2倍

常規使用操作:

  • MYISAM 節約空間,速度較快

  • INNODB 安全性高,事務的處理,多表多用戶操作

在物理空間存在的位置

所有的數據庫文件都存在data目錄下,一個文件夾就對應一個數據庫

本質還是文件的存儲!

MySQL引擎在物理文件上的區別

  • innoDB 在數據庫表中只有一個*。frm文件,以及上級目錄下的 ibdata1文件

  • MYISAM對應文件

    • *.frm -表結構的定義文件

    • *.MYD 數據文件(data)

    • *.MYI 索引文件(index)

設置數據庫表的字符集編碼

charset=utf8

不設置的話,會是mysql默認的字符集集編碼~不支持中文

在my.ini中配置默認的編碼

character-set-server=utf8

小技巧:通過 show create table student語句

顯示表信息后右鍵復制,粘貼到查詢面板上,就自動生成表的sql代碼。

2.6修改刪除表

修改

-- 修改表名: ALTER TABLE 舊表名 rename AS 新表名
ALTER TABLE user1 RENAME AS user
-- 增加表的字段: ALTER TABLE 表名 ADD 字段名 列屬性
ALTER TABLE `user` ADD `age` INT(11)
-- 修改表的字段(重命名,修改約束!):
ALTER TABLE 表名 MODIFY 字段名 列屬性[]
ALTER TABLE user1 MODIFY `age` VARCHAR(11)-- 修改約束

ALTER TABLE 表名 CHANGE `舊字段名` `新字段名` 列屬性
ALTER TABLE user1 CHANGE `age` `age1` INT(1) -- 重命名
-- 刪除表的字段
alter TABLE user1 DROP `age1`

--刪除表(如果表存在再刪除)
DROP TABLE IF EXISTS `user1`

==所有的創建和刪除操作盡量加上判斷,以免報錯==

if not exists 如果不存在就創建

if exists 如果存在就刪除

注意點:

  • ``字段名,使用這個包裹!

  • 注釋: -- /**/

  • sql關鍵字大小寫不敏感,建議寫小寫

  • 所有的符號全部用英文

練習:

ALTER TABLE `user1` RENAME AS `user` --修改表名ALTER TABLE `舊表名` RENAME AS `新表名`
ALTER TABLE `user` ADD `hobby` VARCHAR(20)-- 增加表的字段:ALTER TABLE `表名` ADD `字段名` 屬性
ALTER TABLE `user` MODIFY `hobby` INT(20) -- 修改表的字段 的類型和屬性
ALTER TABLE `user` CHANGE `hobby` `hobby1` VARCHAR(30) -- 修改表的字段名 與類型屬性
alter TABLE `user` DROP `hobby1` -- 刪除表的字段
DROP TABLE if EXISTS `user` -- 刪除表	
show CREATE DATABASE person -- 查看創建數據庫的語句
show create table `student` -- 查看創建表的語句
DESC `student`  -- 顯示表的結構
DROP DATABASE if exists person -- 刪除某個數據庫如果存在的話
show DATABASES -- 查看所有的數據庫
use `school` --使用數據庫

 

3.MySQL數據管理

3.1外鍵(了解即可)

方式一:在創建表的時候,增加約束(麻煩,復雜)

CREATE TABLE IF NOT EXISTS `school`.`grade` (
`gradeid` INT(10) NOT NULL auto_increment COMMENT '年級編號',
`gradename` VARCHAR(10) not null COMMENT '年級名字',
PRIMARY KEY(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8



	CREATE TABLE if not EXISTS`student` (
  `id` int(4) unsigned zerofill NOT NULL AUTO_INCREMENT COMMENT '學號',
  `name` varchar(20) NOT NULL DEFAULT '匿名' COMMENT '姓名',
  `pwd` varchar(20) NOT NULL DEFAULT '123456' COMMENT '密碼',
  `sex` varchar(2) NOT NULL DEFAULT '男' COMMENT '性別',
	`gradeid` INT(10) NOT NULL auto_increment COMMENT '年級編號',
  `birthday` datetime DEFAULT NULL COMMENT '出生日期',
  `address` varchar(60) DEFAULT NULL COMMENT '住址',
  `email` varchar(50) DEFAULT NULL COMMENT '郵箱',
  PRIMARY KEY (`id`),
	KEY `FK_gradeid` (`gradeid`),
	CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

方式二:創建表之后再創建外鍵關系

alter table `student`
add constraint `FK_gradeid` foreign key(`gradeid`) references `grade` (`gradeid`);
-- alter table `表名`
-- add constraint `約束名` foreign key(作為外鍵的列) references 哪個表(哪個字段);

 

刪除有外鍵關系的表的時候,必須要先刪除引用別人的表(從表),在刪除自己的表()

以上的操作都是物理外鍵,數據庫級別的外鍵,,我們不建議使用,避免數據庫過多造成困擾

最佳實踐

  • 數據庫就是單純的表,只用來存數據,只有行和列

  • 我們想使用多張表的數據,想使用外鍵,程序去實現

3.2DML語言(全部記住)

數據庫意義:數據存儲,數據管理

DML語言:數據操作語言

3.3添加 insert

  • insert

-- 插入語句(添加)
-- insert into 表名([字段1,字段2,字段3])VALUES(`值1`),(`2`),(`3`)
INSERT INTO `grade`(`gradename`)VALUES('大四'),
-- 由於主鍵自增我們可以省略(如果不寫字段,它就會一一匹配)
-- 一般寫插入語句,我們一定要數據和字段一一對應!
-- 插入多個字段
INSERT INTO `grade` (`gradename`)VALUES('大二'),('大一')

語法:insert into 表名([字段1,字段2,字段3])VALUES(值1),(2),(3)

注意事項:

  1. 字段和字段之間使用英文逗號隔開

  2. 字段是可以省略的,但是后面的值必須一一對應

  3. 可以同時插入多條數據,values后面的值,需要使用,隔開即可values(),(),....

3.4修改 update

  • update

update 修改誰(條件)set原來的值=新值

-- 修改學員名字,帶了簡介
UPDATE `student` SET `name`='趙武' WHERE id !=2;
-- 不指定條件的情況下,會改動所有表!
UPDATE `student` SET `name`='趙東'
-- 修改多個屬性,逗號隔開
UPDATE `student` SET `name`='大哥',`age`=18,`adress`='三屯' WHERE id=1;

條件:where 運算符 id等語某個值,大於某個值,在某個區間內修改...

操作符 含義 范圍 結果
= 等語 5=6 false
<>或!= 不等於 5<>6 true
>      
<      
<=      
>=      
between...and... 在某個范圍內 [2,5]  
and 我和你&& 5>1&&1>2 false
or 我或你|| 5>1&&1>2 true
-- 通過多個條件定位數據
update `student` set `name`='狂神' where name='大哥' and sex='男' 

語法:update 表名 set colnum_name=value,[colnum_name=value,...] where[條件]

注意:

  • colnum_name 是數據庫的列,盡量帶上``

  • 條件,篩選的條件,如果沒有指定,則會修改所有的列

  • value,是一個具體的值,也可以是一個變量

  • 多個設置的屬性之間,使用英文逗號隔開

3.5刪除 delete

  • delete

語法:delete from 表名 [where] 條件

-- 刪除數據(避免這樣寫,會全部刪除)
delete from `student`

--刪除指定數據
delete from `student` where id=1;

 

truncate 命令

作用:完全清空一個數據庫表,表的結構和索引約束不會變!

-- 清空數據庫
truncate `student`

 

delete 和truncate區別

  • 相同點:都能刪除數據,都不會刪除表結構

  • 不同點:

    • TRUNCATE 重新設置 自增列 計數器會歸零

    • TRUNCATE 不會影響事務

delete from `test` -- 不會影響自增
truncate table `test` -- 自增會歸零

了解即可:DELETE刪除的問題,重啟數據庫,現象

  • Innodb 自增列會從1開始(存在內存當中,斷電即失)

  • MyISAM 繼續從上一個自增量開始(存在文件中的,不會丟失)

4.DQL查詢數據(最重點)

 

4.1DQL

(Data Query LANGUAGE:數據查詢語言)

  • 所有的查詢操作都用它 select

  • 簡單的查詢,復雜的查詢它都能作~

  • 數據庫中最核心的語言,最重要的語言

  • 使用頻率最高的語句

select完整的語法:

select [ALL | distinct]
{*|table.* |[table.field1[as alias1][table.field1[as alias2]]}
 from table_name [as table_alias]
   [left | right | inner join table_name2] --聯合查詢
   [where...] --指定結果需滿足的條件
   [group by..] --指定結果按照哪幾個字段來分組
  [having] --過濾分組的記錄必須滿足的次要條件
  [order by...]  --指定查詢記錄按一個或多個條件排序
  [limit{[offset,]row_count |row_countoffset offset}]; --指定查詢的記錄從哪條至哪條
             

注意:[]括號代表可選的,{}括號代表必選的

4.2指定查詢字段

-- 查詢全部的學生 select 字段 from 表
select * from student

-- 查詢指定字段
SELECT `studentNo`,`studentName` from student

-- 別名,給結果起一個名字,AS 給可以給字段起別名,也可以給表起
select `studentNo` AS 學號,`studentName` AS 學生姓名 FROM student AS 學生

--函數 concat(a,b)
SELECT CONCAT('姓名:',studentName) AS 新名字 FROM student

語法:select 字段名 ... from 表名

有的時候,列名字不是那么的見名知意。我們起別名 As 字段名 as 別名 表名 as 別名

練習:

-- 查詢全部的學生 select 字段 from 表
SELECT * from student

-- 查詢指定字段
SELECT `name`,`pwd` from student

-- 別名,給結果起一個名字,AS 給可以給字段起別名,也可以給表起
SELECT `name` AS 名字, `pwd` AS 密碼 FROM student as 學生; 

--函數 concat(a,b)
SELECT concat('名字:',name) AS 學生名單 from student;

去重 distinct

作用:去除select查詢出來的結果中重復的數據,重復的數據只顯示一條

-- 查詢一下有哪些同學參加了考試,成績
select * from result -- 查詢全部的考試成績
select `studentNo` from result --查詢有哪些同學參加了考試
select distinct `studentNo` from result --去除重復數據

select version() -- 查詢系統版本(函數)
select 100*3-1 as 計算結果 --用來計算(表達式)
select @@auto_increment_increment --查詢自增的步長(變量)

--學員考試成績 +1分查看
select `studentNo`,`studentResult`+1 as '提分后' from result

數據庫中的表達式:文本值,列,NULL,函數,計算表達式,系統變量

select 表達式 from 表

4.3where條件子句

作用:檢索數據中符合條件的值

邏輯運算符

運算符 語法 描述
and && a and b a&&b 邏輯與,兩個都為真,結果為真
or || a or b a||b 邏輯或,有一個為真,結果為真
not ! not a !a 邏輯非,真為假!假為真!

盡量使用英文字母

--查詢考試成績在95-100分之間
SELECT `studentNo`,`studentResult` from result
where studentResult>=95 and studentresult<=100

SELECT `studentNo`,`studentResult` from result
where studentResult>=95 && studentresult<=100

--模糊查詢(區間)
select `studentno`,`studentresult` from result
where studentresult between 95 and 100

-- 除了1000號學生之外的同學的成績
select `studentno`,`studentresult` from result
where studentno!=1000;

where not studentno=1000;

模糊查詢:比較運算符

運算符 語法 描述
is null a is null 如果操作符為null,則結果為真
is not null a is not null 如果操作符為 not null,則結果為真
between a between b and c 若a在b和c之間,則結果為真
Like a like b 如果a能匹配到b則結果為真
In a in(a1,a2,a3) 假設a在a1,a2,a3其中的某一個值,結果為真

練習

-- 模糊查詢
-- 查詢姓劉的同學
-- like 結合(代表0-任意個字符)
select `studentno`,`studentname` from result
where studentname like '劉%' ;
-- 查詢姓劉后面一個字符的
select `studentno`,`studentname` from result
where studentname like '劉_' ;
-- 查詢姓劉后面兩個字符的
select `studentno`,`studentname` from result
where studentname like '劉__' ;
-- 查詢名字中有加字的同學
select `studentno`,`studentname` from result
where studentname like '%劉%' ;

---------------------------------------------------------------
-- in 具體的一個或多個值 查詢1001 1002 1003學員的成績
select `studentno`,`studentname` from result
where studentno IN(1001,1002,1003);

select `studentno`,`studentname` from result
where address in('北京');


---------------null----not null-------------''---
-- 查詢地址為空的學生
select `studentno`,`studentname` from result
where address is NULL or adress='';
-- 查詢沒有生日日期的學生
select `studentno`,`studentname` from result
where birthday is  null ;

 

4.4聯表查詢

74e4d38dce40d3a69dc416c062d839e4b95.jpg

/*
思路:
1.分析需求,分析查詢的字段來自哪些表,(連接查詢)
2.確定使用哪些連接查詢? 7種
確定交叉點,這兩個表中哪個數據是相同的
判斷條件:學生表中的studentno=成績表中的studentno
join(連接的表) on (判斷的條件) 連接查詢
where 等值查詢
*/
-- inner JOIN中間查詢
select s.studentno as 學號,studentname as 名字,subjectno as 排名,studentresult as 分數
from student as s
inner join result as r
on s.studentno=r.studentno

-- right join右查詢
select s.studentno as 學號,studentname as 名字,subjectno as 排名,studentresult as 分數
from student as s
RIGHT JOIN result as r
on s.studentno=r.studentno

-- left join右查詢
select s.studentno as 學號,studentname as 名字,subjectno as 排名,studentresult as 分數
from student as s
left JOIN result as r
on s.studentno=r.studentno
操作 描述
inner join 如果表中至少有一個匹配,就返回行
left join 會從左表中返回所有的值,即使右表中沒有匹配
right join 會從右表中返回所有的值,即使左表中沒有匹配
-- 查詢缺考同學信息
select s.studentno as 學號,studentname as 名字,subjectno as 排名,studentresult as 分數
from student as s
left JOIN result as r
on s.studentno=r.studentno
where studentresult is null ;

-- 我們要 查詢哪些數據 SELECT
-- 需要從哪幾個表中查 FROM 表  xxx join 連接的表 on 交叉條件
-- 假設存在一種多張表查詢,慢慢來,先查詢兩張表增加然后再慢慢增加
-- FROM a left join b
-- from a right join b



-- 查詢 學號,姓名,科目名,成績,
SELECT s.studentno ,studentname,subjectname,studentresult
from student as s
left join result r
on s.studentno=r.studentno
inner join subject as sub
on r.subjectno=sub.subjectno

自連接

父類表:

categoryid categoryName
2 信息技術
3 軟件開發
5 美術設計

子類表

categoryid pid categoryName
4 3 數據庫
6 3 web開發
7 5 ps技術
8 2 辦公信息

操作:查詢父類對應的子類關系。

父類 子類
信息技術 辦公信息
軟件開發 數據庫
軟件開發 web開發
美術設計 ps技術
-- 創建表
CREATE TABLE `school`.`category`(
`categoryid` INT(10) UNSIGNED not null auto_increment comment '主題id',
`pid` INT(10) not null COMMENT '副id',
`categoryName` varchar(50) not null COMMENT '主題名字',
primary key (`categoryid`)
)ENGINE=INNODB auto_increment=9 DEFAULT charset=utf8
-- 添加數據
insert into `category` (`categoryid`,`pid`,`categoryName`)
VALUES('2','1','信息技術'),
('3','1','軟件開發'),
('4','3','數據庫'),
('5','1','美術設計'),
('6','3','web開發'),
('7','5','ps技術'),
('8','2','辦公信息');
show create table `category`
desc `category`

-- 查詢父子信息:把一張表看為兩個一模一樣的表
select a.`categoryName` as '父欄目', b.`categoryName` as'子欄目'
FROM `category` as a,`category` as b
where a.`categoryid`=b.`pid`;

4.5分頁和排序

image-20200603112809851

分頁

image-20200603114045886

4.6子查詢

where(這個值是計算出來的)

本質:在where語句中嵌套一個子查詢語句

-- 查詢java第一學年 課程成績排名前十的學生,並且分數要大於80的學生信息(學號,姓名,課程名稱,分數)
SELECT s.`studentno`,`studentname`,`subjectname`,`studentresult` 
from student as s
inner join result as r
on s.`studentno`=r.`studentno`
inner join `subject` as sub
r.`subjectno`=sub.`subjectno`
where `subjectname`='java第一學年' and `studentresult`>=80
order by `studentresult` desc 
limit 0,10


-- 查詢學生編號,學生姓名,和高等數學-2大於80分的編號

select s.`studentno`,`studentname`
from student as s
inner join result as r
on s.`studentno`=r.`studentno`
inner join subject as sub
on r.`subjectno`=sub.`subjectno`
where `subjectname`='高等數學-2' and `studentresult`>80

-- 子查詢
select s.`studentno`,`studentname`
from student as s
inner join result as r
on s.`studentno`=r.`studentno`
where `studentresult`>80 and `studentno`=(
select `studentname`
from subject where `subjectname`='高等數學-2' 


)
-- 再改造(由里及外)

select `studentno`,`studentname` from student where `studentno`=(
	select `studentno` from result where `subjectno`=(
		select `subjectno` from `subject` where `subjectname`='高等數學-2'
	)
)

練習:

-- 練習:查詢c語言-1 前5名同學的成績的信息(學號,姓名,分數)
select s.`studentno`,`studentname`
from student as s
inner join result as r
on s.`studentno`=r.`studentno`
inner join subject as sub 
on r.`subjectno`=`s.subjectno`
where `subjectname`='c語言-1'
ORDER BY `studentresult` DESC
limit 0,5

-- 子查詢 
select s.`studentno`,`studentname`
from student as s
inner join result as r
on s.`studentno`=r.`studentno`
where `subjectno`=(
	select `subjectno` from `subject` where `subjectname`='c語言-1'
)
ORDER BY `studentresult` DESC
limit 0,5

-- 嵌套查詢
select `studentno`,`studentname` from student where `studentno`=(
	select `studentno` from `result` where `subjectno`=(
		select `subjectno` from `subject` where `subjectname`='c語言-1'
	) 
)
order by `studentresult` desc
limit 0,5

4.7分組和過濾

-- 查詢不同課程的平均分,最高分,最低分,平均分大於80
-- 核心:(根據不同課程分組)
SELECT s.`subjectname`,avg(`studentresult`) as 平均分,max(`studentresult`),min(`studentresult`)
from result as s 
inner join `subject` as sub
on s.`subjectno`=sub.`subjectno`
GROUP BY r.`subjectno`  -- 通過什么字段來分組
HAVING 平均分>80

4.8select小結

順序很重要

select 去重 要查詢的字段 from 表(注意:表和字段可以取別名)
xxx join 要鏈接的表 on 等值判斷
where(具體的值,子查詢語句)
group by(通過哪個字段來分組)
having (過濾分組后的信息,條件和where是一樣的,位置不同)
order by (通過哪個字段排序)[升序asc 降序desc]
limit startindex, pagesize
業務層面:
查詢:跨表,跨數據

 

5.MySQL函數

5.1常用函數

----------常用函數------------------------------
-- 數學運算
select ABS(-8)  -- 絕對值 ABS(X)
select CEILING(9.4)  -- 向上取整  ceiling(x)
SELECT FLOOR(9.4)  -- 向下取整 FLOOR(X)
SELECT RAND()   -- 返回一個0-1之間的隨機數
SELECT SIGN(10)   -- 判斷一個數的符號 0-0 負數返回-1,整數返回1

-- 字符串函數
select char_length('即使再小的帆,也能遠航') -- 查字符串長度 CHAR_LENGTH(str)
select CONCAT('','','')  -- 拼接字符串
select `INSERT`('我愛變成hello',1,4,'超級熱愛編程') -- 查詢,從某個位置開始替換某個長度
SELECT LOWER('KuangShen') -- 小寫字母
select UPPER('KuangShen') -- 大寫字母
select INSTR('KuangShen',n)  -- 但會第一次出現的子串的索引
SELECT REPLACE('狂神說堅持就能成功','堅持','努力') -- 一段字符串,替換指定字符串
select SUBSTR('狂神說堅持就能成功',4.6)  -- 一段字符串,從第幾個字符開始,截取多少個字符
select reverse('清晨我上馬')  -- 反轉字符串

-- 查詢 姓 周的同學, 改為 鄒
SELECT REPLACE(studentname,'周','鄒') from student
where studentname like '周%'

-- 時間和日期函數(記住)
SELECT `CURRENT_DATE`() -- 獲取當前日期
select CURDATE()  -- 獲取當前日期
select NOW()   -- 獲取當前的時間
select LOCALTIME() -- 獲取本地時間
select SYSDATE() -- 系統時間
select YEAR(NOW()) -- 獲取年
select MONTH(NOW())-- 獲取月
select DAY(NOW())-- 獲取日
select hour(NOW())-- 獲取時
select MINUTE(NOW())-- 獲取分
select SECOND(NOW())-- 獲取秒


-- 系統
SELECT SYSTEM_USER()  -- 用戶名
select user()   -- 用戶名
select version() -- 版本

5.2 聚合函數(常用)

函數名稱 描述
count() 技術
sum() 求和
avg() 平均值
max() 最大值
min() 最小值
...  
=================聚合函數===================
-- 都能統計 表中的數據
select count(studentname) from student; -- count(字段),會忽略所有的null值
SELECT count(*) from student;  --count(*),不會忽略null值,本質 計算行數
SELECT count(1) from result;   -- count(1),不會忽略所有null值 本質 計算行數
 
SELECT sum(`studentresult`) as 總和 from result
SELECT avg(`studentresult`) as 平均分 from result
SELECT max(`studentresult`) as 最高分 from result
SELECT min(`studentresult`) as 最低分 from result

5.3數據庫級別的MD5加密(擴展)

什么是MD5?

主要增強算法復雜度和不可逆性。

MD5不可逆,具體的值的MD5是一樣的。

MD5 破解網站的原理,背后有一個字典,MD5加密后的值 加密前的值

-- ==================測試MD5加密=============================
CREATE TABLE `school`.`testmd5`(
	`id` INT(10) NOT NULL,
	`name` VARCHAR(10) NOT NULL,
	`pwd` VARCHAR(20) NOT NULL,
	PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT charset=utf8;

-- 添加三個用戶信息
INSERT INTO `testmd5` VALUES(1,'趙東','123'),(2,'有錢','1'),(3,'帥氣','1');
-- 給用戶的全部密碼加密
UPDATE testmd5 SET pwd = md5(pwd) where id = 2
-- 添加信息的時候,給密碼加密
INSERT INTO `testmd5` VALUES(4,'小明',MD5('123'));
-- 如何效驗,將用戶傳遞進來的密碼進行md5加密,用值來對比
SELECT * from testmd5 WHERE name ='小明' and pwd= MD5('123');

6.事務

6.1什么是事務

 

 

事務原則:ACID原則 原子性,一致性,隔離性,持久性

原子性(Atomicity)

要么都成功,要么都失敗

一致性(Consistency)

事務前后的數據完整性要保證一致

持久性(Durability)--- 事務提交

事務一旦提交則不可逆,被持久化到數據庫中!

隔離性(Isolation)

事務的隔離性是多個用戶並發訪問數據庫時,數據庫為每一個用戶開啟的事務,不能被其他事務的操作數據所干擾,事務之間相互隔離。

 

隔離所導致的一些問題

image-20200603173547695

-- mysql 是默認開啟事務自動提交的
set autocommit =0 -- 關閉自動提交事務
set autocommit =1 -- 開啟自動提交事務(默認)

-- 手動處理事務
set autocommit =0 -- 關閉自動提交

-- 事務開啟
start transaction -- 標記一個事務的開始,從這個之后的 sql 都在同一事務內
insert xxx
insert xxxx

-- 提交:持久化(成功!)
COMMIT
-- 回滾:回道原來的樣子(失敗!)
ROLLBACK
-- 事務結束
set atuommit=1 -- 開啟自動提交

-- 了解
savepoint 保存點名 -- 設置一個事務的保存點
rollback to savepoint 保存點名 -- 回滾到保存點
release savepoint 保存點名 -- 撤銷保存點

 

模擬事務

image-20200603182707107

7.索引

7.1索引的分類

  • 主鍵索引 (primary key)

    • 唯一的標識,主鍵不可重復,只能有一個列作為主鍵

  • 唯一索引(unique key)

    • 避免重復的列出現,唯一索引可以重復,多個列都可以標識為唯一索引

  • 常規索引(key/index)

    • 默認的,index,key關鍵字來設置

  • 全文索引(FUllText)

    • 在特定的數據庫引擎下才有,MyISMA

    • 快速定位數據

image-20200603192639509

索引在校數據量的時候,用戶不大,但是在大數據的時候,區別十分明顯

7.2索引原則

  • 索引不是越多越好

  • 不要對經常變動數據加索引

  • 小數據量的表不需要加索引

  • 索引一般加在常用來查詢的字段上

 

索引的數據結構

Hash 類型的索引

Btree:innodb 的默認數據結構

image-20200603200115539

8.權限管理和備份

8.1用戶管理

======================創建用戶===========================
-- 創建用戶 create user 用戶名 identified by ‘密碼’

create user kuangshen identified by '123456'

-- 修改密碼(修改當前用戶名密碼)set password= password('新密碼')
SET PASSWORD= PASSWORD('123456')

-- 修改密碼(修改制定用戶名密碼)
set password for root = password('123456')

-- 重命名 rename user 原用戶名 to 新用戶名
rename user root to rootdouble

-- 用戶授權 grant all privileges 全部的權限 庫.表
-- 除了給別人授權,其他都能夠干
grant all privileges on *.* to kuangshen
-- 查詢權限
show grants FOR kuangshen -- 茶看制定用戶的權限
show grants for root@localhost
-- root 用戶的權限

-- 撤銷權限 revoke 那些權限, 在哪個庫撤銷 給誰撤銷
revoke all privileges on *.* from kuangshen

-- 刪除用戶
drop user kuangshen

8.2mysql備份

為什么要備份:

  • 保證重要的數據不丟失

  • 數據轉移

MySQL 數據庫備份的方式

  • 直接拷貝物理文件

  • 在可視化工具中手動導出

  • 使用命令行導出 mysqldump 命令行使用

image-20200604120803098

mysqldump -hlocalhost -uroot -p123456 school student >D:/1.sql
導出 從本地導出 用戶名 密碼 數據庫名 表名 》指向 path(導出的路徑)
(導出多張表,在表名后空格 表名)
# 導入
# 導出
# source 備份文件
source d:1.sql

mysql -u用戶名 -p密碼 庫民<備份文件

9.規范數據庫設計

9.1為什么需要設計

當數據庫比較復雜的時候,我們就需要設計了

糟糕的數據庫設計:

  • 數據冗余,浪費空間

  • 數據庫插入和刪除都會麻煩、異常【屏蔽使用物理外界】

  • 程序的性能差

良好的數據庫設計:

  • 節省內存空間

  • 保證數據庫的完整性

  • 方便我們開發系統

軟件開發中,關於數據庫的設計

  • 分析需求:分析業務和需要處理的數據庫的需求

  • 概要設計L設計關系圖E-R圖

設計數據庫的步驟:

  • 收集信息,分析需求

    • 用戶表(用戶登陸注銷,用戶的個人信息,寫博客,創建分類)

    • 分類表(文章分類,誰創建的)

    • 文章表(文章的信息)

    • 友鏈接(友鏈信息)

    • 自定義表(系統信息,某個關鍵的子,或者一些主字段)

  • 標識實體(把需求落地到每個字段)

  • 標識實體之間的關系

    • 寫博客user-->blog

    • 創建分類user -->category

    • 關注:user-->User

9.2三大范式

為什么需要數據規范化

  • 信息重復

  • 更新異常

  • 插入異常

    • 無法正常顯示信息

  • 刪除異常

    • 丟失有效的信息

 

三大范式

第一范式(1NF)

原子性:保證每一列不可再分

第二范式(2NF)

前提:滿足第一范式

每張表只描述一件事情

第三范式(3NF)

牆體:滿足第一范式和第二范式

第三范式需要確保數據表中的每一列數據都和主鍵直接相關,而不能間接相關。

(規范數據庫的設計)

規范性和性能的問題

關聯查詢的表不得超過三張表

  • 考慮商業化的需求和目標(成本,用戶體驗!)數據庫的性能更加重要

  • 在規范性能的問題的時候,需要適當的考慮一下規范性!

  • 故意給某些表增加一些冗余的字段。(從多表查詢中變為單標查詢)

  • 故意增加一些計算列(從大數據量降低為小數據量的查詢:索引)

10.JDBC(重點)

10.1數據庫驅動

驅動:聲卡、顯卡、數據庫

image-20200604151038796

10.2JDBC

sun公司為了簡化開發人員的(對數據庫的同一)操作,提供了一個(java操作數據庫)規范,俗稱JDBC,這些規范的實現具體由具體的廠商去做

image-20200604151417992

image-20200604151752974

10.3第一個JDBC程序

1.創建一個普通項目

2.導入驅動,

3.編寫測試代碼

// 我的第一個JDBC程序
public class jdbcFirstDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加載驅動
         Class.forName("com.mysql.jdbc.Driver");   //固定寫法,加載驅動
        //2.用戶信息 和url
        //useUnicode=true 支持中文編碼  characterEncoding=utf8設置中文字符為utf8 useSSL=true 使用安全連接
        String url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=false";
        String username="root";
        String password="19941027";
        //3.連接成功,數據庫對象
        Connection connection = DriverManager.getConnection(url, username, password);

        //4.執行SQL對象  Statement
        Statement statement = connection.createStatement();
        //5.執行SQL的對象去執行 sql 可能存在結果,查看返回結果
        String sql="select * from student";
        ResultSet resultSet = statement.executeQuery(sql);
        while(resultSet.next()){
            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("name="+resultSet.getObject("name"));
            System.out.println("password="+resultSet.getObject("pwd"));
            System.out.println("sex="+resultSet.getObject("sex"));
            System.out.println("birthday="+resultSet.getObject("birthday"));
            System.out.println("address="+resultSet.getObject("address"));
            System.out.println("email="+resultSet.getObject("email"));
            System.out.println("========================================");
        }
        //5.關閉連接
        resultSet.close();
        statement.close();
        connection.close();
    }

}

步驟總結:

  1. 加載驅動

  2. 連接數據庫DriverManager

  3. 獲得執行sql的對象, statment

  4. 獲得返回的結果集()

  5. 釋放連接

DriverManager

//DriverManager.registerDriver(new com.mysql.jdbc.Driver());
Class.forname("com.mysql.jdbc.Driver");
//推薦用第二種方式創建驅動
//原因:Driver底層是一個靜態代碼塊里面有創建Driver代碼,運行就會創建一次,如果用第一種就會創建兩次
 Connection connection = DriverManager.getConnection(url, username, password);
//Connection 代表數據庫
connection.rollback();//事務回滾
connection.commit();//事務提交
connection.setAutoCommit();//數據庫設置自動提交

URL

//2.用戶信息 和url
        //useUnicode=true 支持中文編碼  characterEncoding=utf8設置中文字符為utf8 useSSL=true 使用安全連接
        String url="jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=false";
// mysql --3306
//協議://主機:端口號/數據庫名?參數1&參數2&參數3
//oralce --1521
//jdbc:oracle:thin:@localhost:1521:sid

Statement執行SQL的對象 PrepareStatement執行SQL的對象

//5.執行SQL的對象去執行 sql 可能存在結果,查看返回結果
        String sql="select * from student";//編寫sql
        statement.executeQuery(sql);//執行查詢操作,返回 ResultSet
        statement.execute(sql);//執行任何sql
        statement.executeUpdate(sql);//更新、插入、刪除。都是用這個,返回一個受影響的行數

ResultSet查詢的結果集:封裝了所有的查詢結果

image-20200604174947701

釋放資源

image-20200604175032049

// 我的第一個JDBC程序
public class jdbcFirstDemo {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加載驅動
        Class.forName("com.mysql.jdbc.Driver"); //創建驅動
        //2.用戶信息 和url
        String url="jdbc:mysql://localhost:3306/school?useSSL=false&useUnicode=true&characterEncode=utf8";
        //useUnicode=true 支持中文編碼  characterEncoding=utf8設置中文字符為utf8 useSSL=true 使用安全連接
        String username="root";
        String password="19941027";
        //3.連接成功,創建數據庫對象
        Connection connection = DriverManager.getConnection(url, username, password);
        //4.創執行sql語句的對象
        Statement statement = connection.createStatement();
        //5.寫sql語句,執行SQL語句  ,查詢,用execute   返回結果集
        String sql="select * from student";
        ResultSet resultSet = statement.executeQuery(sql);
        //6.遍歷查詢結果
        while (resultSet.next()){
            System.out.println("");
            System.out.println("");
            System.out.println("");
            System.out.println("");
            System.out.println("");
            System.out.println("=============================");
        }
        //7.釋放資源
        resultSet.close();
        statement.close();
        connection.close();
    }
}

image-20200604175913714

image-20200604180049092

10.4 statement對象

數據庫配置文件

driver=com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/school?useUnicode=true&characterEncoding=utf8&useSSL=false
username=root
password=19941027

提取工具類

public class JdbcUtils {
    private  static  String dirver=null;
    private  static  String url=null;
    private  static  String username=null;
    private  static  String password=null;
    static {
        //獲取類加載器,后得到資源()

        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(in);
            dirver=properties.getProperty("driver");
            url=properties.getProperty("url");
            username=properties.getProperty("username");
            password=properties.getProperty("password");
            //1.驅動只加載一次
            Class.forName(dirver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    //獲取連接
    public static Connection getConnection() throws SQLException {
        return  DriverManager.getConnection(url, username, password);

    }
    //釋放連接資源
    public static void release(Connection conn, Statement st, ResultSet rs){
        if (rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (st!=null){
            try {
                st.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
        if (rs!=null){
            try {
                rs.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }
}

測試增加數據

public class TestInsert {
    public static void main(String[] args) {
        //提升作用域,方便在finally后關閉資源
        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        //調用utils方法,連接數據庫
        try {
            conn=JdbcUtils.getConnection();//獲取數據庫連接
            st=conn.createStatement();//獲取執行sql對象
            String sql="insert into student(id,`name`,`pwd`,`sex`,`birthday`,`address`,`email`) values (6,'趙龍','121212','男','1994-10-27','小別墅','11111111@qq.com')";
            //增加數據的sql語句
            //利用executeUpdate獲取結果,看結果是否大於0,是,代表插入數據成功
            int i = st.executeUpdate(sql);
            if (i>0){
                System.out.println("插入數據成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //調用關閉資源方法,關閉開啟的對象
            JdbcUtils.release(conn,st,null);//因為增加沒有用到rs方法,所以可以用null代替值
        }
    }
}

刪除數據

public class TestDelete {
    public static void main(String[] args) {
        //提升作用域,方便在finally后關閉資源
        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        //調用utils方法,連接數據庫
        try {
            conn=JdbcUtils.getConnection();//獲取數據庫連接
            st=conn.createStatement();//獲取執行sql對象
            String sql="delete from student where id=4 ";
            //增加數據的sql語句
            //利用executeUpdate獲取結果,看結果是否大於0,是,代表插入數據成功
            int i = st.executeUpdate(sql);
            if (i>0){
                System.out.println("刪除成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //調用關閉資源方法,關閉開啟的對象
            JdbcUtils.release(conn,st,null);//因為增加沒有用到rs方法,所以可以用null代替值
        }
    }
}

 

更新數據

public class TestUpdate {
    public static void main(String[] args) {
        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        try {
            conn=JdbcUtils.getConnection();
            st=conn.createStatement();
            String sql="update student set `name`='帥哥',`sex`='女' where id=3";
            //增加數據的sql語句
            //利用executeUpdate獲取結果,看結果是否大於0,是,代表插入數據成功
            int i = st.executeUpdate(sql);
            if (i>0){
                System.out.println("更新成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //調用關閉資源方法,關閉開啟的對象
            JdbcUtils.release(conn,st,null);//因為增加沒有用到rs方法,所以可以用null代替值
        }
    }
}

查找數據

public class TestSelect {
    public static void main(String[] args) {
        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;
        try {
            conn = JdbcUtils.getConnection();
            st=conn.createStatement();
            String sql="select * from student where id=5";
            rs=st.executeQuery(sql);
            while (rs.next()){
                System.out.println(rs.getString("name"));
                System.out.println(rs.getString("sex"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
}

 

SQL注入問題

存在漏洞,會被攻擊,導致數據泄露。SQL會被拼接

public class TestSelect {
    public static  void login(String username,String password){
        Connection conn=null;
        Statement st=null;
        ResultSet rs=null;

        try {
            conn = JdbcUtils.getConnection();
            st=conn.createStatement();
            // select * from student where `name`='狂神' and `pwd`='123456';
            String sql="select * from student where `name`='"+username+"' and `pwd`='"+password+"'";
            rs=st.executeQuery(sql);
            while (rs.next()){
                System.out.println(rs.getString("name"));
                System.out.println(rs.getString("pwd"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn,st,rs);
        }
    }
    public static void main(String[] args) {
        login("'or'1=1","'or'1=1");
    }
}

10.5 preparedStatement對象

preparedStatement可以防止sql注入。效率更高!

1.新增

 public static void main(String[] args) {

        Connection conn=null;
        PreparedStatement st=null;
        ResultSet rs=null;
        //調用utils方法,連接數據庫
        try {
            conn=JdbcUtils.getConnection();//獲取數據庫連接
            //預編譯sql 先寫sql 然后不執行 使用?占位符代替參數
            String sql="insert into student(id,`name`,`pwd`,`sex`,`birthday`,`address`,`email`) values(?,?,?,?,?,?,?)";

            st=conn.prepareStatement(sql);//獲取執行sql對象
           //手動給參數賦值
            st.setInt(1,6);
            st.setString(2,"趙子龍");
            st.setString(3,"123321");
            st.setString(4,"男");
            // new Date().getTime() 獲取時間戳
            st.setDate(5,new java.sql.Date(new Date(1).getTime()));
            st.setString(6,"常山");
            st.setString(7,"9999999.com");


            //利用executeUpdate獲取結果,看結果是否大於0,是,代表插入數據成功
            int i = st.executeUpdate(sql);
            if (i>0){
                System.out.println("插入數據成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //調用關閉資源方法,關閉開啟的對象
            JdbcUtils.release(conn,st,null);//因為增加沒有用到rs方法,所以可以用null代替值
        }
    }
}

2.刪除

public static void main(String[] args) {
    //提升作用域,方便在finally后關閉資源
    Connection conn=null;
    PreparedStatement st=null;
    ResultSet rs=null;
    //調用utils方法,連接數據庫
    try {
        conn=JdbcUtils.getConnection();//獲取數據庫連接
        String sql="delete from student where id=? ";
        st=conn.prepareStatement(sql)//獲取執行sql對象
       st.setInt(1,1);
        
        //利用executeUpdate獲取結果,看結果是否大於0,是,代表插入數據成功
        int i = st.executeUpdate(sql);
        if (i>0){
            System.out.println("刪除成功");
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally {
        //調用關閉資源方法,關閉開啟的對象
        JdbcUtils.release(conn,st,null);//因為增加沒有用到rs方法,所以可以用null代替值
    }
}

3.更新

    public static void main(String[] args) {
        Connection conn=null;
       PreparedStatement st=null;
        ResultSet rs=null;
        try {
            conn=JdbcUtils.getConnection();
            String sql="update student set `name`=?,`sex`=? where id=?";
            st=conn.prepareStatement(sql);
            st.setString(1,"趙帥");
            st.setString(2,"男");
            st.setInt(3,2);
            //增加數據的sql語句
            //利用executeUpdate獲取結果,看結果是否大於0,是,代表插入數據成功
            int i = st.executeUpdate(sql);
            if (i>0){
                System.out.println("更新成功");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            //調用關閉資源方法,關閉開啟的對象
            JdbcUtils.release(conn,st,null);//因為增加沒有用到rs方法,所以可以用null代替值
        }
    }
}

4.查詢

public static void main(String[] args) {
    Connection conn=null;
    PreparedStatement st=null;
    ResultSet rs=null;
    try {
        conn=JdbcUtils.getConnection();
        String sql="select * from student where id=?";
        st=conn.prepareStatement(sql);
        st.setInt(1,1);
        rs = st.executeQuery();
        if (rs.next()){
            System.out.println(rs.getString("name"));
            System.out.println(rs.getString("pwd"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally{
       JdbcUtils.release(conn,st,rs);
        
    }
}

5.防止SQL注入

PreparedStatement 防止SQL注入的本質,把傳遞進來的參數當做字符

假設其中存在轉義字符,就直接忽略, ‘ 會被直接轉義

public static void main(String[] args) {
    login("趙龍","121212");
}
public  static void login(String username,String password){
    Connection conn=null;
    PreparedStatement st=null;
    ResultSet rs=null;
    try {
        conn=JdbcUtils.getConnection();
        String sql="select * from student where `name` =? and `pwd`=?";
        st=conn.prepareStatement(sql);
        st.setString(1,username);
        st.setString(2,password);
        rs = st.executeQuery();
        if (rs.next()){
            System.out.println(rs.getString("name"));
            System.out.println(rs.getString("pwd"));
        }
    } catch (SQLException e) {
        e.printStackTrace();
    }finally{
        JdbcUtils.release(conn,st,rs);

    }
}

10.6使用idea連接數據庫

右側有datebase按鈕

10.7事務

image-20200604211611420

image-20200604211724593

image-20200604211816390

10.9數據庫連接池

數據庫連接 -- 執行完畢-- 釋放

連接-- 釋放 十分浪費系統資源

池化技術:准備一些預先的資源,過來就連接預先准備好的

image-20200605183804562

 


免責聲明!

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



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