华清远见-重庆中心-数据库/知识点梳理/个人总结

数据存储形式

  • 文件(存储在硬盘)

  • 文件存储的格式

  • 对数据处理可以通过Java代码实现

  • 缺点:读写速度慢,硬盘本身的特点就是读写慢

  • 变量(存储在内存)

  • 读写速度快,临时数据的存储

  • 数据库(数据库管理系统)

  • 数据库管理系统(DBMS database manage system)是一套软件,是一种存储和管理数据表的软件系统

适用于大数据,支持多人并发操作

  • 数据库中的数据是永久存储,数据操作效率高

数据库分类

  • 关系型数据库(存储在硬盘):MySQL、sql server、oracle、db2

  • 数据以二维表的方式存储

  • 实体之间的关联关系

  • 支持SQL(Structured Query Language)结构化查询语言

  • 非关系型数据库(存储在内存):redis、MongoDB、Hbase...

  • 数据按不同的数据类型存储

  • 不支持SQL

ER模型(E-entity 实体,R-relation 关系)

  • ER模型,就是将数据库中的table之间的关系,以图形的方式展示出来

  • ER模型,就是创建数据库表的依据

  • 矩形代表实体,菱形代表关系,椭圆代表实体的属性

  • 实体之间的关系:

  • 1对1:一个国家有一个总统

  • 1对多:一个班级有多个学生

  • 多对多:课程和学生

MySQL中常见的数据类型

类型

说明

解释

tinyint

短整型

对应java的 byte,short

int

整型

对应java的int

bigint

长整型

对应java的long

float

单精度浮点型

对应java的float

double

双精度浮点型

对应java的double

decimal

指定总长度,及其小数占的位数

比如:decimal(10,3)

char(长度)

定长字符串

对应java的string,比如char(5),表示必须是5位的字符串,不够就用空占位

varchar(长度)

可变长字符串

对应java的string,比如varchar(50),表示最大50位,以字符串的实际长度为准

text

文本

date

日期

yyyy-MM-dd

time

时间

HH:mm:ss

datetime

日期时间

yyy-MM-dd HH:mm:ss

timestamp(14或8)

毫秒

保存时间毫秒数,14表示yyyyMMddHHmmss,8表示yyyyMMdd

约束

约束名字

概念

关键字

非空约束

是否允许字段位null

null表示可以为空,not null表示不能为空

主键约束

主键(primary key),保证每行数据不重复,并且主键值不能是null。

一般会在建表的时候,给表设计要给id字段

primary key

唯一约束

保证字段值不重复

unique

外键约束

在有这个主从关系的表中,给有管理关系的字段,设置为外键约束,这个字段值,只能参考主表中的某个字段的值

foreign key references

默认值

可以设置某个字段的默认值,如果没有给这个字段设置数据值,就采用默认值

default

Mysql的命令行操作

  • 链接mysql服务器

mysql -u root -p
Enter password:密码
  • 使用mysql的命令

show databases;		 --显示所有的数据库
use a;			  	 --选择要使用的数据库的名字
show tables;		 --显示a数据库中的所有表
desc lwg(表名);		    --查看指定表的结构
					--Field	,字段
					--Type	,字段类型
					--Null	,是否允许为空
					--Key	,是否为主键
					--Default,默认值
					--Extra ,描述信息
+----------+--------------+------+-----+---------+----------------+
| Field    | Type         | Null | Key | Default | Extra          |
+----------+--------------+------+-----+---------+----------------+
| id       | bigint       | NO   | PRI | NULL    | auto_increment |
| username | varchar(200) | YES  |     | NULL    |                |
| password | varchar(200) | YES  |     | NULL    |                |
| city     | varchar(200) | YES  |     | NULL    |                |
| data     | varchar(200) | YES  |     | NULL    |                |
| email    | varchar(200) | YES  |     | NULL    |                |
+----------+--------------+------+-----+---------+----------------+
insert into lwg (username,password,city) values('root','123546','重庆');--插入数据的sql语句
Query OK, 1 row affected (0.35 sec)								--插入数据成功后的提示信息
select * from lwg;			--查询数据
+----+----------+----------+------+------+-------+
| id | username | password | city | data | email |
+----+----------+----------+------+------+-------+
|  1 | root     | 123546   | 重庆 | NULL | NULL  |
+----+----------+----------+------+------+-------+
1 row in set (0.00 sec)
update lwg set city='渝中区' where username='root';		-- 修改数据
Query OK, 1 row affected (0.31 sec)
Rows matched: 1  Changed: 1  Warnings: 0		-- 成功后的提示信息

