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接口是不会变的,方法是不会变的。