数据库基础—下
五.事务 Transaction
5.1 概述
事务:一组操作要么全部完成,要么全部不做,绝不允许只做其中的一部分操作
事务回滚:当一个事务执行过程中发生了异常、错误,则重新回到最先未开始执行的过程
事务提交:当一个事务执行过程没有发生任何异常、错误,这时要保存这个事务的修改
事务特性(ACID)
原子性:整体的,一起成功或一起失败
一致性:【质量守恒】事务提交后的状态一致
隔离性:并发事务先后顺序执行
持久性:事务提交就保存到硬盘,不会因内存清除而清除
5.2 事务隔离问题
脏读【一个事务读取了另一个事务未提交的数据】
不可重复读【数据多次读取结果不同】
幻读【一个事务读取了别的事务插入的数据】
5.3 事务处理
注:mysql 是默认开启事务、自动提交的;每执行一句代码提交一次事务。
关闭\开启事务自动提交
set autocommit = 0
set autocommit = 1
事务开启
start transaction
提交\回滚
commit\rollback
保存点(了解)
savepoint 保存点名
rollback to savepoint 保存点名
release savepoint 保存点名
例:模拟转账事务
set autocommit = 0; -- 关闭自动提交
start transaction; -- 开启事务
update account set mony=mony-400 where `name`='A';
update account set mony=mony+400 where `name`='B';
commit; -- 提交
rollback; -- 回滚
set autocommit = 1;-- 开启自动提交
六.索引(了解)
索引(index)就是在查询的过程中,提高系统的性能的数据结构
6.1索引分类
主键索引:唯一标识,
唯一索引(unique key)
常规索引(Index)
全文索引(FullText)
七.三大范式⭐️
第一范式(1NF)
要求数据表的每一列都是不可再分割的原子数据项
第二范式(2NF)
前提:满足第一范式
说明:消除了非主属性对于码的【部分函数依赖】
备注:所有的属性必须与主属性直接相关(一张表只记录一件事)
第三范式(3NF):
前提:满足第一、第二范式
说明:消除了非主属性对于码的【传递函数依赖】
备注:所有的属性不能依赖于其他非属性**(消除依赖传递)**
【完全依赖】
若一张表有确定的属性X,则必能确定属性Y的值
则 Y依赖于X 记: x->Y
八.JDBC⭐️
8.0 导入数据库驱动
创建一个与src同级的目录lib => 将 mysql-connector-java.jar 文件放入目录 => 右键lib添加库
8.1 连接测试
import java.sql.*;
public class studenKuan {
public static final String URL = "jdbc:mysql://localhost:3306/textdb?useUnicode=true&characterEncoding=utf8&useSSL=false";
public static final String USER = "root";
public static final String PASSWORD = "123";
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//1.加载驱动程序
Class.forName("com.mysql.jdbc.Driver");
//2. 获得数据库连接,获取数据库对象
Connection conn = DriverManager.getConnection(URL, USER, PASSWORD);
Statement statement = conn.createStatement();
//3.执行SQL,查看返回结果
String sql = "SELECT * from nametab";
ResultSet resultSet = statement.executeQuery(sql);
while (resultSet.next()){
System.out.println(resultSet.getObject("name"));
}
//4.释放连接
resultSet.close();
statement.close();
conn.close();
}
}
注:useSSL=false【SQL版本大于connect版本,就要设置成false】
8.2 statement对象
== 用于向数据库发送SQL语句,完成增删改查操作 ==
【查询】statement. executeQuery(sql);
- 返回查询结果集
- 若知返回值类型则如 res.getIndex(); 否则 res.Object();
- 遍历 res.next();
【更新】statement. executeUpdata(sql);
- 返回受影响行数
- 包括 更新、删除、添加 都是更新
【SQL注入】
是通过某种方式将恶意的sql代码添加到输入参数中,然后传递到sql服务器使其解析并执行的一种攻击手法。
本质是使用了字符串拼接方式构造sql语句
8.3 PreparedStatement
== 可以防止SQL注入,效率高 ==
public class text {
public static void main(String[] args) {
try {
login("zhang",123123);
} catch (SQLException e) {
e.printStackTrace();
}
}
public static void login(String uname,int pass) throws SQLException {
Connection conn = null;
// Statement state = null;
PreparedStatement psta =null;
ResultSet resultSet = null;
try {
conn = jdbc.getConn(); //jdbc为自定义连接数据库封装函数
// state = conn.createStatement();
// String sql="SELECT * FROM login where uname = '"+uname+"' and pass ="+pass;
// resultSet = state.executeQuery(sql);
String sql = "SELECT * FROM login where uname =? and pass = ?";
psta = conn.prepareStatement(sql); //预编译
psta.setString(1,uname); // 输入参数1
psta.setInt(2,pass); // 输入参数2
resultSet = psta.executeQuery();
while (resultSet.next()){
System.out.println("欢迎"+resultSet.getString("uname")+"同学");
}
} catch (SQLException e) {
e.printStackTrace();
} finally {
jdbc.closeConn(conn,psta,resultSet);
}
}
}
- 定义sql语句,使用 ? 作为条件值的占位符
- 预编译
conn.prepareStatement(sql)
- 输入参数
setString(占位符位置,参数值)
- 执行
8.4 使用IDEA连接数据库
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-IV3EjlBd-1634963309526)(C:\Users\26552\AppData\Roaming\Typora\typora-user-images\image-20211021212644598.png)]
注:切换数据库、操作数据库、输入SQL命令…都可在工具栏找对应入口
8.5 操作事务
try {
conn = jdbc.getConn();
//关闭数据库自动提交,打开事务
conn.setAutoCommit(false);
...
conn.commit(); //执行成功,提交事务
} catch (SQLException e) {
conn.rollback(); //失败回滚事务(默认回滚)
} finally {
conn.setAutoCommit(true);
jdbc.closeConn(conn,pStatement);
}
8.5 数据库连接池
数据库连接 ---- 执行 ----结束释放
池化技术:准备一些预先设置好的资源,可直接连接
【开源数据源实现】
8.5.1 DBCP
导入架包 : commons-dbcp-1.4 / commons-pool-1.6
8.5.2 C3P0