select * from lwg;
+----+----------+----------+--------+------+-------+
| id | username | password | city   | data | email |
+----+----------+----------+--------+------+-------+
|  1 | root     | 123546   | 渝中区 | NULL | NULL  |
+----+----------+----------+--------+------+-------+
1 row in set (0.00 sec)							--表中数据已被修改

delete from lwg;			--删除数据
Query OK, 1 row affected (0.01 sec)				--删除成功后的提示信息
select * from lwg;
Empty set(0.00 sec)			--没有数据后显示为空
drop table lwg;				--删除名为lwg的表
Query OK, 0 rows affected (0.05 sec)
select * from lwg;							
ERROR 1146 (42S02): Table 'lwg.lwg' doesnt exist	-- 报错显示表不存在
drop database lwg;			--删除名为lwg的数据库
create database cms;		--创建名为cms的数据库
create table test(id int,name varchar(6),pwd varchar(8));	-- 创建一个名字叫test的表
show tables;
+---------------+
| Tables_in_cms |
+---------------+
| test          |
+---------------+
1 row in set (0.00 sec)

SQL(Structured Query Language):结构化查询语言

sql的使用

  • 创建数据库: create database 数。据库名;

create database 数据库名 default character set utf8; -- 指定了数据库的编码

  • 删除数据库:drop database 数据库名;

  • 创建表:

  • create table 表名 (字段 字段类型 约束条件,字段2...);

  • 如果字段名或表名与关键字重复了,就在字段名或表名上添加引号

  • 尽量避免与关键字重名,一般表可以加前缀:cms_stu -- 表示学生表,s_name -- 表示学生表的name字段名

  • 约束条件:not null 表示字段值不能是null

  • int类型的数据,可以设置为自动增长:auto_increment

  • 主键约束: primary key, 一般用于实现表中的每行数据不重复

特点:非空且不重复

  • 删除表

  • drop table 表名;

添加数据 —— insert

数据添加们都是整行添加,每一行数据叫一个record(记录)

  • 给所有字段赋值

  • 表名之后,没有指定字段名,说明添加的所有字段的值,values中按表格结构的顺序,填写上每个字段对应的值。

    insert into 表名 values(字段值1 ,字段值2···);
    insert into school values('1001','重庆大学','1945-10-23','20650','30065');
  • 遇到自增字段,在values中对应的顺序位置用0,null或者default让其自动填充

  • 遇到有默认的字段,不能省略不写,在values中对应的顺序位置用default占位

  • 遇到允许为空的字段,不能省略不写,在values中对应的顺序位置用null占位

  • 给指定的字段赋值

  • 表名之后,指定的字段名,values只需要设置表名之后指定的字段的value值就可以了(一一对应)

insert into 表名(字段1,字段2,字段3) values(字段1值 ,字段2值,字段3值 );
insert into school(sc_code,sc_name,sc_total) values('1001','重庆大学',25833);
  • 没有默认值的非空字段,必须要设置数据值

  • 表名之后的字段顺序必须和values的值的顺序一致

  • 批量添加

  • 用insert into 语句,一次添加多个记录

  • 一次如果需要添加多条数据,使用批量添加,效率更高

insert into 表名 values(值1,值2),(值1,值2).....
insert into school(sc_code,sc_name,sc_total) 
values('1010','重庆大学',25833),
('1011','重庆文理学院',2585533),
('1012','重庆人文科技学院',2583663);

修改数据 —— update

一般修改,主要根据主键进行筛选修改

  • 修改单个字段的所有值

