MySQL
1.1、什麼是資料庫
概念:資料倉庫,軟體,安裝在作業系統之上
作用:存儲資料,管理資料
1.2、資料庫分類
關系型資料庫:(sql)
mysql,Oracle,Sql Server
通過表與表之間,行與列之間的關系進行資料的存儲
非關系型資料庫:(nosql)
Redis mongDB
非關系型資料庫,對象存儲,通過對象的自身的屬性來決定
DBMS(資料庫管理系統)
資料庫管理軟體,科學有效的管理我們的資料。維護和擷取資料
2、操作資料庫
操作資料庫>操作資料庫中的表>操作資料庫中的表中的資料
2.1、操作資料庫
mysql 中的sql不區分大小寫
建立資料庫
create database if not exists study;
删除資料庫
drop database if exists study;
切換至資料庫
use `study`
2.2、資料庫的列類型
數值
tinyint 1個位元組
smallint 2個位元組
mediumint 3個位元組
int 4個位元組
bigint 較大的資料 8個位元組
float 浮點數 4個位元組
double 8個位元組
字元串
char 字元串 0-255
varchar 可變字元串 0-65535 (常用的)
時間日期
datatime
null
沒有值
2.3、資料庫的字段屬性

2.4、
2.5、資料表的類型
INNODB:安全性高,事務的處理,多表多使用者操作
MYISAM:節約空間,速度較快
2.6、修改删除表
//修改表的名字
alter table `teacher` rename as `teacher1`
//增加表的字段
alter table `teacher1` add age int(11)
//修改表的字段
alter table `teacher1` modify age varchar(11) --修改限制不能重命名
alter table `teacher1` change age age1 int(1) --修改限制也可以改名字
//删除表的字段
alter table `teacher1` drop age1
//删除表
drop table if exists `teacher1`
注意
``字段名,使用這個包裹
注釋使用–
sql關鍵字不區分大小寫
3、mysql資料管理
3.1、外鍵
盡可能在應用層解決
3.2、DML語言
//添加語句,由于主鍵自增,可以省略
insert into 表名(字段名1,字段名2,字段3) values('值1','值2','值3'),('值1','值2','值3')
update `表名` set `列1`='值1',`列2`='值2',`列3`='值3' where 條件
delete from `表名` where id=1;
truncate `表名`
//delete 和truncate 都能删除表資料不能删除表結構,但前面的不會影響自增,後者自增會歸零
3.3、DQL查詢資料
資料查詢語言 所有的查詢操作都用它,簡單的查詢,複雜的查詢都能做。
指定查詢字段: select 列名 as 新名字 from student
select 表達式 from 表 where
//去重,去除select語句查詢出來的結果中重複的資料
select distinct ``from 表 where
模糊查詢 (比較運算符)
like a like b % % _ _
in a in b
聯表查詢
join on 連接配接查詢
inner join
right join 以右表為基準
left join 以左表為基準
-------- 我要查詢哪些資料 從哪幾個表裡查
自連接配接
一張表拆為兩張一樣的表
3.4、分頁和排序
//排序,升序 ASC 和降序 DESC
order by 某個字段 ASC/DESC
//分頁
limit 起始位置 ,頁面的大小
3.5、子查詢
///select的嵌套
where(這個值是計算出來的)
3.6、分組和過濾
group by
having
4、Mysql函數
常用函數
聚合函數
count() 計數
//count(字段)會忽略所有的null值
count(*)不會忽略null值
count(1)不會忽略null值
sum() 求和
5、事務
5.1、什麼是事務
要麼都成功,要麼都失敗
将一組sql放在一個批次中去執行
事務有原則:ACID原則
原子性:要麼都成功,要麼都失敗
一緻性:事務前後的資料完整性要保持一緻
隔離性:多個使用者并發通路資料庫時,資料庫會為每一個使用者開啟的事務,不能被其他的事務操作所影響
持久性:事務的結束狀态不會随外界的原因導緻資料丢失(事務沒有送出,恢複原資料)
事務的隔離級别
隔離會産生的問題
髒讀 一個事務讀取了另外一個事務未送出的資料
不可重複讀 在一個事務内讀取表中的某一行資料,多次讀取的結果不同
幻讀 一個事務内讀取到了别的事務插入資料,導緻前後讀取不一緻
通過隔離級别來解決
第一種隔離級别:Read uncommitted(讀未送出)
如果一個事務已經開始寫資料,則另外一個事務不允許同時進行寫操作,但允許其他
事務讀此行資料,該隔離級别可以通過“排他寫鎖”,但是不排斥讀線程實作。這樣就
避免了更新丢失,卻可能出現髒讀,也就是說事務B讀取到了事務A未送出的資料
第二種隔離級别:Read committed(讀送出)
如果是一個讀事務(線程),則允許其他事務讀寫,如果是寫事務将會禁止其他事務訪
問該行資料,該隔離級别避免了髒讀,但是可能出現不可重複讀。事務A事先讀取了
資料,事務B緊接着更新了資料,并送出了事務,而事務A再次讀取該資料時,資料
已經發生了改變。
第三種隔離級别:Repeatable read(可重複讀取)
可重複讀取是指在一個事務内,多次讀同一個資料,在這個事務還沒結束時,其他事
務不能通路該資料(包括了讀寫),這樣就可以在同一個事務内兩次讀到的資料是一樣
的,是以稱為是可重複讀隔離級别,讀取資料的事務将會禁止寫事務(但允許讀事
務),寫事務則禁止任何其他事務(包括了讀寫),這樣避免了不可重複讀和髒讀,但是
有時可能會出現幻讀。(讀取資料的事務)可以通過“共享讀鏡”和“排他寫鎖”實作。
第四種隔離級别:Serializable(可序化)
提供嚴格的事務隔離,它要求事務序列化執行,事務隻能一個接着一個地執行,但不
能并發執行,如果僅僅通過“行級鎖”是無法實作序列化的,必須通過其他機制保證新
插入的資料不會被執行查詢操作的事務通路到。序列化是最高的事務隔離級别,同時
代價也是最高的,性能很低,一般很少使用,在該級别下,事務順序執行,不僅可以
避免髒讀、不可重複讀,還避免了幻讀

