大良网站智能推广如何WordPress怎么加入用户关注
news/
2025/9/23 5:54:22/
文章来源:
大良网站智能推广如何,WordPress怎么加入用户关注,洛阳网络科技有限公司,站长之家域名查询鹿少女目录 MySQL安装: 1. 数据库基本操作1.1 创建数据库1.2 显示当前数据库1.3 删除数据库1.4 使用数据库/选中数据库 2. SQL中的数据类型2.1 数值类型2.2 字符串类型2.3 时间类型 3. 表的操作3.2 创建表3.1 显示数据库中的表3.3 查看表的详细情况3.4 删除表3.5 注释3. 修改列(了解即… 目录 MySQL安装: 1. 数据库基本操作1.1 创建数据库1.2 显示当前数据库1.3 删除数据库1.4 使用数据库/选中数据库 2. SQL中的数据类型2.1 数值类型2.2 字符串类型2.3 时间类型 3. 表的操作3.2 创建表3.1 显示数据库中的表3.3 查看表的详细情况3.4 删除表3.5 注释3. 修改列(了解即可) 4. 表的增删查改4.1 插入(insert)4.2 查询(select)全列查询查询指定列查询时指定表达式查询时给列取别名去重查询排序查询条件查询字符匹配null的比较分页查询聚合查询聚合函数group by 分组查询having 联合查询内连接外连接自连接子查询合并查询 4.3 修改(update)4.4 删除(delete) 5. 约束5.1 not null5.2 unique5.3 default5.4 primary key5.5 foreign key 6. 表的设计7. 索引查看索引创建索引删除索引索引背后的秘密 - B树关于索引的总结找工作面试常问 8. 事务事务的特性(面试常问) 9. MySQL与JDBC10. 完结撒花 家人们删库是危险操作慎用! 前言 今天开始正式进入MySQL的学习希望这篇文章能够帮助到大家
MySQL安装:
下载链接 下载链接
打开链接之后直接点击No thanks, just start my download. 即可下载 如果该版本不是你想要的也可以选择去Oracle官网或者MySQL官网下载其他版本
安装步骤就是一路next这里不多介绍需要注意的是学习过程中MySQL设置的密码尽量简单一点容易记住
关于MySQL需要知道的 MySQL是 “客户端-服务器” 结构的程序 1个MySQL服务器上可以包含多个数据库 1个数据库利用包含多个数据表 1个数据表可以包含多个数据行 1个数据行可以包含多个数据列一个数据行也可以叫一条记录
如图
1. 数据库基本操作
1.1 创建数据库
创建数据库如果数据库名字存在会报错
create database 数据库名;如果不存在该名称的数据库就创建数据库如果存在就什么的不做也不会报错但是有警告
create database if not exists 数据库名;显示警告
show warnings;设置字符编码
MySQL里面的utf8是阉割版的utf8在MySQL中真正的utf8是utfmb4
create database if not exists 数据库名 charset utf8mb4;1.2 显示当前数据库
语法
show databases;例如 以上这四个数据库是系统自带的安装好就有的数据库
1.3 删除数据库
删库非常危险慎重使用
drop database 数据库名;也可以添加条件
drop database if not exists 数据库名;1.4 使用数据库/选中数据库
use 数据库名;2. SQL中的数据类型
2.1 数值类型
数据类型大小说明对应Java中的类型bit(M)默认为1,M表示位数表示二进制数,M取1~64tinyint1字节Bytesmallint2字节Shortint4字节Integerbigint8字节Longfloat(M,D)4字节单精度浮点数M表示总长度,D表示小数点位,不能精确表示小数Floatdouble(M,D)8字节双精度浮点数M表示总长度,D表示小数点位,不能精确表示小数Doubledecimal(M,D)M/D最大值2M表示总长度,D表示小数点位,能精确表示小数BigDecimalnumeric(M,D)M/D最大值2M表示总长度,D表示小数点位,能精确表示小数BigDecimal
以上类型都是有符号类型(能够表示负数)常用的有int、bigint、double、decimal
2.2 字符串类型
数据类型大小说明对应Java类型varchar(size)0~65535字节可变长度字符串,size表示字符个数Stringchar(size)0~65535字节定长字符串,size表示字符个数Stringtext0~65535字节长文本数据(可变长,无需指定最大长度,是自适应的)Stringmediumtext0~16777215字节中等长度文本数据Stringblob0~65535字节二进制数据byte[]
可变长:根据存储的数据自动调整存储空间例如char(10)与varchar(10),能保存的最大长度是10个字符,如果只存储了5个字符,char申请的存储空间是10个字符,可变长的varchar申请的存储空间是5个字符。
常用的有varchar
2.3 时间类型
数据类型大小说明对应Java类型datetime8字节能表示范围1000年到9999年java.util.Date、java.sql.Timestamptimestamp4字节能表示范围1970年到2038年java.util.Date、java.sql.Timestamp
timestamp(时间戳):当前时间与1970年1月1日0时0分0秒的时间之差(单位可以是秒/毫秒/微秒…)只能表示到2038年不适用
常用的有datetime
总结 上述类型并不是数据库全部的类型不同的数据库支持的类型也有差别掌握以下类型int、bigint、double、decimal、varchar、datetime
3. 表的操作
大前提先选中某个数据库
3.2 创建表
语法
create table 表名(列名 类型,列名 类型.....);例如 create table test(id int,name varchar(20));在命令行中执行SQL语句执行成功会提示Query OK
3.1 显示数据库中的表
show tables;此时会展示已经创建好的表
3.3 查看表的详细情况
desc 表名;例如
desc是describe的缩写,desc只能查看表的结构(有哪些列,每个列的情况),不能查看表中具体的内容
Field 字段列的名字
Type 列的类型int(11)11表示位宽最多只显示11个字符长度
NULL 列是否允许为空yes表示允许
key 主键/外键本文后面会介绍到
Default 默认值可以手动指定
Extra 补充信息
3.4 删除表
drop table 表名;整个表的内容都会删除,包括数据
慎重使用
3.5 注释
使用comment、–、#
如
comment comment比较特殊用法如下(创建表的时候使用)
3. 修改列(了解即可)
关键字alter 添加列 alter table 表名 add 新增的列名 类型;修改列的类型 alter table 表名 modify 要修改的列名 类型;删除列 alter table 表名 drop 要删除的列名;修改表名 alter table 要修改的表名 rename to 新表名;添加主键 alter table 表名 add primary key(列名);删除主键 alter table 表名 drop primary key;添加外键 alter table 表名 add constraint 添加的外键约束名 foreign key (设为外键的列名) references 参考的表名;删除外键 alter table 表名 drop foreign key 外键约束名;4. 表的增删查改
4.1 插入(insert)
基本语法
insert into 表名 values(值,值,值...);插入的数据类型要和表对应列类型匹配
插入数据需要和列的个数、数据类型、顺序匹配
如果要插入的数据包含中文,必须保证创建数据库时指定的字符集为utf8/gbk
例子 我们先准备好一个学生表表的结构如下
基本插入方法
insert into student values(1,张三);类型转换 例如
insert into student values(111,222);上图代码中,虽然插入第一列的是字符串类型,但是系统会尝试自动转成int;第二列插入的是整数类型,系统会尝试转成字符串。
指定某些列名进行插入
insert into 表名(列名,列名...) values(值,值...);为指定的列的值:如果允许为空值则为空值如果不允许为空值则为默认值如果没有指定默认值插入失败
insert into student(id) values(2);插入多行
insert into 表名 values(值,值...),(值,值...),(值,值...);如
insert into student values(1,张三),(2,李四),(3,王五);插入时间类型
遵循格式
年-月-日空格时:分:秒
insert into test values(2024-05-11 15:10:30);获取系统当前时间,使用函数now(),如
insert into test values(now());插入和查询结合
也就是将查询的结果插入表中可以指定列
insert into 表名 select语句;要求select得到的结果集合要和insert into的表的列数、类型、顺序匹配
例如将student1中年龄小于20的记录插入到student2中
insert into student2 select * from student1 where age 20;4.2 查询(select)
关键字select
生成临时表不会改变原始数据
全列查询
select * from 表名;例如
select * 的操作慎用因为实际工作中如果表非常大数据非常多此时使用select 操作可能会将硬盘、网卡带宽吃满其他客户端访问数据库就无法正常进行
查询指定列
select 列名,列名... from 表名;查询时指定表达式
select 表达式 from 表名;遍历每一行,取出想要的列代入表达式,结果为临时表,不会改变原来的数据
例
有表grades如下 查询每个同学的英语成绩和数学成绩的总和语句如下
select mathenglish from grades;查询结果 查询时给列取别名
如果表达式比较复杂无法直接观察此时可以取别名
select 列名 as 别名 from 表名;as 可以省略不建议省略容易看混
例如
去重查询
多个行的数据如果出现相同的值,就只保留一份(针对也是临时表)
select distinct 列名 from 表名;例如
如果要查询多列,多列都重复才能触发去重效果
例如: 查询的是math和name,虽然math重复了,但是name没有重复,没有触发去重效果
排序查询
针对查询结果进行顺序/降序排列,使用order by
select 列名 from 表名 order by 想要进行排序的列名 desc;-- 降序
select 列名 from 表名 order by 想要进行排序的列名 asc;-- order by默认的就是升序,asc 可以省略desc,asc分别是descend、ascend的缩写
例按数学成绩降序 按数学成绩升序(asc可以省略不写)
另外,可以指定多个列,先按第一列排序,第一列相同则按照第二列排序以此类推
例如按照数学成绩排序如果数学成绩一样则按照英语成绩排序 条件查询
查询过程可以指定筛选条件,查询结果会保留满足条件的记录
select 列名 from 表名 where 条件;条件指的是条件表达式
比较运算符
比较运算符说明、、、大于、大于等于、小于、小于等于等于null不安全nullnull的结果为null等于null安全nullnull结果是 true!、不等于between a and b表示连续的范围[a,b)in(a1,a2,…)表示非连续的范围(离散的)is null是nullis not null不是nulllike字符匹配
逻辑运算符
逻辑运算符说明and多个条件都为真结果才是真or任意一个条件为真结果就为真
and 优先级高于or
执行顺序问题(大部分解释是这样,但是并不靠谱) 遍历表取出每一行 把当前行代入到where条件根据条件真假决定这一行是否需要查询出来 再根据select后面写的列名/表达式来进行筛选列/进行计算/别名 如果有order by则进行排序
字符匹配
like、not like
%表示任意长度
_代表任意一个字符
例如
查询学生表(student)中以李开头的学生的所有内容
select * from student where name like 李%;查询课程表(course)中,以’结构’结尾的课程名
select cname from course where cname like %结构;%表示可以是任意长度的字符串
查询学生表中姓名倒数第二个字为’德’的学生的所有内容
select * from student where name like %德_;null的比较
is null、is not null、
看例子 原始数据如下 nullnull和nullnull的区别 分页查询
限制一次查询最多能查多少个记录
select 列名 from 表名 limit n;从下标m开始查n条记录原来的表中的第一条记录的下标是0
select 列名 from 表名 limit m offset n;select 列名 from 表名 limit m,n;聚合查询
聚合是针对行和行之间的操作需要搭配聚合函数
聚合函数
函数说明count([distinct] 表达式)返回查询结果的数量行数sum([distinct] 表达式)返回查询结果的总和avg([distinct] 表达式)返回查询结果的平均值max([distinct] 表达式)返回查询结果的最大值min([distinct] 表达式)返回查询结果的最小值
distinct是可选项表示去重前面介绍过
count
select count(*) from 表名;
-- 表示查询这张表有多少个记录(多少行),如果某个记录存在空值null,查询结果也会包含这列select count(列名) from 表名;
-- 查询这一列的记录个数(多少行),如果这列存在空值null,查询结果不会包含空值(重名也计算)sum 针对指定列进行求和
select sum(列名/表达式) from 表名;sum操作的这一列的类型必须是数字类型遇到空值null直接跳过不参与运算 3. avg 针对指定列进行求和
select avg(列名/表达式) from 表名;avg操作的这一列的类型必须是数字类型遇到空值null直接跳过不参与运算
max 针对指定列进行求最大值
select max(列名/表达式) from 表名;max操作的这一列的类型必须是数字类型遇到空值null直接跳过不参与运算 5. min 针对指定列进行求最小值
select min(列名/表达式) from 表名;min操作的这一列的类型必须是数字类型遇到空值null直接跳过不参与运算
group by 分组查询
使用group by时指定一个列把列的值相同的行归到一组中 语法如下
select 列名 from 表名 ... group by 想要分组的列名;例 有员工薪资表如下
使用group by分组
将role值相同的归为一组进行group by分组时select后面的列名一般写group by分组的列或者搭配聚合函数的列
例如 统计每个部门(role)的平均薪资
统计每个部门的人数
与order by搭配使用
having
当需要指定分组的条件时可以使用having不能使用where
例统计薪资平均值以role分组但是除去老板 注意:having是分组的条件,而where是没有分组时的条件
联合查询
联合查询也就是多表查询查询设计多个表
笛卡尔积简单来说就是拿着第一个表的每一行依次和第二个表进行匹配
如 有学生表和班级表,以及这两个表的笛卡尔积 也就是将第一张表学生表中每一条记录依次和第二张表班级表依次进行排列组合多表查询就是基于笛卡尔积但是在笛卡尔积中有一些记录是不合理的例如上述的张三的班级编号既有1又有2但真实情况是张三的班级编号是2如果两个表不存在某个列具有对应关系对应关系如上述的班级编号则这两个表进行笛卡尔积是无意义的。
在SQL语句中如何进行笛卡尔积
我们创建上述例子的两个表 笛卡尔积的SQL语句为
select * from 表1,表2;例如
内连接
语法:
select 列名 from 表1 [inner]join 表2 on 连接条件 and 其他条件;-- 表1join表2就相当于表1和表2进行笛卡尔积,inner表示内连接,可以省略
select 列名 from 表1,表2 where 连接条件 and 其他条件;-- 也就是把join换成逗号,把on换成where只包含两个表中同时具备的数据
外连接
不支持from多个表,只能使用joinMySQL中也不支持全外连接
左外连接,表1完全显示
select 字段名 from 表名1 left join 表名2 on 连接条件; -- 表1为基准右外连接,表2完全显示
select 字段 from 表名1 right join 表名2 on 连接条件; -- 表2为基准例如有两张表
左外连接左表为基准会确保左表中的每个记录都出现在如果左表中的记录在右边中没有对应的记录会把右表的字段填成null
右外连接和左外连接逻辑是一样的确保右表中所有的记录都出现在结果中如果右边中的记录在左边中没有对应的相关字段则填成null 外连接和内连接可以总结为下面这张图 自连接
自连接就是一张表自己和自己进行笛卡尔积自连接本质上是把行关系转换成列关系自连接的语法如下
select 列名 from 表1 as 别名1,表1 as 别名2;表1和表1是同一个表
例如
如果不取别名就会出现下面的报错
同样的自连接也需要指定连接条件否则会出现许多无效记录
总结如果发现查询的条件是针对两行而不是两列可以使用自连接但是如果表的数据量非常大要谨慎操作
子查询
子查询简单来说就是套娃嵌套次数过多容易脑瓜子嗡嗡,不推荐使用
例如查询和张三同班的同学
select * from student
where classid (select classid from student where name 张三);多行子查询,使用in
例如查询语文和英语的成绩信息
select * from score
where courseid in( select id from course where name 语文 or name 英语);合并查询
合并查询使用union关键字可以把多个select查询结果合并成一个
select 列名 from 表名 条件 union select 列名 from 表名 条件;可以把两个查询的结果合并在一起针对不同表查询也可以
如果不想去重可以使用union all
select 列名 from 表名 条件 union select 列名 from 表名 条件;要求合并的两个集合类型、个数、顺序、要匹配
4.3 修改(update)
update 表名 set 列名 值,列名 值 ...;后面可以加上条件where/limit/order by 例
4.4 删除(delete)
删除的是硬盘上的一条符合条件的记录,如果没有规定条件,则是删除所有的记录(不会删除表)
delete from 表名 条件;5. 约束
约束是数据库针对表中的数据,进行的一系列校验检查约束类型有not null、unique、default、primary key、foreign key等
5.1 not null
表示某列不能为空值语法
create table 表名 (属性)例创建表时指定某列的值不能为空
在插入/修改数据时插入/修改id属性就不能为空如果有空则插入/修改失败
5.2 unique
unique表示唯一某列的每行必须有唯一值在插入、修改时不能插入/修改成存在过的值 unique如何知道数据是否存在重复插入、修改之前会进行一次查询操作
例指定学生表的name为unique 插入一条姓名为张三的记录后又一次插入姓名为张三的记录此时插入失败
5.3 default
default表示默认指定某列的默认值插入一条记录如果不指定某行的值会设置为默认值例如
创建学生表时指定name的默认值为‘无名’
查看一下student的详细信息default为‘无名’如果创建表时不指定默认值则默认是null
此时插入数据如果不指定该列的值这列的值就会被设置为我们指定的默认值如
5.4 primary key
primary key表示主键主键是一行唯一标识一条数据的属性例如一个学校中学生的学号就可以设置为主键因为一个学校的学生学号不可能重复
primary key可以看成是not null和unique的结合主键的值不能为空也不能重复
例创建学生表将学号设为主键
查看表的详细信息PRI指的就是primary 表示该属性是主键
在进行插入/修改之前会进行一次查询查看是否存在重复的主键值如果存在插入失败/修改
如果主键的类型是整型可以搭配auto_increment使用表示自增主键此时插入记录可以不指定主键的值MySQL会自动分配主键值每次都会记录自增主键的最大值后续插入数据是按最大值进行分配同时也可以手动指定其他的值
创建学生表 如
此时表中数据为
5.5 foreign key
foreign key表示外键外键涉及两个表语法格式
create table 表名 (列名 类型,...... foreign key(列名) references 表名(列名));创建class表
创建student表student中外键为classid引用自class表
此时外键约束出现了如果要往student表中插入数据必须保证插入的数据的classid在class表中存在否则插入失败
父表制约的表class表子表被约束的表student表
如何知道classid存不存在插入时会触发对class表的查询数据库内部完成
如果父表的某个记录被子表引用了此时不能删除/修改父表中对应的记录了
删除表需确保先删除子表再删除父表否则出错
场景商品表goodsidgoodsnameprice订单表orderidgoodsid如果某个需要商品下架如何删除
逻辑删除额外添加一列表示标记
6. 表的设计
一对一关系如一个班级只能有一个班长一个班长也只能在一个班级中任职设计思路可以设计成一个表同时包含两个属性也可以弄两个表利用用主键来进行两个表的关联如班级班长表班级id班级名班长id或者 班级班长表班级id班级名班长id一对多关系如一个学生只能属于一个班级一个班级可以包含多个学生设计思路在“一”表中添加“多”表的主键如学生表学生id学生姓名班级id班级表班级id班级名称多对多关系一个学生能选择多门课程学习一门课程也能被多个学生选择设计思路创建一个新的关联表通过关联表把多对多的关系表示出来如学生表学生id学生姓名课程表课程id课程名创建一个关联表学生-课程表学生id课程id
7. 索引
索引相当于一个特殊的“目录”有了索引的存在能够加快查询速度尽可能避免对表数据的遍历。
引入索引的缺点 需要消耗额外的存储空间 引入索引虽然可以提高查询速度但是可能会影响增、删、改的效率增删改的时候需要同步更新维护索引
操作索引的SQL语句
查看索引
show index from 表名;如果建表时指定了主键会自动生成主键索引索引是按照列的方式创建的可以给某个列创建索引。如果以某个列创建索引当查询的时候以该列为条件时索引才能生效提高查询速度否则无法生效。
除了主键外unique、foreign key也会自带索引
创建索引
可以给非主键、外键、unique的列手动创建索引语法如下
create index 索引名 on 表名(列名);创建索引,也是危险操作~因为一旦数据量比较大就会触发大量的硬盘IO所以在最初建表时就提前规划好建立哪些索引
删除索引
语法
drop index 索引名 on 表名;只能删除自己手动创建的索引,自动生成的索引无法删除删除索引也是危险操作~~
索引背后的秘密 - B树
构建索引也就是引入一些数据结构对数据进行存储从而提高查找速度
数据库中索引保存的数据结构主要为B树为啥不用别的数据结构
顺序表、链表不适合查找栈、队列也不适合查找
二叉搜索树可以提高查找效率但是问题在于保存数据较多时树的高度就会变高比较的次数也就会变高会造成非常大的硬盘IO
哈希表只能进行相等的查询不能进行范围查询比如、、between and,也无法进行like这样的模糊查询
适合给数据库做索引的数据结构就是B树什么是B树
想要了解B树得先知道B树也可以写作B-树
B树: 平衡的nn2叉搜索树每个结点可以有多个子树这样树的高度就大大降低了如图
树的高度降低了每个结点的比较次数变多了比较逻辑和某个结点比较的时候先进行一次硬盘IO把所有的结点内容读取出来但是硬盘IO减少了
B树: 针对B树改进的数据结构 B树的优点
N叉搜索树高低低硬盘IO次数少叶子结点是数据的全集并且用链表结构连接方便范围查询B树所有的查询都要落到叶子结点上完成任何一次查询经历的IO次数和比较次数是差不多的查询开销稳定叶子结点是数据的全集所以非叶子结点不必存储数据行只需要存储索引列的key值即可使得非叶子结点消耗空间小这样甚至
关于索引的总结找工作面试常问
索引是什么?
索引相当于书的目录能够提高查询速度
索引付出了什么代价? 消耗了更多的存储空间 可能会影响增、删、改的效率可能提高也可能降低也可能没有影响
使用SQL语句操作索引 show index from 表名; – 查看表的索引(主键、外键、unique会自动生成索引) create index 索引名 on 表名(列名); – 给指定的列创建索引 drop index 索引名 on 表名; – 删除索引(只能删除自己手动创建的索引)
关于索引的注意事项
索引是针对列创建的后续查询时只有查询条件包含了这列索引才能提高效率针对数据量比较大的表最好不要在中途添加和删除索引因为这样可能会触发大量的硬盘IO可能把数据库搞崩溃
索引背后的数据结构是B树特点如下
N叉搜索树每个结点上包含n(n2)个key划分出n个区间每个父结点都会在下一层多存一份叶子结点这层包含了数据集合的全集叶子结点使用链表将所有的叶子结点连起来
使用B树的优点
n叉搜索树降低了树的高度减少了硬盘的IO次数进行范围查询时非常方便所有查询都落在叶子结点上开销稳定成本容易评估叶子结点存储数据行非叶子结点存储索引的key值非叶子结点占据空间小甚至可以加载到内存中进一步减少了IO的访问次数
8. 事务
事务是用来解决某些特定场景的问题的有些场景完成某个操作需要多个SQL语句配合完成~
想象一个场景
张三在玩王者农药想要充648点券买皮肤于是给马花藤的账户充了648
先创建表~~
create table account( id int primary key auto_increment,
name varchar(20) comment 账户名称,
money decimal(11,2) comment 金额);insert into account(name, money) values
(马花藤, 99999999),
(张三, 1000);充值逻辑
update account set money money-648 where name 张三;
update account set money money648 where name 马花藤;两个sql必须都执行完毕转账才能完成假设第一条update执行成功后突然出现网络问题主机断电了或者数据库崩了后面的语句无法执行导致张三的账户里减少了648而马花藤的账户金额没有增加。这种情况显然是不对的如何避免这种情况使用事务保证上面两条语句要么全部执行成功要么全部都执行失败
语法
start transaction; -- 开启事务
sql语句
rollback; -- 回滚,表示sql语句全部执行成失败start transaction;
sql语句
commit;-- 提交,表示sql语句全部执行成功事务的特性(面试常问)
所谓事务就是将多个需要执行的sql语句包装成一个整体要么这个整体都执行完要么都不执行不是真的不执行而是还原成出现问题之前的状态这样的机制也叫回滚rollback
1、原子性上述的包装成的整体也可以称为一个原子表示这个整体不能拆分了这样的特征叫原子性
2、一致性事务执行前和执行后数据库中的数据都是合法状态不会出现非法的临时结果状态比如转账不能出现A转账给BA的账户余额少了而B账户余额没有增加
3、持久性事务执行完毕后会修改硬盘上的数据事务都是持久生效的
4、隔离性隔离性描述的是多个事务并发执行时相互之间的影响是怎样的。什么是并发MySQL是客户端–服务器结构的程序一个服务器可能会给多个客户端同时提供服务。所以如果这些同时执行的事务恰好也是针对同一个表进行增删改查就会出现下面问题
脏读有两个事务A、B其中A在针对某个表中的数据进行修改A执行过程的同时B也去读取这个表中的数据B读取完之后A则把表中的数据改成别的了导致B读取到的不是最终的正确的数据而是临时性的脏数据旧的数据
解决办法约定好A在修改数据时B不能读取数据 -- 给写加锁
不可重复读有三个事务A、B、C首先事务A执行一个修改操作A执行完毕提交数据接下来事务B执行事务B读取A提交的数据B读取的过程中又来了一个事务CC对A修改过的数据再次修改对B来说后续再读取的数据和之前读取的数据不一样了这个过程就叫不可重复读一个事务多次读取的结果不一样叫不可重复读举个例子A同学写了代码将代码提交到github上了B同学想要学习一下A同学的代码于是在github上看A同学写的代码在B同学看的过程中A同学发现自己写的代码有问题就修改了一下重新提交此时B同学的视角为代码看着看着就变了
解决办法约定好一个事务在读取数据的时候其他事务不能修改正在读取的数据 -- 给读加锁
幻读事务A正在读取数据读的过程中另一个事务B新增/删除了一些其他数据不是A读取的数据对于A来说多次读取的数据输入内容是一样的但是结果集合不一样
解决办法约定只要有事务在读取数据其他事务就不要干任何操作 -- 串行化也就是说多个客户端同时提交多个事务给服务器服务器是一个一个执行事务而不是同时执行
隔离性描述的是针对上述问题如何解决的在mysql中提供了4个隔离级别可以通过设置配置文件来设置当前服务器的隔离级别
read uncommited 读取未提交一个事务可以读取另一个事务为提交的数据此时会产生脏读、不可重复读、幻读并发程度高速度快read commited 读已提交一个事务只能读取另一个事务提交之后的数据给写操作加锁了解决了脏读问题repeatable read 可重复读给写操作和读操作都加锁解决了脏读和不可重复读mysql默认的级别seriallizable可串行化所有事务在服务器上都是一个接一个执行的并发程度最低执行速度最慢隔离性最高数据最准确
9. MySQL与JDBC
实际工作中很少直接使用命令行/图形化界面 的客户端来操作数据库更多的是使用C、Java、Python等语言来操作数据库。数据库提供了API供我们使用代码来操作数据库。数据库有很多种Oracle、MySQL、SQL server这些数据库提供的API是不一样的于是Java自身制定了一套标准要求这些数据库都要把自己的API转换成和兼容Java的API而JDBC就是由Java制定的针对数据库操作的API。
MySQL本身的API是C语言的API把C语言的API转换成兼容JDBC的Java的API需要MySQL官方提供的mysql-connector如何下载mysql-connector
下载方法去Maven中央仓库Maven中央仓库
输入mysql点击Search
我们可以看到有两个选项第一个选项的版本比较新第二个选项是老的经典的版本
选择对应版本根据自己的mysql的版本来选择如果mysql是5系列的版本那么connector也必须是5系列的只要是5开头的就可以
我们随便选一个版本点击jar按钮即可下载
把下载好的connector导入到项目中才能编写我们的代码来进行数据库的操作 随便取个名字 将下载好的jar文件复制到刚才创建好的lib路径 直接选中lib然后Ctrlv粘贴,点击OK 复制好之后还有一步,右键刚才的lib,点击Add as Library(告诉lib是一个库目录) 点击OK 添加完成之后的效果是这样的 以上方法是简单粗暴的方法导入jar包,实际开发并不会这样操作如何操作后续再介绍~ 接下来,就可以开始写java代码了 JDBC使用步骤 准备工作(创建数据源对象描述了数据从哪里来数据库服务器所在位置) 方法1:利用了向上转型和向下转型 DataSource dataSource new MysqlDataSource();//MysqlDataSource是刚才导入的.jar包里面的
((MysqlDataSource)dataSource).setURL(jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncodingutf8useSSLfalse);//数据源,要访问的数据库在哪里
((MysqlDataSource)dataSource).setUser(root);//访问数据库的账户
((MysqlDataSource)dataSource).setPassword(1234);//访问数据库的密码,这里假设密码是1234上述字符串 jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncodingutf8useSSLfalse中,127.0.0.1是一个特殊的IP地址,表示本机的地址,因为我们用的MySQL服务器基本上都是在自己的电脑上,如果服务器在其他地方,填对应的IP地址即可,3306表示指的是端口号,用于区分一个主机上的应用程序 方法2: MysqlDataSource dataSource new MysqlDataSource();
dataSource.setURL(jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncodingutf8useSSLfalse);
dataSource1.setUser(root);
dataSource1.setPassword(1234);和数据库服务器建立网络连接 Connection connection dataSource.getConnection();构造SQL语句 String sql insert into student values(?,?);//变量sql表示要执行的sql语句,问号表示占位符
PreparedStatement statement connection.prepareStatement(sql);//处理结果 int n statement.executeUpdate();
//处理的是更新操作相关的语句(包括create,delete,update等除查询外的操作),返回值n表示几行受到了影响ResultSet resultSet statement.executeQuery();
//处理查询操作相关的SQL,返回值是ResultSet,可以理解为数据集合释放资源 statement.close();
connection.close();
resultSet.close();//如果处理了查询操作相关的SQL,需要加上这句,如果没有则不加例如: public static void main(String[] args) throws SQLException {Scanner scanner new Scanner(System.in);//1.创建数据源对象MysqlDataSource dataSource new MysqlDataSource();dataSource.setURL(jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncodingutf8useSSLfalse);//字符串的内容表示(jdbc:mysql://数据库服务器的IP地址/数据库名?characterEncodingutf8useSSLfalse);dataSource.setUser(root);dataSource.setPassword(111111);//2.和数据库建立网络连接Connection connection dataSource.getConnection();//3.构造SQL语句String sql insert into student values(?,?);//问号表示占位符,PreparedStatement statement connection.prepareStatement(sql);int id scanner.nextInt();String name scanner.next();//设置占位符的相关值也就是设置上述?号的值statement.setInt(1, id);statement.setString(2, name);// 4. 把 SQL 发送到服务器上进行执行int n statement.executeUpdate();System.out.println(n 行受到影响);//5.关闭资源statement.close();connection.close();}实用案例: 在jdbctest数据库中有学生表student,初始状态表中没有数据 使用代码,通过控制台输入数据,并插入到student表中 public static void main(String[] args) throws SQLException {// 1. 创建数据源MysqlDataSource dataSource new MysqlDataSource();dataSource.setUrl(jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncodingutf8useSSLfalse);dataSource.setUser(root);//账号dataSource.setPassword(111111);//密码// 2. 建立连接Connection connection dataSource.getConnection();// 3. 构建 sqlString sql insert into student values(?,?);PreparedStatement statement connection.prepareStatement(sql);//3.1 在控制台输入要插入的值Scanner scanner new Scanner(System.in);System.out.println(请输入学生id);int id scanner.nextInt();System.out.println(请输入学生姓名);String name scanner.next();statement.setInt(1, id);//1表示下标,从1开始!!,id表示列statement.setString(2, name);// 4. 执行 sqlint n statement.executeUpdate();// 5. 关闭对应的资源statement.close();connection.close();}运行程序,分别输入1,张三 再次查询学生表 可以看见学生表中多了一条记录, 另外还可以使用java代码进行查询语句的操作 如: 初始数据: 使用java代码查询 public static void main(String[] args) throws SQLException {// 1. 创建数据源MysqlDataSource dataSource new MysqlDataSource();dataSource.setUrl(jdbc:mysql://127.0.0.1:3306/jdbctest?characterEncodingutf8useSSLfalse);dataSource.setUser(root);//账号dataSource.setPassword(111111);//密码// 2. 建立连接Connection connection dataSource.getConnection();// 3. 构建 sqlString sql select * from student;PreparedStatement statement connection.prepareStatement(sql);// 4. 执行 sqlResultSet resultSet statement.executeQuery();//返回值是ResultSet,可以理解为数据集合// 5. 遍历结果集合while (resultSet.next()) {// 循环里针对一行进行处理System.out.println(resultSet.getInt(id) \t resultSet.getString(name));}// 6. 关闭对应的资源resultSet.close();statement.close();connection.close();}输出结果:
10. 完结撒花
关于MySQL的内容就介绍到这了以上内容能应付大部分的面试和笔试感谢大家支持~~
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/911524.shtml
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!