update 表名 set 字段名 = 新值
-- update school set sc_ttal = 100		不合理,这表示吧所有记录中的sc_total都修改为100了
  • 修改多个字段的值

update 表名 set 字段名 = 新值,	字段名 = 新值2.。。。。
-- update school set sc_ttal = 100 ,sc_area = 100		不合理,这表示吧所有记录中的sc_total都修改为100了,总面积都修改为100
  • 根据条件修改数据(where)

update 表名 set 字段名 = 新值 where 条件
update 表名 set 字段名 = 新值,	字段名 = 新值2.。。。。 where 条件
  • 指定值

update 表名 set 字段名 = 新值 where 字段名 = 字段值
update school set sc_total=6000 where sc_code = 1002	--修改学校编号是1002的学校人数
  • 指定范围

--1. > , < , >= , <= 表示范围, and  ,or  将多个条件进行关联
update school set sc_total=6120 where sc_code < 1004
--2.使用between...and ,设置要给区间之内
update school set sc_total=6120 where sc_code between 1005 and 1620 -- [1005,1620]
--3.使用!=或<>不等于
update school set sc_total=6120 where sc_code <>1665 --不是1665的就修改
  • 指定集合

-- 1.在某个集合中		in
update school set sc_total=6120 where sc_code in(1001,1002,1003);  -- 修改sc_code等于1001或1002或1003
update school set sc_total=6120 where sc_code =1001 or sc_code = 1002  or sc_code = 1003;
-- 2.不在某个集合中	not in
update school set sc_total=6120 where sc_code not in(1001,1002,1003);	--不修改sc_code等于1001或1002或1003,其他都修改
  • 空值 null

-- 1. is null		表示空
update 表名 set 字段名 = 新值 where 字段 is null
-- 2. is not null	表示非空
update 表名 set 字段名 = 新值 where 字段 is not null
  • 模糊匹配

-- 1.  '_'代表一个任意字符
-- 2.  '%'代表任意个字符(1个或多个)
--以什么开始
sc_name like "重庆%"
--以什么结尾
sc_name like "%大学"
--包含什么
sc_name like "%交通%"
--只能包含4个字符
sc_name like "__大学"
--倒数第二个是大
sc_name like "%大_"

update school set sc_total = sc_total+1000 where sc_name like '%大_'  -- 匹配成功的行,人数增加

删除数据 —— delete(remove,drop)

delete是删除数据本身,表的结构还在

drop是删除表,数据库,结构被删除了,数据自然被删除了

  • 删除所有数据

  • delete会保留自增列删除前的值,继续添加新数据,从删除前的最大一个数值开始增加

  • truncate会重置自增列的值,效率高

  • 如果有主从表关系,建议先删除从表的数据,再删除主表的数据

delete from 表名
-- 或
truncate table 表名
  • 根据添加删除

  • 根据主键删除

delete from 表名	where 主键字段 = 值
delete from book_info where book_id = 1006	--删除主键为1006的书
  • 参考update中的where条件的写法

-- 练习: 删除book_id是1004到1008区间的
delete from book_info where book_id between 1004 and 1008;

-- 练习:删除booK_id不是1001,1004,1007的
delete from book_info where book_id not in(1001,1004,1007)
  • 删除表结构

drop table 表名

查询 — select

  • 全表查询

select * from 表名	--	*表示的是所有字段名
select * from school	 --查询school表的所有数据
select 列名1,列名2...  from 表名 --直接把所有列名写出来
select sc_code,sc_name,sc_birth,sc_address,sc_total,sc_area from school   			--等同于select * from school
  • 查询指定的列

select 列名1,列名2 from 表名  -- 只查找出指定的列
select sc_name,sc_address from school  --只显示学校的名字和地址
  • 条件查询(筛选行)——where

  • 模糊查询——like

-- 模糊查询是针对字符类型(char,varchar)
-- % ,任意个字符
-- _ , 一个字符
select * from 表名 where 字段名 like 
  • 数据的条件查询

