您的位置:首页 > 博客中心 > 数据库 >

00 MySQL

时间:2022-03-14 01:55

1数据库 1.1名词解释      DB:数据库Database,用于存放数据仓库      DBMS:数据库管理系统 DataBase Management System,管理数据库      table : 表,用于描述实体(对象)集合,需要提供行和列 1.2数据库分类      网状型数据库      层次型数据库      关系型数据库(Relationship DataBase Management System)      非关系型数据库:NoSql (not only sql) 1.3关系型数据库种类      DB2 : IBM公司,收费      Oracle : oracle公司,收费      MS sql server : 微软,收费,只适合window平台      Mysql : 免费


2 Mysql数据库      2.1介绍      2.2安装           gxlsystem.com,布布扣           其中MySQLInstanceConfig.exe可用于绿色版Mysql的设置.            mysql默认端口:3306      mysql将UTF-8编码称为:UTF8(只此一家)      mysql默认账号:root

     gxlsystem.com,布布扣

 

     gxlsystem.com,布布扣


2.3mysql启动和停止      手动方式(了解)           cmd>   mysqld --console      使用window服务           服务开发方式:运行 “services.msc”                启动                     cmd> net start mysql                停止                     cmd> net stop mysql

          gxlsystem.com,布布扣

2.4mysql登录      方式1(推荐):格式  “mysql -u账号 -hip地址 -p密码”           例: cmd> mysql  -uroot -h192.168.18.98 -p1234      方式2:           例: cmd> mysql --user=root --host=192.168.18.98 --password=1234
2.5mysql常用命令      显示当前数据库服务器中的数据库列表           mysql> show databases;      显示当前所使用的数据库名称           mysql> select database();      显示当前数据库的状态           mysql> status;      使用数据库           mysql> use 要使用已存在的数据库名称;      显示数据库中的数据表           mysql>show tables;      显示当前数据库中某表的表结构 (DESCRIBE )           mysql> desc user;      显示所支持的字符集           show character set;   使用sql语句,注意:sql语句必须以分号(;)结尾      %mysql% 表示mysql的安装目录      %mysql%/data/mysql 表示mysql核心数据,切记不能删除
3 SQL语句 3.1介绍      sql:结构化查询语言(structured query language), 是操作和检索(查询)关系型数据库的标准语言.           ?注:ANSI(American National Standards Institute,美国国家标准学会)制定的标准      各个数据库生产厂商,要遵循sql标准,同时又开发出自己数据特有的特性   3.2SQL分类      DDL,Data Definition Language,数据定义语言           管理表的结构和索引的结构 -- 【结构】           保留字:CREATE (create 创建)),DROP (drop 删除),ALTER (alter 修改)        DML,Data Manipulation Language,数据操作语言           用于添加,修改和删除表中的行(记录) -- 【数据】           保留字:INSERT (insert 录入),DELETE(delete 删除)和TRUNCATE ,UPDATE(update 更新)            DQL,Data Queries Language,数据查询语言           用以从表中获得数据 -- 【查询(检索)】           保留字:SELECT (select 查询),WHERE (where 条件),GROUP BY (group by 分组),having和order by(order by 排序)        DTL,Data Transaction Language,事务处理语言           确保被DML语句影响的表的所有行及时得以更新  -- 【事务】           保留字:BEGIN TRANSACTION (begin transaction 开启事务),COMMIT (commit 提交事务)和ROLLBACK(rollback 回滚事务)        DCL,Data Control Language,数据控制语言           授权用户或用户组操作和访问数据的权限  --【权限】           保留字:GRANT(grant 授权)或REVOKE (revoke 取消权限)
3.3DDL:数据定义语言      对数据库、表、列 进行结构的操作   3.3.1数据库操作      创建数据库           mysql> create database [IF NOT EXISTS] 数据库名称 [character set 字符集] ;           数据库默认使用 平台设置编码(my.ini文件)      删除数据库           mysql> drop database [IF EXISTS] 数据库名称;      修改数据库           mysql> alter database character set 修改数据库字符集;(不建议)   3.3.2表操作      创建表           mysql>  create table 表名(字段描述1,字段描述2, … );                * 多个字段描述 使用逗号分隔                * 最后一个字段描述没有逗号           字段描述的格式:字段名 字段类型 [约束]      删除表     mysql> drop table 表名;      修改表     mysql> alter table 表名 rename [to] 新表名;   3.3.3列操作      添加列     mysql> alter table 表名 add [column] 字段描述      删除列     mysql> alter table 表名 drop [column] 字段名      修改列     mysql> alter table 表名 change [column] old_字段名  new_字段描述
3.4字段类型      3.4.1字符串
mysql类型 java类型 描述
char(n) java.lang.String char表示固定字符串,n表示字符个数。
例如:char(5) , 当前字段必须写5个字符.
如果录入的数据”abc”,右侧自动添加空格,结果“abc空空”
varchar(n) java.lang.String varchar表示可变字符串,n表示字符个数. 例如:varchar(5),当前字段最多存放5个字符.
 如果例如的数据”abc”,存放的就是”abc”
       3.4.2数字 gxlsystem.com,布布扣        3.4.3日期 gxlsystem.com,布布扣      注:           java.sql 包下面对象,之后都在dao层使用。           但一般使用java.util.Date 对象                java.util.Date 有三个子类:                java.sql.Date, java.sql.Time,java.sql.Timestamp           java.sql 包创建实例                Date date = new java.util.Date();                new java.sql.Timestamp(date.getTime());
