00 MySQL

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安装

其中MySQLInstanceConfig.exe可用于绿色版Mysql的设置.

mysql默认端口:3306

mysql将UTF-8编码称为:UTF8(只此一家)

mysql默认账号:root


2.3mysql启动和停止

手动方式(了解)

cmd>   mysqld --console

使用window服务

服务开发方式:运行 “services.msc”

启动

cmd> net start mysql

停止

cmd> net stop mysql

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数字

3.4.3日期

注:

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大数据

字节大数据: 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‘);

最终得到

### 多表操作 , 表名 [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中文乱码处理

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表中

update user set password = password(‘1234‘) where host = ‘%‘;

#需要使用 password() 函数对密码进行加密

删除用户

语法: DROP USER ‘账号’@’host’

例如: mysql> drop user ‘root‘@‘%‘;

密码不正确


7约束

7.1主键约束: 被约束的字段的内容,非空不重复

关键字:primary key

一个表中只能由一个主键

但一个主键不表示只是一个字段,可以是联合主键

使用

方式1 : 声明字段时,同时声明主键

方式2 : 声明字段之后,在约束区域声明主键

constraint primary key (id)

方式2 可以声明 联合主键:多个字段组合在一起,是一个主键,内容合并在一起不重复。

方式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‘);

#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;

和隐式内连接一样

#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;

# 右外连接:查询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;



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%‘;

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.

时间: 2024-12-30 10:35:10

00 MySQL的相关文章

00 MySQL必知必会涉及的数据库

建表语句: ######################################## # MySQL Crash Course # http://www.forta.com/books/0672327120/ # Example table creation scripts ######################################## ######################## # Create customers table #################

mongo/mysql , 字段添加&quot;-00&quot;

============================================================ Phil-PROD-20141212,字段添加"-00" ========= 现需要对线上垫付宝数据与轻易贷关联的数据有问题的数据进行修改(批量) mongodb bindingloan 需要对 loanAccountId后加 '-00' MySql 需要将 select LoanAccountId from KyPayAccounts LoanAccountId

mysql数据库安全设置

数据库作为数据管理的平台,它的安全性首先由系统的内部安全和网络安全两部分来决定.对于系统管理员来说,首先要保证系统本身的安全,在安装MySQL数据库时,需要对基础环境进行较好的配置. 1.修改root用户口令,删除空口令缺省安装的MySQL的root用户是空密码的,为了安全起见,必须修改为强密码,所谓的强密码,至少8位,由字母.数字和符号组成的不规律密码.使用 MySQL自带的命令mysaladmin修改root密码,同时也可以登陆数据库,修改数据库mysql下的user表的字段内容,修改方法如

mysql表名等大小写敏感问题、字段类型timestamp、批量修改表名、oracle查询历史操作记录等

mysql表名等大小写敏感问题:http://blog.csdn.net/postnull/article/details/72455768: 1 MySQL在Linux下数据库名.表名.列名.别名大小写规则是这样的: 2 1.数据库名与表名是严格区分大小写的: 3 2.表的别名是严格区分大小写的: 4 3.列名与列的别名在所有的情况下均是忽略大小写的: 5 4.字段内容默认情况下是大小写不敏感的. ================================================

MySql的复杂查询

案例一: 有表message和user. 表messagemessageid senderid recipientid content1 1 2 "xxx"2 2 3 "yyy"3 1 3 "123" 表useruserid username1 "Tom"2 "Jim"3 "Rose" 希望查询的结果如下:id sender recipient content1 "Tom&qu

Mysql高开用集群搭建

环境 rhel6.5x64 192.168.20.11   mysql11 192.168.29.12   mysql12 拓扑 环境 关闭iptables 关闭selinux yum -y install ncurses-devel gcc gcc-c++make autoconf automake zlib zlib-devel openssl openssl-devel pcre-devel 开始安装配置mysql11 [[email protected] ~]# tar -xf MySQ

Mysql 查看数据库大小

1 命令行进入数据库 [[email protected] ~]# mysql -uroot -p Enter password: 2 查看数据库 mysql> show databases; +--------------------+ | Database           | +--------------------+ | information_schema | | mysql              | | test               | +--------------

mysql 日期类型比较

MySQL 日期类型:日期格式.所占存储空间.日期范围 比较. 日期类型        存储空间       日期格式                 日期范围 ------------ ---------   --------------------- ----------------------------------------- datetime       8 bytes   YYYY-MM-DD HH:MM:SS   1000-01-01 00:00:00 ~ 9999-12-31

mysql命令

1 添加mysql\bin 到path 2 启动cmd 登陆 :mysql -hlocalhost -uroot -pxxxx 3退出 exit 在mysql>提示符下命令   show databases; 显示数据库 use  world; 打开world数据库 show tables; 显示表 create database 库名;建库 drop database 库名 ;删库 create table ...;建表 drop table 表名;删表 delete from 表名; 删除记