-- > , < , >= , <= , = , != , <>
select * from 表名 where 字段名 [> , < , >= , <= , = , != , <>]数据值
  • 使用关键字,实现条件的组合

-- and , or , in , not in , between...and
select * from 表名 where 条件1 and[or] 条件2
select * from 表名 where 字段名 in[not in](数据1,数据2......) or 条件 and ....
  • 去掉重复的行 —— distinct

select distinct * from 表名 where 条件
  • 给字段取昵称

select 字段1 as "1",字段2 as "2" from 表名 where 条件		--as 用于取别名,1是字段1的别名,2是字段2的别名
select 字段1  "1",字段2  "2" from 表名 where 条件			--as可以省略
select school.sc_code code,school.sc_name name from school
  • 多表查询 —— 两张表

  • 交叉连接、笛卡尔积

集合A:{a,b}

集合B:{1,2,3}

集合A * 集合B = {a1,a2,a3,b1,b2,b3}

将两张表中的数据两两组合,得到的结果就是交叉连接的结果,也成为笛卡尔积

select * from 表1 ,表2
select * from 表1 cross join 表2  -- cross
select * from 表1 inner join 表2  -- inner
-- 两张表数据组成一张表,其中有很多无效数据
  • 内连接

通过主表主键字段和从表外键字段进行等值判断

主表和从表字段名一样,使用“表名.字段名”进行区分,可以给表取别名

如果用where进行内连接,后续还有其他条件的查询,使用and拼接 后续条件

如果用 inner join /on join ,后续有其他条件,使用where进行条件拼接

只显示两张表中有关联的数据

select * from 表1 ,表2 where 表1.字段 = 表2.字段	--判断相等的字段就是有外键约束的字段
select * from 表1 inner join 表2 on 表1.字段 = 表2.字段-- on后买你的相等字段判断,也是有外键约束的字段
-- 查询学生的学生信息和班级信息
select * from t_stu,t_class where t_stu.c_id = t_class.c_id
select * from t_stu,t_class where t_stu.c_id = t_class.c_id and t_stu.money > 5000		-- 使用and拼接查询条件
select * from t_stu inner join t_class on t_stu.c_id = t_class.c_id where t_stu.money > 5000 	-- 加上关键字where后,拼接条件
  • 左连接

左表内容全显示,右表只显示有关联的数据

保证左表的数据完整,关联右表中的数据,没有关联的数据用null表示

select * from 左表 left join 右表 on 左表.字段=右表.字段     -- 左连接
-- 查询学生和班级信息
select * from t_class c left join t_stu s on c.c_id=s.c_id	-- 左表内容全显示
select * from t_stu s left join t_class c on c.c_id=s.c_id
  • 右连接

右表内容全显示,左表只显示有关联的数据

保证右表的数据完整,关联左表中的数据,没有关联的数据用null表示

select * from 左表 right join 右表 on 左表.字段=右表.字段     -- 右连接
select * from t_class c right join t_stu s on c.c_id=s.c_id	-- 右表内容全显示
select * from t_stu s right join t_class c on c.c_id=s.c_id
  • 子查询

子查询是在查询语句中,嵌套了另一个查询语句,也可以嵌套查询

  • 子查询作为where条件

-- 查询出班级名字为"软件技术11班"的所有学员
select * from t_stu where c_id = (select c_id from t_class where c_name='软件技术11班')
-- 查询出没有学生的班级
select * from t_class where c_id not in(select c_id from t_stu)  -- 查询出学生的班级c_id,不在这些c_id中的班级就没有学生
  • 子查询是作为一张临时表

如果把子查询的结果作为一张临时表,必须要把子查询的结果,设置一个别名

-- 查询出所有男生 ,工资大于5000
-- 先用一个查询,查询出所有男生,然后在跟这个结果中,查询出工资大于5000的
select * from (select * from t_stu where s_sex = '男') stuman where s_money >5000
  • 子查询作为一个字段

如果子查询的结果作为一个字段,那么要求该子查询每次只能返回一行记录

-- 查询出所有班级名字和学生名字
select (select c_name from t_class c where c.c_id = s.c_id) as c_name , s_name from t_stu ss