3.4.4大数据      gxlsystem.com,布布扣 字节大数据: blob ,Binary Large Object 字符大数据: clob , Character Large Object
3.5 DML数据操作语言      对指定的表中的数据进行:添加、删除、修改 ?录入数据      格式1: mysql> insert into 表名 values(字段对应的值,值2,值3,….);      格式2: mysql> insert into 表名(字段名1,字段名2,…) values(值1, 值2,….) ?修改数据      格式1: mysql> update 表名 set 字段=值,字段=值,…..            #将表中所有的字段都进行修改      格式2: mysql> update 表名 set 字段=值,字段=值,….  where 条件 # 将符合条件的字段进行修改 ?删除数据      格式1: mysql> delete from 表名;                      #清空表中的所有数据      格式2: mysql> delete from 表名 where 条件;    #删除符合条件
3.6DQL数据查询语言      select distinct 字段|*            from 表名            where 条件                 group by 分组字段                 having 分组条件                 order by 排序字段 asc|desc 3.6.1准备数据      create table t_user(           id varchar(22) primary key,           firstname varchar(22),           age smallint,           secondname varchar(22),           counts smallint      );        insert  into `t_user`(`id`,`firstname`,`age`,`secondname`,`counts`)            values (‘u001‘,‘张‘,18,‘飞‘,60),                  (‘u002‘,‘赵‘,20,‘云‘,58),                  (‘u003‘,‘关‘,22,‘羽‘,80),                  (‘u004‘,‘刘‘,25,‘备‘,98),                  (‘u006‘,‘黄‘,18,‘盖‘,NULL),                  (‘u005‘,‘王‘,12,‘子云‘,20),                  (‘u007‘,‘诸葛‘,24,‘亮‘,100);
3.6.2没有条件查询      查询所有             mysql> select * from t_user;      查询部分信息           select secondname,age from t_user;           select id, firstname, age, secondname, counts from t_user; #等价于查询所有,推荐写法      查询用户编号、姓名,及格           select id,concat(firstname,secondname),counts-60 from t_user;   ?修改上面查询显示字段名称,用"姓名"表示姓名,用"及格"表示及格      #字段的别名格式:字段名 [as] 别名 select id,concat(firstname,secondname) as 姓名,counts-60 及格 from t_user; select id,concat(firstname,secondname) as ‘姓   名‘,counts-60 及格 from t_user; #引号可以使用 select id,concat(firstname,secondname) as `姓   名`,counts-60 及格 from t_user; #
3.6.3带有条件查询 查询分数等于60的学生      select * from t_user where counts=60; #如果是数字,可以使用单引号,一般不用。 查询姓"张"学生      select * from t_user where firstname = ‘张‘;       #注意:如果是字符串必须使用引号,建议是单引号 查询年龄大于18的学生      select * from t_user where age > 18; 显示分数在60-80的学生      select * from t_user where counts >=60 and counts <=80;      select * from t_user where counts between 60 and 80; 查询编号为u001和u002的学生      select * from t_user where id = ‘u001‘ or id = ‘u002‘;      select * from t_user where id in (‘u001‘, ‘u002‘); 查询年龄是18或20的学生      select * from t_user where age = 18 or age = 20;      select * from t_user where age in (18, 20); 查询名中含有"云"的学生      ### like语句,模糊查询,不完全匹配查询      ### 格式:字段 like 值      ## 特殊符号:% _      % 匹配若干      ‘%云‘,必须以“云”结尾      ‘云%‘,必须以“云”开头      ‘%云%‘,含有“云”      _ 匹配一个字符        # 查询名中含有"云"的学生           select * from t_user where secondname like ‘%云%‘;      # 查询名中第二字还有"云"的学生           select * from t_user where secondname like ‘_云%‘;        查询分数小于60 或 大于90分的学生            //这种情况下属于两边,不能用between and, 而只能是or, 何况or和and功能强大得多.      select * from t_user where counts < 60 or counts > 90;        查询分数等于60 或者  分数大于90并且年龄大于23      select * from t_user where counts = 60 or counts > 90 and age > 23;            #优先级问题: and 优先 or      select * from t_user where counts = 60 or (counts > 90 and age > 23);        查询没有考试的学生           select * from t_user where counts is null;      查询所有考试的学生           select * from t_user where counts is not null;
3.6.4聚合函数(同查询结果进行相应统计,显示一行一列数据)      count(): 用于计数,查询共有有多少条记录           select count(*) from t_user;           select count(id) from t_user; #统计指定字段值           select count(counts) from t_user; #且不进行null计数           select count(1) from t_user;      平均成绩 avg()           select avg(counts) from t_user; #不计算null           select sum(counts)/count(*) from t_user;#计算null,指的是所有人的平均分,包含没               参加考试的.      最高成绩 max()           select max(counts) from t_user;      最小年龄 min()           select min(age) from t_user;      班级总成绩 sum()           select sum(counts) from t_user;      查询所有的年龄数           select age from t_user;      ### 去重复           select distinct age from t_user;
3.6.5排序 格式:select.... order by 排序字段名1 asc|desc, 字段2 asc|desc, ....;      asc:表示升序,默认值,可以不写      desc:表示降序 select age,money from person order by money desc,age asc;      *指先使用money进行降序的排列,如果数据重复,在按照age排序           10  18           10  20           10  23           9   20
3.6.6分组 #1添加班级字段(classes)      alter table t_user add column classes varchar(3);      update t_user set classes = ‘1‘ where id in (‘u001‘,‘u002‘,‘u003‘,‘u004‘);      update t_user set classes = ‘2‘ where id in (‘u005‘,‘u006‘,‘u007‘); #2查询1班和2班的平均成绩      #2.1 查询所有平均成绩           select sum(counts)/count(*) from t_user;      #2.2 使用班级进行分组           ### 分组格式:select .... group by 分组字段 having 分组条件;           select classes,sum(counts)/count(*) from t_user group by classes;           注意:如果使用分组,select查询字段处,只能使用“聚合函数”或“分组字段”           select id,classes,sum(counts)/count(*) from t_user group by classes; #此处id没有意义      #3查询班级平均成绩不及格的班级成员信息           3.1 查询班级平均成绩不及格(包含没参加考试的)                select classes as 班级, sum(counts)/count(*) as 平均分 from t_user group by 班级 having 平均分<60;           3.2 2班的班级成员信息                select * from t_user where classes = ‘2‘;
3.3 整合      新建表二:           create table t_user2(                name varchar(20) not null,                classes varchar(16) not null           );      再insert to数据           insert into t_user2 (name, classes) values                 (‘作者‘, ‘1‘),                (‘小明‘, ‘2‘); 最终得到      gxlsystem.com,布布扣      gxlsystem.com,布布扣           ### 多表操作 , 表名 [as] 别名           select * from A,B where A.classes = B.classes;      ### 表的别名           select a.* from A as a,B as b where a.classes = b.classes;
例如      select * from t_user as A , t_user2 as B where A.classes=B.classes;      select A.* from t_user as A , t_user2 as B where A.classes=B.classes;      //应该是笛卡尔(直积)全部串起来 ,然后再select 元素的排列.          列举出那些班级平均分<60的所有学生      思路:将列表一 和 结果select修饰过后的表二拼起来即可.      法一:           select A.* from t_user as A, (select classes, sum(counts)/count(*) as avgcount         from t_user           group by classes                 having avgcount < 60) as B   where A.classes = B.classes;      法二: 暂时没想到.不写了
4 cmd中文乱码处理      gxlsystem.com,布布扣        1,2,4 client/connection/results 此三项必须保持一致,且与事实符合           client:在服务器端设置的客户端的编码           connection:在服务器端设置的客户端与服务器的连接编码           results:在服务器端设置的服务器响应给客户端数据的编码        mysql 服务器端环境变量:character_set_database,设置数据库的编码,如果不出现乱码,设置的字符集支持中文即可,GBK或UTF-8或GB2312等        修改服务器端设置: mysql> set names GBK:
5数据库备份与还原 备份      格式:mysqldump -u账号 -p密码 数据库名称 > 位置      cmd#  mysqldump -uroot -p1234 day14 > d:/day14.sql   还原      格式: mysql -u账号 -p密码 数据库名称 < 位置      cmd#  mysql -uroot -p1234 day14_bak < d:/day14.sql      注意:必须手动先创建数据库
6修改root账号的密码      手动启动mysql服务器,且进行无权限验证方式的启动           cmd> mysqld --console --skip-grant-tables      使用root账号登陆,不需要密码           cmd> mysql -uroot      修改账号的密码,mysql数据库,user表中      gxlsystem.com,布布扣      update user set password = password(‘1234‘) where host = ‘%‘;         #需要使用 password() 函数对密码进行加密   删除用户      语法: DROP USER ‘账号’@’host’      例如: mysql> drop user ‘root‘@‘%‘;   密码不正确 gxlsystem.com,布布扣
7约束      7.1主键约束: 被约束的字段的内容,非空不重复      关键字:primary key           一个表中只能由一个主键           但一个主键不表示只是一个字段,可以是联合主键      使用           方式1 : 声明字段时,同时声明主键           方式2 : 声明字段之后,在约束区域声明主键                constraint primary key (id)                方式2 可以声明 联合主键:多个字段组合在一起,是一个主键,内容合并在一起不重复。  gxlsystem.com,布布扣           方式3 : 在创建表之后,修改表结构,声明主键                alter table pk03 add [constraint] primary key (id);
7.2唯一约束(被约束的字段的内容,不能重复)            方式1 : 声明字段时,同时声明unique约束.            方式2 : 声明字段之后,在约束区域声明主键                constraint unique (id)               方式3 : 在创建表之后,修改表结构,声明主键                alter table pk03 add [constraint] unique (id);
7.3非空约束(被约束的字段的内容,不能为null)      关键字:not null      使用:在声明字段时,声明非空
7.4 Mysql特有字段:自动增长列      关键字:auto_increment      自动增长列:被约束字段的内容,可以自动累加, 所以录入数据时,可以不操作自动增长列        删除           delete from ai01;   #清空表中的数据,但不重置“自动增长列”的累加数           truncate table ai01;#清空表中的数据,但重置“自动增长列”的累加数 (先删除表,再创建表)
7.5 外键约束 关键字:foreign key      外键:           1 在从表添加一个字段           2 类型:必须与主表主键的一致           名称:自定义,建议:user_id  或 uid           内容:从表外键的内容,必须是主表主键的引用      特点:           从表的外键不能添加(更新),主表主键不存在的内容           主表的主键不能删除(更新),从表外键已经引用的内容      //可以拿学籍注册举例
8.1一对多 实例:      国家(1) -- (*)城市      教室(1) -- (*)学生      用户(1) -- (*)书籍  需要使用主外键关系描述:一对多      #添加的格式:alter table 从表表名 add constraint [外键名称] foreign key (从表外键) references 主表表名 (主表主键);      #删除的格式:alter table 表名 drop foreign key 外键名称;           //所以最好以后每个key都要自己起名字.
通过案例学习 # 主表:user表 create table t_user(       id varchar(32),       username varchar(50),       password varchar(32)  #MD5加密 ); ### 主表的主键 alter table t_user add constraint primary key (id);     # 从表:book表 create table t_book(       id varchar(32),       title varchar(50),       author varchar(50),       user_id varchar(32)  #外键,类型t_user.id一致 ); #添加外键 alter table t_book add constraint foreign key (user_id) references t_user (id);   #插入数据 insert into t_user(id,username,password) values(‘u001‘,‘jack‘,‘1234‘); insert into t_user(id,username,password) values(‘u002‘,‘rose‘,‘1234‘); insert into t_user(id,username,password) values(‘u003‘,‘tom‘,‘1234‘);   insert into t_book(id,title,author,user_id) values(‘b001‘,‘javaweb‘,‘任童‘,‘u001‘);      #成功,外键是主键引用 insert into t_book(id,title,author) values(‘b002‘,‘javaweb2‘,‘任童2‘);      #成功,user_id = null,外键可以为null,而且我发现可以插入多个null. 这不太好吧. insert into t_book(id,title,author,user_id) values(‘b003‘,‘android‘,‘小华华‘,‘u001‘); insert into t_book(id,title,author,user_id) values(‘b004‘,‘菊花是怎么成长的‘,‘强哥‘,‘u002‘);     gxlsystem.com,布布扣gxlsystem.com,布布扣   #1 笛卡尔积,两个表的乘积集合 select * from t_user,t_book; select count(*) from t_user,t_book;  #12条  #2 隐式内连接  ## 例如:查询某人借某了某书      select * from t_user,t_book where t_user.id = t_book.user_id;      select t_user.username,t_book.title from t_user,t_book where t_user.id = t_book.user_id; #可以起表的别名哦. 下面这句话用隐式内连接实现(借阅人和借阅数据的列表)      select U.username, B.title from t_user as U , t_book as B      where U.id = B.user_id; #3 内连接  ## 格式:select ... from A  inner join B on 条件      select U.username, B.title from t_user as U      inner join t_book as B       on U.id = B.user_id; gxlsystem.com,布布扣和隐式内连接一样 #4 外连接 # 左外连接:查询A表的所有内容,B表的内容是否显示,取决条件是否成立,成立显示,不成立显示null      ### 格式:select ... from A left outer join B on 条件      ### 例如:统计用户借阅书籍情况           select * from t_user u             left outer join t_book b on u.id = b.user_id; gxlsystem.com,布布扣   # 右外连接:查询B表的所有内容,A表的内容是否显示,取决条件是否成立,成立显示,不成立显示null      ### 格式:select ... from A right outer join B on 条件      ### 例如:统计书籍被解决情况           select * from t_user u                right outer join t_book b on u.id = b.user_id; gxlsystem.com,布布扣
8.2多对多      实例:           教师(*) -- (*)学生           人(*) -- (*)角色           角色(*) -- (*)权限           学生(*) -- (*)课程【】 ##多对多 (many) ## 主表:学生表 create table m_student(   id varchar(32) primary key,  #主键   `name` varchar(50),   age int ); ## 主表:课程表 create table m_course(   id varchar(32) primary key, #主键   content varchar(50),   teacher varchar(50) ); ## 从表:中间表,学生课程表 create table m_student_course(   student_id varchar(32), #学生表对应外键   course_id varchar(32)   #课程表对应外键 ); ##### 关系 ### 中间表与学生表 :主外键关系 alter table m_student_course add constraint foreign key (student_id) references m_student (id); ### 中间表与课程表 :主外键关系 alter table m_student_course add constraint foreign key (course_id) references m_course (id); ### 联合主键 alter table m_student_course add constraint primary key (student_id,course_id);     ### 外键删除 alter table 表名 drop foreign key 外键名称;   ### 测试:   insert into m_student(id,name,age) values(‘s001‘,‘jack‘,18);  #成功 insert into m_course(id,content,teacher) values(‘c001‘,‘java基础‘,‘自摸‘); #成功 insert into m_student_course(student_id,course_id) values(‘s001‘,‘c001‘);#成功,多对多关系通过中间数据维护     insert into m_student(id,name,age) values(‘s002‘,‘rose‘,21); insert into m_course(id,content,teacher) values(‘c002‘,‘java web‘,‘梁少‘); insert into m_course(id,content,teacher) values(‘c003‘,‘android‘,‘侃哥‘); insert into m_student_course(student_id,course_id) values(‘s001‘,‘c002‘); insert into m_student_course(student_id,course_id) values(‘s001‘,‘c003‘); insert into m_student_course(student_id,course_id) values(‘s002‘,‘c002‘); insert into m_student_course(student_id,course_id) values(‘s002‘,‘c003‘);   ### 查询:某人学某课 ##隐式内用多对多看来是高级连接操作吧 select s.name , c.content from m_student s , m_student_course sc , m_course c   where s.id = sc.student_id and sc.course_id = c.id; ##内连接,三个的内连接也是高级的内连接吧 select s.name ,c.content from m_student s   inner join m_student_course sc on s.id = sc.student_id   inner join m_course c on sc.course_id = c.id; 8.3一对一 (不讲)
SQL注入 select * from t_user where username = ‘jack‘ or 1=1 or 1=‘‘ and password = ‘12345678‘   select * from t_user where username = ‘\‘‘ and password = ‘‘   # 手动防止sql注入,将所有的单引号替换成  "\‘"

