本周总结
一、数据库
1、约束之外键约束
foreign key
设置方式:
1)创建表的时候直接添加外键
CREATE TABLE emp(
id INT PRIMARY KEY AUTO_INCREMENT, -- 员工编号
NAME VARCHAR(20), -- 员工姓名
gender VARCHAR(10), -- 性别
dept_id INT, -- 部门编号
CONSTRAINT fk_demp_emp -- 声明 外键名称
FOREIGN KEY (dept_id) -- 作用在指定从表的指定字段
REFERENCES -- 关联
dept(id) -- 部门表的主键id
2)通过alter table 表名 add … 方式添加
-- 通过修改表添加外键
ALTER TABLE
emp
ADD
CONSTRAINT -- 声明
fk_demp_emp -- 外键名称
FOREIGN KEY (dept_id) -- 作用在指定从表的指定字段
REFERENCES -- 关联
dept(id) ; -- 部门表的主键id
删除外键约束:
ALTER TABLE emp DROP FOREIGN KEY 外键名称
有了外键有关联关系,所以不直接操作主表,需要先修改从表,或者删除外键约束
级联操作 :CASCADE
级联修改:ON UPDATE CASCADE
当前修改主表的数据,那么从表和主表相关联的数据一定会被随着改变
级联删除: ON DELETE CASCADE
当删除主表的数据时,从表和主表相关联的数据也会被删除
2、数据库的备份和还原
1)图形界面化:简单直观
选择数据库—右键----备份---->选择导出的路径(结构以及数据都保存)
之前存在库,然后选择 执行指定sql脚本----> 选择指定的sql脚本—进行执行即可!
2)命令行方式
备份:mysqldump -uroot -p密码 备份数据库名称 > 保存的本地地址
还原:将原来删除,新建库,使用库,source将保存的本地地址
3、 表于表的关系
一对一:是一种特例 (应用场景不多)
举例: 人和身份证
一个人对应一张身份证
一个身份证属于某个人的
一对多的关系 ,多对多的关系
员工表和部门表
一个部门可以有多个员工,一个员工属于某一个部门的(员工表中有一个外键)
4、数据库的三大范式:
1NF :数据库表的每一列都是不可分割的原子数据项
不能出现复合项
2NF :第二范式就是在第一范式的基础上所有列(所有字段)完全依赖于主键列(主键字段)
3NF :在第二范式2NF的基础上,非主键字段不能传递依赖于主键,需要通过外键解决
5、多表查询
1)内连接查询
隐式内连接:通过where语句作为连接条件来查询(按照外键关联关系)
操作步骤:
– 1)查询哪张表
– 2)要查询的是指定表中的哪个字段
– 3)表和表之间的关联关系问题
显示内连接 :
– select <字段列表>
– from 表名1
– (inner) join
– 表名2
– on 关联关系(连接条件);
内连接查询出现的问题:只能查出交集部分的数据
2)外连接查询
左外连接 :
left(outer) join: 通用
将两表中左表的数据全部进行查询并且将交集部分的数据全部查询
右外连接:
right (outer) join
语法格式:
select
字段列表
from
表名1 --左表
left outer join 表名2
on 连接条件 ;
3)子查询
情况1:单行单列的情况:通常使用运算符进行操作
情况2:多行多列的情况:使用关键字in(集合数据)
情况3:使用select语句查询的结果作为一个虚表,使用这个虚表然后与其他表进行查询
-- 入职日期 join_date > '2011-03-14' 将查询作为虚表 和部门表继续进行查询
SELECT * FROM emp WHERE join_date > '2011-03-14';
-- 可以使用左外连接
SELECT
t2.*, -- 员工的所有信息
t1.`name` '部门名称'
FROM
dept t1 -- 部门表
LEFT OUTER JOIN
(SELECT * FROM emp WHERE join_date > '2011-03-14') t2
ON
t1.`id` = t2.`dept_id` ;
-- 最基本隐式内连接
SELECT
t1.* , -- 员工所有信息
t2.`name` -- 部门名称
FROM
emp t1 ,
dept t2
WHERE
t1.`dept_id` = t2.`id`
AND
t1.`join_date` > '2011-03-14' ;
6、 事务
事务:在业务操作过程中,一次性可能同时操作多个sql语句,防止 操作多个sql语句时候出现问题,将这整个业务操作看成一个整体,进行处理
– 这些多个sql要么一次性全部执行成功,要么同时失败!
事物的特点 :ACID
1)原子性:就是事物操作业务中的sql ,要么同时执行成功,要么同时失败
2)一致性:操作sql语句的前后,总数量保持不变
3) 隔离性:
将业务使用事务管理,业务与业务之间分离
事物与事物之间不能相互影响
4)持久性:如果一旦事务被提交了,是永久存储的
隔离级别:
read uncommitted :读未提交 安全性最差 不能有效防止脏读
read committed :读已提交 安全性相比上个高,能有效防止脏读,不能够防止可重复读的问题
repeaable read :可重复读 能够有效防止脏读,可重复读
serializable :串行话
查询隔离级别:
select @@tx_isilation; ------------5,1/5,7
select @@ transaction_isolation; -----------8,0
设置隔离级别 set global transaction isolation level 级别字符串;
隔离级别不同,会出现的不同问题:
1)脏读:一个事务读取另一个没有提交的事务
2)不可重复读:一般都是update语句影响,两个事务中,一个事务读取的前后内容不一致
3)幻读:一般insert/delete :影响两个事务中,前后数量不一致
二、JDBC
1、介绍
jdbc的本质就是能够实现sun公司提供的java.sql包下的相关的接口的实现类
使用java连接数据库的过程
1)在java项目添加额外的第三方的jar包
2)注册驱动
3)获取数据库的连接对象
4)准备静态sql语句
5)通过数据库连接对象创建执行对象Statement
6)执行更新操作
7)释放资源
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Statement;
public class JdbcDemo {
public static void main(String[] args) throws Exception {
//1)导包了
//2)注册驱动
Class.forName("com.mysql.cj.jdbc.Driver") ; //mysql8.0 的驱动实现类:com.mysql.cj.jdbc.Driver
//mysql8.0以前的驱动实现类:com.mysql.jdbc.Driver
//3)获取数据库的连接对象
Connection connection = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydb_01?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true", "root", "123456");
//4)准备sql语句
String sql = "insert into account(name,balance) values('赵又廷',1000)" ;
//5)通过数据库连接对象获取执行对象
//public Statement createStatement() ;用于将sql语句发送的数据库的执行器对象
Statement stmt = connection.createStatement();
//6)执行更新操作
//通用方法
//int executeUpdate(String sql) throws SQLException
int count = stmt.executeUpdate(sql);
System.out.println("影响了"+count+"行");
//7)释放资源
stmt.close() ;
connection.close();
}
2、ResultSet接口
ResultSet接口 :一般都是select 查询语句查询的数据表的结果集
需求:将ee_2106这个数据库中的student表数据全部查询并遍历出来!
import java.sql.*;
public class JdbcDemo3 {
public static void main(String[] args) {
Connection conn = null ;
Statement stmt = null ;
ResultSet rs = null ;
//注册驱动
try {
Class.forName("com.mysql.cj.jdbc.Driver") ;
//创建数据库连接对象
conn = DriverManager.getConnection(
"jdbc:mysql://localhost:3306/ee_2106?characterEncoding=utf8&useSSL=false&serverTimezone=UTC&allowPublicKeyRetrieval=true",
"root",
"123456");
//准备sql
String sql = "select * from student" ;
//创建执行对象
stmt = conn.createStatement() ;
//执行sql语句
rs = stmt.executeQuery(sql);
if(rs.next()) {
int id = rs.getInt(1);
String name = rs.getString(2) ;
String gender = rs.getString(3) ;
String email = rs.getString(4) ;
System.out.println(id+"\t"+name+"\t"+gender+"\t"+email);
}
while(rs.next()){
int id = rs.getInt("id");
String name = rs.getString("name") ;
String gender = rs.getString("gender") ;
String email = rs.getString("email") ;
System.out.println(id+"\t"+name+"\t"+gender+"\t"+email);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (SQLException e) {
e.printStackTrace();
}finally {
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
e.printStackTrace();
}
}
if(conn!=null){