修改表结构

  • drop table,然后重新建

  • 给表增加字段

alter table 表名 add 字段名 字段类型  -- alter 修改
alter table dept add d_phone varchar(20) -- 给dept表增加一个字符串类型的字段d_pohoe
  • 删除表中的字段名

alter table 表名 drop 字段名 字段类型  -- alter 删除字段名
alter table dept drop d_phone        -- 删除dept表的d_phone字段名
  • 修改表中的字段名

alter table 表名 modify 原字段名 新的类型   -- 修改字段的类型
alter table dept modify d_note int
  • 修改字段名

alter table 表名 change 原字段名 新字段名 新字段类型
alter table dept change d_note d_note1 varchar(200)
  • 修改表名

alter table 表名 rename to 新表名
alter table emp rename to employee				-- 修改表名
  • 增加外键约束

alter table 从表名 add constraint 约束名 foreign key(字段名) references 主表名
alter table t_stu add constraint fk_stu_class foreign key(c_id) references t_class(c_id)  		-- 在c_id字段添加一个名叫fk_stu_class的外键
  • 删除外键约束

alter table 表名 drop foreign key 约束名字
alter table t_stu drop foreign key fk_stu_class   -- 根据约束名字,删除约束
  • 添加约束

-- 添加唯一约束
alter table 表名 add unique (字段名)
-- 添加非空约束
alter table 表名 change 原字段名 新字段名 数据类型 not null
-- 添加主键约束
alter table 表名 add primary key(字段名)
-- 添加默认值
alter table 表名 字段名 set default 默认值

函数

  • 统计函数(聚合函数)

select 统计函数字段名 from 表名

函数名

功能

count(字段名),count(*)

统计行数

sum(字段名)

求和

avg(字段名)

平均值

max(字段名)

最大值

min(字段名)

最小值

  • 数学相关的函数

select 函数(字段名) ...... from 表名

select sc_name ,round(sc_area) from school

函数名

功能

round(字段名 或 值)

四舍五入

ceil(字段名)

向上取整

floor(字段名)

向下取值

abs(字段名)

绝对值

pow(字段名)

sqrt(字段名)

平方根

  • 字符串函数

select 函数(字段名) ...... from 表名

select reverse(sc_name) ,round(sc_area) from school --反转学校名

select concat(sc_name,sc_birth) from school --学校名字和建校日期拼接

函数名

功能

trim(字段名)

去掉字符串前后多余的空格

lenth(字段名)

计算字符串的长度

substr(字段名,start)

截取字符串

lcase(字段名)

转小写

ucase(字段名)

转大写

reverse(字段名)

反转

concat(字段名1,字段名2...)

拼接

  • 时间函数

select 函数(日期相关的字段名) ...... from 表名

select now() -- 得到系统时间

select current_date() -- 得到当前日期

select sc_name ,year(sc_birth) from school

函数名

功能

now()

当前日期时间

current_date() ,curdate()

当前日期

current_time() ,curtime()

到期时间

year/month/day(日期相关的字段名)

得到时间分量

datediff(时间,时间)

计算相隔的天数

数据库中的其他对象

  • 视图(view)- 虚表

可以使用select语句查询视图中的数据

修改了视图中的数据,会同时修改到原表中的数据,建议不要修改视图的数据

create view 视图名字 as select ... 
--- 查出女生的信息,保存在视图当中
create view v_student as select s_id,s_name,s_age,s_sex from student where s_sex='女'
--- 视图名字:v_student
--- 视图内容: select s_id,s_name,s_age,s_sex from student where s_sex='女'

-- 查询出所有的女生
select * from v_student	-- 在视图中查找数据
drop view 视图名字		-- 删除视图
  • 索引(index) - 有助于提高查询的效率

create index 索引名字 on 表名(字段名) -- 给表中的字段创建索引
create idnex idx_stu_name on student(s_name) --给student表的s_name创建了索引
drop index 索引名 on 表名
drop index idx_stu_name on student		--删除索引
  • PL/SQL - 存储过程

  • 复杂的逻辑通过java程序来实现

  • DBA - 数据库管理员