2预处理对象      2.1介绍      接口:javax.sql.PreparedStatement 预处理对象,预先处理sql语句,使用户的输入的内容,只是执行的参数,而不是sql语句语法的一部分。        2.2编写流程           1 提供一个已经处理过的sql语句,让预处理对象进行编译。 -- 将实际参数使用?替换                String sql = "select * from t_user where username = ? and password= ? ";           2 使用已经处理过的sql,获得预处理对象                PreparedStatement psmt = conn.prepareStatement(sql);        //此处提供sql语句           3 设置实际参数                psmt.setXxx(1,"jack");   //给第一个?设置实际参数                psmt.setString(2,"1234"); //给第二个?设置实际参数           4 执行sql语句                int r = psmt.executeUpdate(); //注意:此处不提供sql语句                ResultSet rs = psmt.exeucteQuery();      2.3应用场景           ①防sql注入:               sql注入:用户输入的内容,是sql语句语法的一部分           ②大数据:blob字节大对象、clob 字符大对象           数据库可以保存:图片、视频、小说等                注意:图片、视频等不会保存数据库,如果需要图片,则完成文件上传,将图片等保存服务器端,将服务器端保存的路径,保存数据库中。           ③批处理 : 批量的处理sql语句                Statement 批处理 : 一次性可以执行多条sql语句,需要编译多次。                * 应用场景:系统初始化 (创建表,创建数据等)                * api                     添加sql语句,st.addBatch(sql)   --添加sql语句                     批量处理sql语句,int[]  st.executeBatch()                     清除缓存: st.clearBatch();                  PreparedStatement 批处理 : 执行一条sql语句,编译一次,执行sql语句的参数不同。                     * 应用场景:表数据初始化                     * api                添加批量参数:psmt.addBatch()    --添加实际参数,执行之前,需要执行psmt.setXxx()设置实际参数                执行批处理:int[] psmt.executeBatch()                清除缓存:pstm.clearBatch();
3事务 transaction 3.1介绍      事务:业务中存在一组操作,要么全部成功,要么全部不成功。      例如:转账   3.2事务特性 ACID      原子性:一个事务不可分割。【整体】      一致性:事务的前后数据一致。【数据】      隔离性:多个事务并发性。【并发】      持久性:事务操作之后不可改变状态。【不可变】--如果事务提交了,将不可改变。   3.3mysql事务的操作      开启事务:start transaction      提交事务:commit      回滚事务:rollback   3.4数据的隔离问题      脏读:一个事务读到另一个事务没有提交的数据。      不可重复读:一个事务读到另一个事务提交的数据。(update 更新)      幻读(虚读):一个事务读到另一个事务提交的数据。(insert 录入)   3.5数据隔离级别      数据的隔离级别,解决不用隔离问题。提供4种隔离级别      read uncommitted ,读未提交:一个事务读到另一个事务没有提交的数据。存在问题:3个      read committed ,读已提交:一个事务读到另一个事务调剂的数据。存在问题2个:不可重复读、幻读。解决问题:脏读      repeatable read,可重复读:一个事务中读到数据重复的。存在问题1个:幻读。解决问题:脏读、不可重复读      serializable ,串行化:单事务。没有问题,解决问题:脏读、不可重复读、幻读。        对比: * 性能:read uncommitted > read committed > repeatable read > serializable * 安全:read uncommitted < read committed < repeatable read < serializable      mysql 默认隔离级别:repeatable read      Oracle默认隔离级别:read committed   Connection提供常量:      TRANSACTION_READ_COMMITTED,指示不可以发生脏读的常量;不可重复读和虚读可以发生。       TRANSACTION_READ_UNCOMMITTED ,指示可以发生脏读 (dirty read)、不可重复读和虚读 (phantom read) 的常量。       TRANSACTION_REPEATABLE_READ ,指示不可以发生脏读和不可重复读的常量;虚读可以发生。       TRANSACTION_SERIALIZABLE,指示不可以发生脏读、不可重复读和虚读的常量。
3.6隔离级别演示 3.6.1准备工作      查询数据库隔离级别:mysql>  show variables like ‘%iso%‘;           gxlsystem.com,布布扣           mysql 系统环境变量查询:mysql> select @@tx_isolation;      设置数据库的隔离级别:           mysql>  set session transaction isolation level 隔离级别   3.6.2读未提交      A 隔离级别:读未提交 read uncommitted      AB开始事务      A查询      B更新      A再查询 -- 查询到,A读到B没有提交的数据      B 回滚      A再查询 -- B更新之前的数据。   3.6.3读已提交      A 隔离级别:读已提交 read committed      AB开启事务      A查询      B更新      A再查询 -- 没有查询到,解决:脏读      B提交      A再查询 -- 查询到,存在问题:不可重复读   3.6.4可重复读      A隔离级别:可重复读 repeatable read      AB开启事务      A查询      B更新      A再查询 -- 没有查询到,解决:脏读      B提交      A再查询 -- 没有查询到,解决:不可重复读      A提交或回滚      A 再查询 -- 查询到,新事物   3.6.5串行化      A隔离级别:串行化 serializable      AB开启事务      A查询      B更新 -- 等待 (A提交或回滚B继续操作;B等待超时)   3.7lost update 丢失更新      丢失更新:两个事务同时操作,A事务更新的数据,被B事务更新的数据覆盖了,导致A事务更新的数据丢失      解决 * 乐观锁:丢失更新肯定不会发生。提供版本字段,进行数据的有效操作。 * 悲观锁:丢失更新肯定会发生。采用mysql数据库的锁机制 * 读锁:共享锁,一个表可以存在多个读锁 mysql> select .... lock in share mode; * 写锁:排他锁,一个表只能由一个写锁。(独占) mysql> select .... for update; 注意:mysql的锁必须在事务中 所有的update语句都使用写锁
4事务案例      4.1JDBC事务           一个连接Connection 就表示一个事务           api                conn.setAutoCommit(false);  //开启事务  -- 将自动提交关闭了                conn.commit();            //提交事务                conn.rollback();            //回滚事务        mysql事务默认情况自动提交
4.2JDBC事务管理--service层() 4.2.1模板1:(必须学会)      Connection conn = null;           try{             //0 获得连接             conn = ....;             //1 开启事务             conn.setAutoCommit(false);              A步骤             B步骤             C步骤             D步骤             //2 在不报错的情况下, 提交事务             conn.commit();           } catch(e){             //3 回滚事务                  conn.rollback();            } finally{                  //释放资源                  conn.close();      }
4.2.2模板2: # AB是必选项(A和B是一个整体),CD可选项(C和D一个整体)。 #需要通过Savepoint 保存点进行部分内容管理      Connection conn = null;      Savepoint savepoint = null;      try{        //0 获得连接        conn = ....;        //1 开启事务        conn.setAutoCommit(false);         A步骤        B步骤        // 设置一个保持点        savepoint = conn.setSavepoint();        C步骤        D步骤        //2 提交事务        conn.commit();      } catch(e){         if(savepoint == null){                 //AB 其中之一存在异常,回滚AB选项                 conn.rollback();         } else {                 //CD存在异常                 // * 将CD进行回滚                 conn.rollback(savepoint);  //回滚到保存点之前,也就是AB之后                 // * 提交AB            conn.commit();         }      } finally{        //释放资源
  conn.close();
     }
4.3案例:转账 transfer,详见案例1,2.
5连接池      java.lang中类 ThreadLocal<T>, 详见案例3.

热门排行

今日推荐

热门手游