mysql是預設開啟事務自動送出的
6、索引
索引是幫助Mysql高效擷取資料的資料結構
索引的使用
1、在建立表的時候建立索引
2、添加一個索引
ALTER TABLE ·表名·ADD INDEX `索引名`(`列名`)
3、 CREATE INDEX 索引名 on 表 (`字段`)
6.1、索引的類型
主鍵索引
唯一的辨別,主鍵不可重複,隻能有一個列作為主鍵
唯一索引
避免重複的列出現,唯一索引可以重複,多個列都可以辨別位 唯一索引
正常索引
預設的,index,key關鍵字來設定
全文索引
在特定的資料庫下
6.2、索引法則
索引不是越多越好
不要對程序變動資料加索引
小資料量的表不需要加索引
索引一般加在常用來查詢的字段上
索引的資料類型
hash類型的索引
btree:innoDB的預設資料結構
7、資料庫三大範式
三大範式
第一範式(1nf):要求資料庫表中的每一列都是不可分割的院子資料項
第二範式(2nf):必須滿足第一範式,每張表隻描述一件事情
第三範式(3nf):第三範式需要確定資料表中的每一列資料都與主鍵直接相關,而不是間接相關
8、JDBC
8.1、資料庫驅動
不同的資料庫有不同的驅動
8.2、JDBC
步驟總結
1、加載驅動
2、連接配接資料庫 DriverManager
3、擷取執行的sql對象 Statement
4、獲得傳回的結果集
5、釋放連接配接
import java.sql.*;
public class JDBCTest {
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1、加載驅動
Class.forName("com.mysql.cj.jdbc.Driver");
//2、使用者資訊和url
String url = "jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8";
String username = "root";
String password = "?????";
//3、連接配接成功,資料庫對象
Connection connection =DriverManager.getConnection(url,username,password);
//4、執行sql的對象statement
Statement statement =connection.createStatement();
//5、去執行結果
String sql = "SELECT `name` FROM `student`";
ResultSet resultSet = statement.executeQuery(sql);
while(resultSet.next()){
System.out.println("name="+resultSet.getObject("name"));
}
//6、釋放連接配接
resultSet.close();
statement.close();
connection.close();
}
}
url
String url = "jdbc:mysql://localhost:3306/study?useUnicode=true&characterEncoding=utf8&useSSL=true&serverTimezone=GMT%2B8"
協定://主機位址:端口号/資料庫名?參數1&參數2.&參數3
jdbc中的Statement對象用于向資料庫發送sql語句
9、sql注入
存在sql注入的本質是sql語句被拼接
import com.han.jdbc.utils.JDBCutil;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
public class sqlInjection {
public static void main(String[] args) {
login("'or ' 1=1");
}
public static void login(String name){
Connection conn = null;
Statement st = null;
ResultSet rs = null;
try {
conn = JDBCutil.getConnection();
st = conn.createStatement();
String sql = "SELECT * FROM student WHERE `id` = 1 AND `name` = '"+ name +" '";
ResultSet resultSet = st.executeQuery(sql);
while(resultSet.next()){
System.out.println("name="+resultSet.getObject("name"));
}
} catch (SQLException e) {
e.printStackTrace();
}finally {
JDBCutil.release(conn,st,rs);
}
}
}
PrepareStatement對象
可以防止sql注入,并且效率更高
本質是把傳遞進來的參數當做字元
10、資料庫連接配接池
資料庫連接配接 --執行完畢 --釋放 十分浪費資源
池化技術 :準備一些預先的資源,過來久了連接配接預先準備好的
編寫連接配接池,實作一個接口 DataSource
無論使用什麼資料源,本質是一樣的,DataSource接口是不會變的,方法是不會變的。