create procedure p_test(in a int , out b int)	--  p_test是存储过程的名字 , a - 输入参数, b - 输出函数
begin
	select s_age into b from student where s_id =  a ;	-- 存储过程的功能:根据id,查询出学生的年龄
end
set @a = 2;
call p_test(@a,@b);
select @b;

JDBC - JAVA Database Connection

jdbc:java 连接数据库,进行数据库中数据的操作:insert , update , dalete , select

jdk中提供了一套操作数据库的接口:java.sql.*,每一个数据库厂商,实现这些对应的接口,把这些实现类打包为.jar文件。

比如:使用mysql服务器,下载mysql对应的jar包,使用的oracle服务器,下载对应的oracle的jar包。

jar包:以 .jar 为后缀的文件,称为java的归档文件,保存的是java的字节码文件(.class),在我们的java工程中,导入 .jar 文件,就可以使用这些 .class

  • 核心接口

  • Connection,用于设置连接数据库的地址,账号,密码

  • PreparedStatement,用于预处理,始行sql

  • ResultSet,用于接收查询后的数据

  • 项目中导入数据库驱动程序包 -jar

  1. 把msql的驱动程序包,添加到项目中(建一个lib文件夹,然后把jar包复制到这个文件夹中)

  1. 在.jar文件上,右键,选择"add as library"

  • 查询

package test;

import entity.School;
import java.sql.*;

public class SchoolTest {
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/bookdb?serverTimeZone=Asia/shanghai";
        String user = "root";
        String pwd = "123456";
        Connection con = DriverManager.getConnection(url, user, pwd);
        System.out.println(con);
        String sql = "select * from school";
        PreparedStatement ps = con.prepareStatement(sql);
        ResultSet rs = ps.executeQuery();
        while(rs.next()){
            int code = rs.getInt(1);
            String name = rs.getString(2);
            Date birth = rs.getDate(3);
            String address = rs.getString(4);
            int total = rs.getInt(5);
            double area = rs.getDouble(6);
            School school = new School(code, name, birth, address, total, area);
            System.out.println(school);
        }
        rs.close();
        ps.close();
        con.close();
    }
}
  • 增加

package test;

import entity.School;

import java.sql.*;
import java.util.Date;
import java.text.ParseException;
import java.text.SimpleDateFormat;

public class SchoolInsert {
    public static void main(String[] args) throws ClassNotFoundException, SQLException, ParseException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/bookdb?serverTimeZone=Asia/shanghai";
        String user = "root";
        String pwd = "123456";
        Connection con = DriverManager.getConnection(url, user, pwd);
        System.out.println(con);
        String sql = "insert into school values (?,?,?,?,?,?)";
        PreparedStatement ps = con.prepareStatement(sql);
        ps.setInt(1, 3);
        ps.setString(2, "重庆兴渝学校");
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        Date date = sdf.parse("2022-08-04 00:00:00");
        long dateTime = date.getTime();
        ps.setDate(3, new java.sql.Date(dateTime));
        ps.setString(4, "重庆市九龙坡区二郎新区大道99号");
        ps.setInt(5, 10000);
        ps.setDouble(6, 5220.2);
        int i = ps.executeUpdate();
        if (i > 0) {
            System.out.println("添加成功");
        }else {
            System.out.println("添加失败");
        }
        ps.close();
        con.close();
    }
}
  • 修改

package test;

import java.sql.*;
import java.text.ParseException;

public class SchoolUpdate {
    public static void main(String[] args) throws ClassNotFoundException, SQLException, ParseException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/bookdb?serverTimeZone=Asia/shanghai";
        String user = "root";
        String pwd = "123456";
        Connection con = DriverManager.getConnection(url, user, pwd);
        System.out.println(con);
        String sql = "update school set sc_code = 5,sc_name ='重庆中学' where sc_code=3";
        PreparedStatement ps = con.prepareStatement(sql);
        int i = ps.executeUpdate();
        if (i > 0) {
            System.out.println("修改成功");
        } else {
            System.out.println("修改失败");
        }
        ps.close();
        con.close();
    }
}
  • 删除

package test;

import java.sql.*;
import java.text.ParseException;

public class SchoolDelete{
    public static void main(String[] args) throws ClassNotFoundException, SQLException, ParseException {
        Class.forName("com.mysql.cj.jdbc.Driver");
        String url = "jdbc:mysql://localhost:3306/bookdb?serverTimeZone=Asia/shanghai";
        String user = "root";
        String pwd = "123456";
        Connection con = DriverManager.getConnection(url, user, pwd);
        System.out.println(con);
        String sql = "Delete from school where sc_code = 5";
        PreparedStatement ps = con.prepareStatement(sql);
        int i = ps.executeUpdate();
        if (i > 0) {
            System.out.println("删除成功");
        }else {
            System.out.println("删除失败");
        }
        ps.close();
        con.close();
    }
}

事务

事务是由一组数据sql语句组成的执行单元(几个sql是要一个整体操作),这些sql语句之间一般互相依赖,那么这些sql语句要么全部成功,要么全部失败(原子性)

  • 事务的使用

  • 提交:commit,事务执行成功,需要commit

  • 回滚: rollback,事务执行失败了。需要rollback,回滚到事务执行之前的状态

  • java中的jdbc默认是自动提交了

  • con.setAutoCommit(false): 设置了不自动提交,那么sql执行之后,需要主动提交:con.commit();

 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/cms?serverTimeZone=Asia/shanghai";
        String user = "root";
        String pwd = "123456";
        //3.获取连接
        Connection con = DriverManager.getConnection(url, user, pwd);
        con.setAutoCommit(false);
        //4.增加(insert...)
        String sql = "insert into book_info values(0,'基督山伯爵','大促马',19.6,'1655-02-15',1001,2)";
        PreparedStatement ps = con.prepareStatement(sql);
        int i = ps.executeUpdate();// i -- 返回行数
        if (i>0){
            System.out.println("添加成功");
        }else {
            System.out.println("添加失败");
        }
        con.commit();  // 提交
        //5.释放资源
        ps.close();
        con.close();
  • 事务的特性ACID

  • 原子性:atomicity,事务是最小的执行单元

  • 一致性:Consistency,事务执行的前后,必须让所有的数据保持一致状态。(总体数据守恒)

  • 隔离性:Isolation,事务并发时相互隔离,互补影响

  • 持久性:Durability。事务一旦提交,对数据的改变是永久的

  • 事务并发可能出现的问题

在同一时间同时执行了多个事务,称为事务的并发

事务并发可能会出现以下问题:

问题

描述

脏读

事务A读取到了事务B未提交的数据

不可重复读

事务A中如果读取两次数据,在这期间,事务B对数据进行了修改并提交,导致事务A读取两次的数据情况不一致

幻读

事务A读取id从1~10之间的数据,假如只有到2,5数据,在读取的期间,事务B添加了id为3的数据。导致事务A多读到了事务B中的数据

  • 事务的隔离级别

为了防止事务并发时出现以上的情况。数据库中设计了集中事务与事务之间的隔离级别

隔离级别

能否出现脏读

能否出现不可重复读

能否出现幻读

Read Uncommited 未提交读(RU)

Read Commited 已提交读(RC)默认(Oracle)

不会

Repeatable Read 可重复读(RR)

不会

不会

Serializable 可以序列化

不会

不会

不会

redis - 非关系型数据库

  • 关系型数据库:mysql 、oracle ,以二维表的形式存储在硬盘上,支持sql语言

  • 非关系型数据库:redis,存储在内存中,不支持sql语言

  • redis 安装

  • 双击安装包

  • redis 的命令

通过命令,存,取,改,删数据

  • 字符串操作

set user alice		-- 保存一个key是user,value是alice的字符串内容到redis服务器
get user			-- 根据key,找到value 
strlen user 		-- 获取长度
getrange user 0 1 	-- 取子字符串
  • hashes操作(hashmap)

hmset hqyj web www.baidu.com tel 023-111 address 总部城A区 -- 存储
了一个hqyj 这个hashmap , 保存了三个键值对
hgetall hqyj 		-- 查看所有的内容
hkeys hqyj 			-- hashmap的键
hvals hqyj 			-- hsahmap 的values
hdel hqyj web 		-- 删除一个键
  • ists 操作

lpush java css 			-- 从队列的左边添加一个
rpush java js 			-- 从队列的右边添加一个
lpush java servert mysql jsp 	-- 一次加多个
lrange java 0 1 		-- 指点范围查看元素
lindex java 1 			-- 查找指定索引位置的元素
lpop java 				-- 从左边出队一个
rpop java 				-- 从右边出队一个
  • set 操作

sadd web html 				 -- 增加一个数据
sadd web css js jquery 		  -- 批量增加
scard web 					 -- 查看数据量
smembers web				 -- 查看成员
srem web jquery 			 -- 删除一个成员
  • key 操作

keys * 				-- 查看所有的键
keys u* 			-- 模糊匹配, 查看u开始的
del key 			-- 删除key
exist key 			-- 判断是否存在
rename key newkey 	 -- 修改名字
type key 			-- 查看key的类型
  • java程序操作redis数据库

  • redis数据库的驱动jar包(redis数据库操作的类)

  • java程序,连接上redis数据库,然后调用操作数据库的各种方法

package test;

import redis.clients.jedis.Jedis;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

public class RedisTest {
    public static void main(String[] args) {
//testString();
//testSet();
//testList();
        testHash();
    }

    // 4.测试hash
    public static void testHash() {
        Jedis jedis = new Jedis("localhost");
        Map<String, String> map = new HashMap<>();
        map.put("语文", "80");
        map.put("数学", "90");
        map.put("英语", "100");
        jedis.hmset("score", map); // 存储
        System.out.println("所有的keys:" + jedis.hkeys("score"));
        System.out.println("所有的values:" + jedis.hvals("score"));
        Map<String, String> score = jedis.hgetAll("score");
        Set<Map.Entry<String, String>> entries = score.entrySet();
        for (Map.Entry<String, String> one : entries) {
            System.out.println(one.getKey() + "---" + one.getValue());
        }
    }

    // 3. 测试list
    public static void testList() {
        Jedis jedis = new Jedis("localhost");
        jedis.lpush("stu", "a1", "a2", "a3");
        jedis.rpush("stu", "a4", "a5", "a6");
        System.out.println("学生的个数:" + jedis.llen("stu"));
        System.out.println("索引为3的学生:" + jedis.lindex("stu", 3));
        List<String> stus = jedis.lrange("stu", 0, jedis.llen("stu") - 1);// 获取全部元素,保存到List中
        System.out.println(stus);
        jedis.lrem("stu", 1, "a1"); // lrem 删除
        System.out.println("出去一个:" + jedis.lpop("stu"));
        jedis.close();
    }

    // 2. 测试set
    public static void testSet() {
        Jedis jedis = new Jedis("localhost");
// 重庆风景区保存redis中
        jedis.sadd("cqfjq", "李子坝", "磁器口", "解放碑", "观音桥");
        jedis.sadd("cqfjq", "杨家坪");
// 查看成员
        Set<String> cqfjq = jedis.smembers("cqfjq");
        for (String s : cqfjq) {
            System.out.println(s);
        }
        Long num = jedis.scard("cqfjq");
        System.out.println("风景区的数量:" + num);
        jedis.close();
    }

    // 1. 测试字符串
    public static void testString() {
        Jedis jedis = new Jedis("localhost"); // 端口号默认是6379
        System.out.println(jedis);
// set user tom -- 命令 , 存要给字符串
        jedis.set("username", "admin");
        System.out.println("redis数据库中的所有key:");
        System.out.println(jedis.keys("*"));
        String username = jedis.get("username");
        System.out.println("username:" + username);
        System.out.println("判断keys是否存储:" + jedis.exists("web"));
        System.out.println("username的长度:" + jedis.strlen("username"));
        jedis.close();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值