目录

  • 概述
  • 1、初识数据库
    • 1.1、DataBase
    • 1.2、数据库分类
    • 1.3、DBMS(数据库管理系统)
    • 1.4、命令行操作数据库
  • 2、操作数据库
    • 2.1、操作数据库
    • 2.2、数据库列类型
    • 2.3、数据库字段类型
    • 2.4、创建数据库表
    • 2.5、数据表的类型
    • 2.6、修改删除表
  • 3、MySQL数据管理
    • 3.1、外键
    • 3.2、DML语言
    • 3.3、添加
    • 3.4、修改
    • 3.5、删除
  • 4、DQL查询数据
    • 4.1、DQL
    • 4.2、查询
    • 4.3、where
    • 4.4、联表查询
    • 4.5、分页和排序
    • 4.6、子查询
    • 4.7、分组和过滤
  • 5、MySQL函数
    • 5.1、常用函数
    • 5.2、聚合函数
    • 5.3、数据库级别的MD5加密
  • 6、事务
  • 7、索引
    • 7.1、索引的分类
    • 7.2、测试索引
    • 7.2、索引原则
  • 8、权限管理与备份
    • 8.1、用户管理
    • 8.2、mysql备份
  • 9、规范数据库设计
    • 9.1、为什么需要设计
    • 9.2、数据库三大范式
  • 10、JDBC
    • 10.1、数据库驱动
    • 10.2、JDBC
    • 10.3、第一个jdbc程序
    • 10.4、statement对象
    • 10.5、PreparedStatement对象
    • 10.6、事务
    • 10.7、数据库连接池

概述

MySQL学习笔记,跟随b站up主狂神,恶补理论,弥补曾经犯下的错误 ,程序员落泪ing…

狂神:只要学不死,就往死里学

视频链接:https://www.bilibili.com/video/BV1NJ411J79W

1、初识数据库

1.1、DataBase

存储数据,管理数据

1.2、数据库分类

关系型数据库

  • MySQL ,SQL Server ,DB2 , SQLite…

非关系型数据库:

  • Redis
  • MongoDB

1.3、DBMS(数据库管理系统)

  • 数据库的维护管理软件

1.4、命令行操作数据库

mysql -uroot -p123456 --链接数据库
create database student --创建数据库
show databases; --查看所有数据库
use 数据库名 --切换数据库
show tables -- 查看所有表
describe student --查看student表结构
exit --退出链接

数据库xxx语言:

  • DDL 定义
  • DML 操作
  • DQL 查询
  • DCL 控制

2、操作数据库

关键字不区分大小写

2.1、操作数据库

  • 创建数据库
create database [if not exists] student
  • 使用数据库
--表明或者字段名如果是一个特殊字符,就需要带`
use `student`
  • 删除数据库
drop database [if exists] student

2.2、数据库列类型

数值

  • tinyint 十分小的数据,1个字节
  • smallint 较小的数据 , 2个字节
  • mediumint , 3 个字节
  • int 标准的整数 , 4个字节
  • big 较大的数字,8个字节
  • float 单精度浮点数 4 个字节
  • double 浮点数 8个字节
  • decimal 字符串形式的浮点数 金融计算一般使用decimal

字符串

  • char 字符串固定大小 0 -255

  • varchar 可变字符串 0 - 65536

  • tinytext 微型文本 2^ 8-1

  • text 文本串 2^ 16 -1 保存大文本

时间日期

  • date YYYY-MM-DD 日期格式
  • time HH:mm:ss 时间格式
  • datetime YYYY-MM-DD HH:mm:ss
  • timestamp 时间戳,1970.1.1到现在的毫秒数,也较为常用
  • year 年份

null

  • 没有值,未知
  • 注意不要使用null进行运算

2.3、数据库字段类型

Unsigned

  • 无符号整数
  • 生命了该列不能声明为负数

zerofill

  • 0填充
  • 不足的位数使用零填充 int(5) 3 — 003

自增

  • 自动在上一条记录的基础上+1
  • 通常用来设计唯一的主键,必须是整数类型
  • 可以自定义设计主键自增的初始值和步长

非空

  • 假设设置为not null,如果不赋值会报错

默认

  • 设置默认值

拓展

  • 每一个表都要有以下五个字段 ,阿里巴巴开发手册

    • id 主键
    • version 乐观锁
    • is_delete 伪删除
    • gmt_create 创建时间
    • gmt_update 更新时间

2.4、创建数据库表

create TABLE IF NOT EXISTS `student`(`id` int(4) NOT NULL AUTO_INCREMENT COMMENT '学号',`name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',PRIMARY KEY (`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

2.5、数据表的类型

MyISAM和InnoDB的区别

InnoDB 默认使用

MyISAM 早些年使用

MyISAM InnoDB
事务 不支持 支持
数据行锁定 不支持 支持
外键 不支持 支持
全文索引 支持 不支持
表空间大小 较小 较大,约为2倍

常规使用操作:

  • MyISAM 节约空间 速度较快
  • InnoDB 安全性高,事务处理,多表多用户操作

在物理空间的位置:

所有数据库文件都存在data文件夹下,本质还是文件存储

  • InnoDB : 在数据库表中只有.frm文件,以及上级目录的abdata1文件
  • MyISAM对应文件
    • frm文件 表结构定义文件
    • MYD 数据文件(data)
    • MYI 索引文件

2.6、修改删除表

修改

Alter

  • 修改表名
Alter Table 旧表名 RENAME as 新表名
  • 增加字段
Alter Table 表名 add age Int(11)
  • 修改字段(重命名,修改约束)
Alter table 表名 modify age varchar(11) --约束
Alter table 表名 change age age1 varchar(11) --重命名
  • 删除表字段
Alter table 表名 drop 字段名

删除

  • 删除表
Drop table if exists 表名

所有的创建和删除操作尽量加上判断,以免报错

注意点:

  • ``字段名包裹
  • 注释 – /**/
  • sql大小写不敏感,建议小写

3、MySQL数据管理

3.1、外键

外键居然是了解即可。。。。。

方式一 创建表是增加约束 麻烦

create table `grade`(`id` int(10) not null auto_increment comment 'id',`name` varchar(50) not null comment 'name',primary key (`id`)
)engine=innodb default charset=utf8create TABLE IF NOT EXISTS `student`(`id` int(4) NOT NULL AUTO_INCREMENT COMMENT '学号',`name` varchar(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',`gradeid` int(10) not null comment '年级',PRIMARY KEY (`id`),key `FK_gradeid`(`gradeid`), --定义外键keyconstraint `FK_gradeid` foreign key(`gradeid`) reference `grade`(`id`)   --给这个外键添加约束(执行引用)
)ENGINE=INNODB DEFAULT CHARSET=utf8

删除有外键关系的表,必须先删除引用别人的表(从表),在删除被引用的表(主表)

方法二 修改表添加

alter table `stuent`
add constraint `FK_gradeid` foreign key(`gradeid`) reference `grade`(`id`)

以上都是数据库级别的物理外键,不建议使用(避免数据库过多造成困扰)

最佳实践:

  • 数据库就是单纯的表,只用来存数据,只有行和列
  • 想用多张表的数据,用程序实现

3.2、DML语言

DML:数据操作语言

3.3、添加

insert

--插入语句
insert into 表名([字段1,字段2,字段3...]) values('值1','值2','值3'...)
--由于主键自增,我们可以省略(如果不写字段,他就会一一匹配)
--我们写插入语句,一定要数据与字段一一对应
--插入多个字段
insert into 表名 ([字段])
values('值1'),('值2'),('值3')...)

注意:

  • 字段可以省略,但是后面的值必须一一对应,不能少

3.4、修改

update

update student set name = 'xwy' where id = '1' --没有选择条件默认改变所有数据--修改多个属性
update student set name = 'xwy',email = '11.com'  where id = '1'

条件:where子句。运算符 id=某个值,>某个值,在某个区间内修改…

操作符返回布尔值

操作符 含义 范围 结果
= 等于 5=6 false
<>或者!= 不等于 5<>6 True
> , >=
< ,<=
between…and… 闭合区间 [2,5]
And
or

注意:

  • Column_name 是数据库列,尽量``
  • 条件,筛选的条件如果没有指定就会修改所有的列
  • value是一个具体的值,也可以是一个变量(时间一般会用)

3.5、删除

delete

delete from 表名 [where 条件]

truncate

完全清空数据库,表的结构和索引约束不会变

truncate table 表名

区别:

  • truncate 重新设置自增列,自增会归零!
  • truncate不会影响事务

delete删除的问题,重启数据库,现象

  • InnoDB 自增列从1开始,存在内存中,断电即失
  • MyISAM 继续从上一个自增量开始,存在文件中,不会丢失

4、DQL查询数据

4.1、DQL

  • 所有的查询操作都用它 select
  • 简单的查询复杂的查询都能用
  • 数据库最核心的语言
  • 使用频率最高的语言

4.2、查询

select * from student --查询student的全部字段
select stuname from student --查询某个字段
select stuname as 姓名 from student --别名
select concat('姓名:',stuname) as 新名字 from student --函数 拼接字符串

列的名字不是那么见名知意,就用别名

去重查询 distinct

select distinct stuNum from result --    去除查询结果中重复的数据只显示一条

数据库的列(表达式)

select version() --查询系统版本(函数)
select 100*3 as jieguo --用来计算(计算表达式)
select @@auto_increment_increment --查询自增的步长(变量)
select `studentResult`+1 as '提分后' form result

数据库的表达式:文本值,列,null,函数,计算表达式,系统变量。。。。

4.3、where

作用:检索数据库符合条件的值

逻辑运算符

运算符 语法 描述
and && a and b a&&b 两个都为真就为真
or || a or b a ||b 一个为真就为真
Not ! not a !a 真为假,假为真

尽量使用英文表达式

select stuNum,sturesult from resultwhere sturesult>=95 and sturesult<=100.  --and where sturesult between 95 and 100.      --between andwhere sturesult !=1000                   --!where not sturesult =1000                --not

模糊查询:比较运算符

运算符 语法 描述
is null a is null 如果操作符为null,结果为真
is not null a is not null 如果操作符不为null,结果为真
between a beteween b and c 若a在b和c之间,结果为真
like a like b sql匹配,如果a匹配b,结果为真
in a in (a1,a2,a3…) 如果a在a1…中的某一个,结果为真
--like结合,%代表0-任意个字符 _代表一个字符
select stuname form student where stuname like '刘%' --姓刘

4.4、联表查询

查询参加了考试的同学的姓名、学号、科目编号、分数

1、分析查询的字段来自那几张表

2、确定使用那种查询? 7种

3、确定交叉点(两个表中哪个数据是是相通的)

select a.studentNo,studendName,SubjectNo,StudentResult
from student as s
inner join result as r
where a.studenNo = r.studentNo

没参加考试的查不出

select a.studentNo,studendName,SubjectNo,StudentResult
from student as s
right join result as r
on s.studentNo = r.studentNo --join on是连接查询 where是等值查询

没参加考试的也查出来

select a.studentNo,studendName,SubjectNo,StudentResult
from student as s
left join result as r
on s.studentNo = r.studentNo
操作 描述
inner join 如果表中至少有一个匹配,就返回行
left join 即使右表中没有匹配,也会从左表返回所有值
Right join 即使左表中没有匹配,也会从右表返回所有值

查询缺考的同学

select a.studentNo,studendName,SubjectNo,StudentResult
from student as s
left join result as r
on s.studentNo = r.studentNo
where studentResult is null

自连接

自己的表和自己的表连接,核心:一张表拆分为两张一样的表

父类

categoryid pid
2 信息技术
3 软件开发
5 美术设计

子类

Pid(父id) categoryid categoryName
3 4 数据库
2 8 办公信息
3 6 web开发
5 7 ps技术

操作:查询父类对应的子类关系

select categoryName as '父栏目' ,categoryName as '子栏目'
from category as a ,category as b
on a.categoryid = b.categoryid

4.5、分页和排序

分页 limit、 排序 order by

排序:

select a.studentNo,studendName,SubjectNo,StudentResult
from student as s
left join result as r
on s.studentNo = r.studentNo
order by StudentResult ASC -- 降序 desc

分页:

分页,美页只显示五条数据

select a.studentNo,studendName,SubjectNo,StudentResult
from student as s
left join result as r
on s.studentNo = r.studentNo
order by StudentResult ASC -- 降序 desc
limit 0,5 --limit 起始值,页面大小

4.6、子查询

where(这个值是计算出来的)

本质:在where的语句中嵌套一个子查询语句

--查询数据库结构-1的所有考试结果(学好、科目编号、成绩),降序
--方式1:使用连接查询
select studentNo,r.SubjectNo,studentResult
from result as r
inner jogin subject as sub
on r.subjectNo = sub.subjectNo
where subjectName = '数据库结构-1'
--方式2:子查询(由里及外)
select studentNo,SubjectNo,studentResult
from result
where studentNo = (select studentNo from subject where subjectName = '数据库结构-1')
order by studentResult

4.7、分组和过滤

--查询不同课程的平均分,最高分,最低分,平均分大于80分
select subjectName AVG(studentResult) as 平均分 ,max(StudentResult),Min(StudentResult)
from result r
inner join subject sub
on r.subjectNo = sub.subjectNo
group by r.subjectNo --通过什么子段来分组
having 平均分>80

5、MySQL函数

5.1、常用函数

--数学运算
select ABS(-8)  --绝对值
select Ceiling(9.4) --向上取整 10
select Floor(9,4) --向下取整
select  Rand() --返回一个0-1之间的随机数
select sign() --判断 一个数的符号,负数返回-1,正数返回1
--字符串函数
select char_length('即使再小的帆也能远航') --字符串长度
select concat('我','爱','你',',们') --拼接字符串
select insert('我爱编程',1,2,'超级爱') --查询,替换 从某个位置开始替换某个长度
select lower('KuangShen')
select upper('KuangShen')
select instr('KuangShen','h') -- 7 返回第一次出现字串的索引
select replace ('坚持就能成功','坚持','努力') --替换出现的字符串
select substr('坚持就能成功',4,6)--源字符串,截取的位置,截取的长度
select reverse('坚持就能成功') --反转
--时间和日期函数
select current_date() --获取当前日期
select now() --获取当前时间
select localtime() -- 获取本地时间
select sysdate() --系统时间
--系统
select system_user() --系统当前登陆用户
select version() --版本

5.2、聚合函数

函数名称 描述
count()
sum()
avg()
max()
min()
select count(studentName) from student --count(字段) 会忽略null值
select count(*) from student --不会忽略null,本质计算行数
select count(1) from result --不会忽略null,本质计算行数
--!!对于主键字段,用count(字段)更快
--查询不同课程的平均分,最高分,最低分,平均分大于80分
select subjectName AVG(studentResult) as 平均分 ,max(StudentResult),Min(StudentResult)
from result r
inner join subject sub
on r.subjectNo = sub.subjectNo
group by r.subjectNo --通过什么子段来分组
having 平均分>80

5.3、数据库级别的MD5加密

MD5不可逆,具体的值的MD5是一样的

insert into md5Test values(1,'zhangsan',MD5('123456'))
--如何校验:将用户传进来的没密码,进行md5加密,比对加密的值
select * from md5Test where name ='zhangsan' and pwd = MD5('123456')

6、事务

要么都成功,要么都失败


1、A给B转账 A 1000 —>200 B 200

2、B收到A的钱 A 800 --> B 400


将一组SQL放在一个批次中去执行

事务原则ACID

事务的原子性(Atomicity):

是指一个事务要么全部执行,要么不执行,也就是说一个事务不可能只执行了一半就停止了。比如你从取款机取钱,这个事务可以分成两个步骤:1划卡,2出钱。不可能划了卡,而钱却没出来。这两步必须同时完成,要么就不完成。

要么都成功,要么都失败

一致性)(Consistency):

是指事务的运行并不改变数据库中数据的一致性。例如,完整性约束了a+b=10,一个事务改变了a,那么b也应该随之改变。

事务前后的数据完整性要保持一致,1000

独立性(Isolation):

事务的独立性也称作隔离性,是指两个以上的事务不会出现交错执行的状态。因为这样可能会导致数据不一致,更加具体的来讲,就是事务之间的操作是独立的。

==事务一旦提交则不可逆,被持久化到数据库中!

持久性(Durability):

事务的持久性是指事务执行成功以后,该事务对数据库所作的更改便是持久的保存在数据库之中,不会无缘无故的回滚。

==事务的隔离性是多个用户并发访问数据库时,数据库为每一个对象开启的事务,不能被其他事务操作数据库所干预,事务之间要相互隔离。

隔离导致的问题

脏读

指一个事务读取了另一个事务未提交的数据

不可重复读

在一个事务内读取表中的某一行数据,多次读取的结果不同。

虚读(幻读)

是指在一个事务内读取到了别的事务插入的数据,导致前后读取不一致

事务的隔离级别

读未提交(Read Uncommitted)

读未提交,顾名思义,就是可以读到未提交的内容。

因此,在这种隔离级别下,查询是不会加锁的,也由于查询的不加锁,所以这种隔离级别的一致性是最差的,可能会产生“脏读”、“不可重复读”、“幻读”。

如无特殊情况,基本是不会使用这种隔离级别的。

读提交(Read Committed)

读提交,顾名思义,就是只能读到已经提交了的内容。

这是各种系统中最常用的一种隔离级别,也是SQL Server和Oracle的默认隔离级别。这种隔离级别能够有效的避免脏读,但除非在查询中显示的加锁,如:

select * from T where ID=2 lock in share mode;

select * from T where ID=2 for update;

不然,普通的查询是不会加锁的。

那为什么“读提交”同“读未提交”一样,都没有查询加锁,但是却能够避免脏读呢?

这就要说道另一个机制“快照(snapshot)”,而这种既能保证一致性又不加锁的读也被称为“快照读(Snapshot Read)”

假设没有“快照读”,那么当一个更新的事务没有提交时,另一个对更新数据进行查询的事务会因为无法查询而被阻塞,这种情况下,并发能力就相当的差。

而“快照读”就可以完成高并发的查询,不过,“读提交”只能避免“脏读”,并不能避免“不可重复读”和“幻读”。

可重复读(Repeated Read)

可重复读,顾名思义,就是专门针对“不可重复读”这种情况而制定的隔离级别,自然,它就可以有效的避免“不可重复读”。而它也是MySql的默认隔离级别。

在这个级别下,普通的查询同样是使用的“快照读”,但是,和“读提交”不同的是,当事务启动时,就不允许进行“修改操作(Update)”了,而“不可重复读”恰恰是因为两次读取之间进行了数据的修改,因此,“可重复读”能够有效的避免“不可重复读”,但却避免不了“幻读”,因为幻读是由于“插入或者删除操作(Insert or Delete)”而产生的。

串行化(Serializable)

这是数据库最高的隔离级别,这种级别下,事务“串行化顺序执行”,也就是一个一个排队执行。

这种级别下,“脏读”、“不可重复读”、“幻读”都可以被避免,但是执行效率奇差,性能开销也最大,所以基本没人会用。

--mysql默认开启事务自动提交--手动处理事务
SET autocommit = 0 --关闭事务
--事务开启
start transaction --标记一个事务的开始,从这个之后的sql都在同一个事务里--提交:持久化(成功)
commit
--回滚:回到原来的样子(失败)
rollback
--事务结束
set autocommit = 1--了解
savepoint 保存点名字--保存点
rollback to savepoint  保存点名字--回滚到保存袋内
release savepoint 保存点名字 --撤销保存点

模拟场景

--转账
create database shop character set utf8 collate utf8_general_ci
use shop
--创建数据库
...
--插入数据
INSERT INTO account(name,money)
VALUES('A',2000.00),('B',10000.00)--开启事务
set autocommit = 0;
start TRANSACTION
update account set Money = money-500 where name='A';
update account set Money = money+500 where name='B';
COMMIT;
set autocommit=1;

7、索引

索引是帮助mysql高效获取数据的数据结构

7.1、索引的分类

  • 主键索引 primary key

    • 唯一的标识,不可重复,只能有一个列作为主键
  • 唯一索引 unique key
    • 避免重复列出现,唯一索引可以重复,多个列都可以标识为唯一索引
  • 常规索引 key/index
    • 默认的,index/key关键字设置
  • 全文索引 FullText
    • 在特定的数据库引擎下才有,MyISAM
    • 快速定位数据
--索引的使用
--1、在创建表的时候给字段增加索引
--2、创建完毕后,增加索引--显示所有的索引信息
show index from student
--增加一个索引
alter table student add fulltext index studentName(studentName) -- 索引名(列名)
--分析sql执行的状况
explain select * from student --非全文索引
explain select * from student where match(studentName) against('刘') --全文索引

7.2、测试索引

--sql编程,了解就行
--插入一万条数据
delimiter $$ --写函数之前必须要写,标志
create function mock_data()
returns int
begindeclare num int default 1000000;declare i int defalut 0;where i <num doinsert into app_user(name,email,phone,gender,password,age) values(concat('用户',i),'123456@qq.com'............);set i = i+1;end while;return i;
end;select mock_data();--使用索引
select * from app_user where name = '用户9999'; --要转个圈 耗时接近一秒钟
--id_表名_字段名
--create index 索引名 on 表名(字段)
create index id_app_user_name on app_user(name);
select * from app_user where name = '用户9999'; --耗时0.001

索引在小数据量的时候用处不大,在大数据时,区别十分明显

7.2、索引原则

  • 索引不是越多越好
  • 不要对经常变动的数据加索引
  • 小数据量表不需要加索引
  • 索引一般应该加在常用来查询的字段上

索引的数据结构

Hash类型的索引

BTree:InnoDB的默认数据结构

8、权限管理与备份

8.1、用户管理

sql命令

用户表:mysql下的user表

本质:对这张表进行增删改查

--创建用户
create user kuangshen identified by '123456'
--修改密码(当前登陆)
set password  = password('111111')
--修改密码(其他用户)
set password for kuangshen = password('111111')
--重命名
rename user kuangshen to xxx
--用户授权 全部权限 库.表
--all privileges 除了给别人授权(grant),其余的都可以干
grant all privileges on *.*  to xxx
--查询权限
show grants for xxx --执行用户
show grants for root@localhost --root用户权限
--撤销权限
revoke all privileges on *.* from xxx
--删除用户
drop user xxx

8.2、mysql备份

  • 保证重要的数据不丢失
  • 数据转移

MySQL数据库备份方式:

  • 直接拷贝物理文件
  • 可视化工具中手动倒出
    • 选择备份或导出,一般选择结构+数据
  • 使用命令行倒出 mysqldump
mysqldump -hlocalhost -uroot -p123456 school student result  >D:/a.sql
--导入
--登陆的情况下,切换到指定的数据库
source 备份文件

假设要备份数据库,以防数据丢失

把数据库给朋友!sql给别人即可!

9、规范数据库设计

9.1、为什么需要设计

当数据库比较复杂的时候,就需要设计

糟糕的数据库设计:

  • 数据冗余,浪费空间
  • 数据库插入和删除都会麻烦,异常【屏蔽使用物理外键】
  • 程序性能差

良好的数据库设计:

  • 节省内存空间
  • 保证数据库完整性
  • 方便我们开发系统

软件开发中关于数据库的设计:

  • 分析需求,分析业务和需要处理数据库的需求
  • 概要设计:设计关系图E-R图

设计数据库的步骤(个人博客)

  • 收集信息,分析需求

    • 用户表(用户登录注销,用户的个人信息,写博客,创建分类)
    • 分类表(文章分类,谁创建的)
    • 文章表(文章信息)
    • 友链表
    • 自定义表(系统信息,某个关键的字,或者一些主字段 key:value
  • 标识实体(把需求落实到每个字段)
  • 标识实体之间的关系
    • 写博客 user->blog
    • 分类 User->category
    • 关注 User->user
    • 友链 links
    • 评论 User->user

9.2、数据库三大范式

  • 信息重复
  • 更新异常
  • 插入异常
    • 无法正常显示信息
  • 删除异常
    • 丢失有效信息

三大范式

第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项。

保证每一列不可分

第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。

每张表只描述一件事情

第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

每一列都和主键直接相关,而不能间接相关

规范性和性能的问题

关联查询的表不能超过三张表

  • 考虑商业化的需求和目标(成本、用户体验)数据库的性能更加重要
  • 在规范性的问题的时候,需要适当考虑一下规范性
  • 故意给某些表增加一些冗余字段
  • 故意增加一些计算列(从大数据量减为小数据量的查询)

10、JDBC

10.1、数据库驱动

我们的程序通过数据库驱动和数据库打交道!

10.2、JDBC

简化开发人员对数据库统一操作,提供java操作数据库的规范,俗称jdbc

规范的实现由具体厂商去做

对于开发人员只需要掌握jdbc接口即可

10.3、第一个jdbc程序

1、创建项目

2、导入jar包

3、编写测试代码

package com.xxx;import java.sql.*;/*** @author levi* @create 2020/9/7 6:37 下午*/
public class JDBCFirstDemo {public static void main(String[] args) throws ClassNotFoundException, SQLException {//1、 加载驱动Class.forName("com.mysql.jdbc.Driver");//2、用户信息和urlString url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8";String username = "root";String password = "123456";//3 连接成功,数据库对象Connection connection = DriverManager.getConnection(url,username,password);//4 执行sql的对象Statement statement = connection.createStatement();//5、执行sql对象去执行sql,可能返回结构,查看返回结果String sql = "select * from account";ResultSet resultSet = statement.executeQuery(sql);//结果集包含所有查询出的结果while(resultSet.next()){System.out.println("id="+resultSet.getObject("id"));System.out.println("name="+resultSet.getObject("name"));System.out.println("money="+resultSet.getObject("money"));}//6、释放链接resultSet.close();statement.close();connection.close();}
}

DriverManager

Class.forName("com.mysql.jdbc.Driver"); //固定写法
Connection connection = DriverManager.getConnection(url,username,password);//connection  代表数据库
connect.commit();
connect.rollback();
connect.setAutoCommit();

URL

协议://ip:端口/数据库名?参数1&参数2&参数3
//oracle --1521
//jdbc:oracle:thin:@localhost:1521:sid

statement执行sql的对象

statement.executeQuery(); //查询返回ResultSet
statement.execute();  //执行任何sql
statement.executeUpdate(); //更新、插入、删除都用这个,返回一个受影响的行数

ResultSet 查询结果集,封装所有查询结果

获取指定数据类型

resultSet.getObject(); //不知道列类型时使用
resultSet.getString();
resultSet.getInt();
.....

遍历

resultSet.beforeFirst();//移动到最前面
resultSet.afterLast();//移动到最后
resultSet.next();//移动到下一个
resultSet.previous(); //移动到前一个
resultSet.absolute(row);//移动到指定行

释放链接

resultSet.close();
statement.close();
connection.close();

10.4、statement对象

配置累

driver = com.mysql.jdbc.Driver
url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8
username=root
password=123456

提取工具类

package com.xxx;import java.sql.*;/*** @author levi* @create 2020/9/7 6:37 下午*/
public class JDBCFirstDemo {public static void main(String[] args) throws ClassNotFoundException, SQLException {//1、 加载驱动Class.forName("com.mysql.jdbc.Driver");//2、用户信息和urlString url = "jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf8";String username = "root";String password = "123456";//3 连接成功,数据库对象Connection connection = DriverManager.getConnection(url,username,password);//4 执行sql的对象Statement statement = connection.createStatement();//5、执行sql对象去执行sql,可能返回结构,查看返回结果String sql = "select * from account";ResultSet resultSet = statement.executeQuery(sql);//结果集包含所有查询出的结果while(resultSet.next()){System.out.println("id="+resultSet.getObject("id"));System.out.println("name="+resultSet.getObject("name"));System.out.println("money="+resultSet.getObject("money"));}//6、释放链接resultSet.close();statement.close();connection.close();}
}

测试插入

package com.xwy;import com.xwy.util.JDBCUntil;import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;/*** @author levi* @create 2020/9/7 7:24 下午*/
public class Test {public static void main(String[] args) {Connection connection = null;Statement statement = null;ResultSet resultSet = null;try{connection = JDBCUntil.getConnect();statement = connection.createStatement();String sql = "insert into account(name,money) values('xxx',1000.00)";int i = statement.executeUpdate(sql);if(i>0){System.out.println("插入成功");}}catch (SQLException e){e.printStackTrace();}finally {JDBCUntil.relase(connection,statement,resultSet);}}
}

SQL注入问题

sql存在漏洞会被攻击导致泄漏

本质:sql会被拼接

10.5、PreparedStatement对象

防止sql注入,效率更高

package com.lesson03;import com.xwy.util.JDBCUntil;import java.math.BigDecimal;
import java.sql.*;/*** @author levi* @create 2020/9/7 7:38 下午*/
public class Test {public static void main(String[] args) {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection =  JDBCUntil.getConnect();String sql = "insert into account(name,money) values(?,?)";//预编译//防止sql注入的本质,将传递过来的参数当作字符// 假设存在转义字符,直接忽略掉  ' 会被直接转义掉statement = connection.prepareStatement(sql);statement.setString(1,"xwy");BigDecimal bigDecimal = new BigDecimal("13304.00");statement.setBigDecimal(2, bigDecimal);int i = statement.executeUpdate();if(i>0){System.out.println("插入成功");}}catch (SQLException e){e.printStackTrace();}finally {JDBCUntil.relase(connection,statement,null);}}
}

10.6、事务

package com.lesson04;import com.xwy.util.JDBCUntil;import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** @author levi* @create 2020/9/7 8:29 下午*/
public class TestTransaction {public static void main(String[] args) {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection =  JDBCUntil.getConnect();connection.setAutoCommit(false);String sql1 = "update  account set  money = money-100 where name = 'A'";statement = connection.prepareStatement(sql1);statement.executeUpdate();String sql2 = "update  account set money = money+100 where name = 'B'";statement = connection.prepareStatement(sql2);statement.executeUpdate();connection.commit();System.out.println("操作成功");}catch (SQLException e){try{connection.rollback();}catch (SQLException e1){e1.printStackTrace();}e.printStackTrace();}finally {JDBCUntil.relase(connection,statement,resultSet);}}
}

10.7、数据库连接池

数据库连接释放十分浪费资源

池化技术:准备一些预先的资源,过来就链接预先准备好的

最小连接数:常用连接数

最大连接数:业务最高承载上限

排队等待

等待超时:100ms

编写连接池,实现接口DataSource

开源数据源实现

DBCP

C3P0

Druid:阿里巴巴

使用数据库连接池,就不需要再编写连接数据库的代码了

DBCP

需要用到jar包

commons-dbcp-1.4.jar

Commons-pool-1.6.jar

工具类

package com.lesson05.utils;import com.xwy.util.JDBCUntil;
import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;import javax.sql.DataSource;
import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;/*** @author levi* @create 2020/9/7 10:44 下午*/
public class JDBCUtils_DBCP {private static DataSource dataSource = null;static {try{InputStream in = JDBCUtils_DBCP.class.getClassLoader().getResourceAsStream("dbcpconfig.properties");Properties properties = new Properties();properties.load(in);//创建数据源dataSource =  BasicDataSourceFactory.createDataSource(properties);}catch (Exception e){e.printStackTrace();}}//获取链接public  static Connection getConnect() throws SQLException {return dataSource.getConnection();//从数据源获取连接}//释放链接public static void relase(Connection connection , Statement statement, ResultSet resultSet){if(resultSet!=null){try{resultSet.close();}catch (SQLException e){e.printStackTrace();}}if(statement!=null){try{statement.close();}catch (SQLException e){e.printStackTrace();}}if(connection!=null){try{connection.close();}catch (SQLException e){e.printStackTrace();}}}
}

测试代码

package com.lesson05;import com.lesson05.utils.JDBCUtils_DBCP;
import com.xwy.util.JDBCUntil;import java.math.BigDecimal;
import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;/*** @author levi* @create 2020/9/7 10:54 下午*/
public class TestDBCP {public static void main(String[] args) {Connection connection = null;PreparedStatement statement = null;ResultSet resultSet = null;try {connection =  JDBCUtils_DBCP.getConnect();String sql = "insert into account(name,money) values(?,?)";//预编译//防止sql注入的本质,将传递过来的参数当作字符// 假设存在转义字符,直接忽略掉  ' 会被直接转义掉statement = connection.prepareStatement(sql);statement.setString(1,"lll");BigDecimal bigDecimal = new BigDecimal("13304.00");statement.setBigDecimal(2, bigDecimal);int i = statement.executeUpdate();if(i>0){System.out.println("插入成功");}}catch (SQLException e){e.printStackTrace();}finally {JDBCUtils_DBCP.relase(connection,statement,null);}}
}

CP30

xml配置

结论:无论使用什么数据源,本质是一样的,DataSource接口不会变

MySQL学习笔记-恶补基础篇相关推荐

  1. 菜鸟学习笔记:Java基础篇7(包装类、时间相关类、文件类、异常处理类)

    菜鸟学习笔记:Java其他常用类 基本数据类型包装类 时间处理和文件处理相关类 Date时间类 SimpleDateFormat Calendar日历类 文件类 异常机制 异常的概念 Java异常处理 ...

  2. 菜鸟学习笔记:Java基础篇6(数组、字符串)

    菜鸟学习笔记:Java常用类(数组.字符串) 数组 概述 数组的定义 二维数组 数组查找和排序 查找 排序 数组运用--字符串 不可变字符序列(String) 可变字符序列(StringBuilder ...

  3. 菜鸟学习笔记:Java基础篇5(抽象类与接口、回调函数、内部类)

    菜鸟学习笔记:Java面向对象篇下 抽象类 接口 回调函数 内部类 成员内部类 匿名内部类 抽象类 通过前面知识的学习,抽象类这个概念应该不难理解,但比较容易和后面要说的接口混淆,而且在面试中也比较爱 ...

  4. 菜鸟学习笔记:Java基础篇4(面向对象三大特征)

    菜鸟学习笔记:Java面向对象篇中 继承 概念 方法重写(override) Object类 Super关键字 组合 final关键字补充 封装 访问控制符 多态 继承 概念 继续上一篇的例子: #m ...

  5. 菜鸟学习笔记:Java基础篇3(面向对象思想、程序执行过程内存分析、面向对象重要概念)

    菜鸟学习笔记:Java面向对象篇上 Java面向对象的思想 Java程序执行过程内存分析 Java垃圾回收机制 构造方法 方法重载(overload) static关键字 this关键字 Java面向 ...

  6. 菜鸟学习笔记:Java基础篇2(变量、运算符、流程控制语句、方法)

    菜鸟学习笔记:Java基础篇2 变量 基本概念 变量作用域 final关键字 运算符 算术运算符 比较运算符 逻辑运算符 位运算符 赋值运算符 条件运算符 运算符优先级 Java三种流程控制语句 顺序 ...

  7. MySQL学习笔记一之基础架构

    MySQL学习笔记一之架构@TOC 架构图如下 Server层 连接器 负责跟客户端建立连接.获取权限.维持和管理连接 客户端如果太长时间没有动静,连接器会将其自动断开,时间由参数wait_timeo ...

  8. MySQL学习笔记_8_SQL语言基础复习

    SQL语言基础复习 一.概述 SQL语句注释方式 1)以"#"开头直到行尾的所有内容都是注释 2)以"--"(--后还有一个空格)开头直到行尾的所有内容都是注释 ...

  9. 【网络安全态势感知学习笔记】——“行远自迩”基础篇一:网络安全态势感知的基本概念

    文章目录 1. 网络安全态势感知的基本概念 1.1 态势感知的基本概念 1.2 网络安全态势感知 1.2.1 网络安全态势感知的定义 1.2.2 网络安全态势感知的阶段 1.2.3 网络安全态势感知的 ...

最新文章

  1. 悔不当初:回顾进化之路
  2. [转]关于WM_NCHITTEST消息
  3. C#nbsp;Listlt;gt;简单用法
  4. 将控制台输出重定向到textbox的dotnet类
  5. Google推荐的15条军规:HTML5代码规范
  6. python程序设计陈春晖答案_Python程序设计
  7. 华成英模拟电子技术笔记(1)-绪
  8. 微信小程序Animation动画的使用
  9. springcloud五大组件永远滴神——成神之路
  10. python基础----Day06
  11. 楚门的世界/The Truman Show (1998)
  12. Andromeda 源码解析 (同步获取服务)
  13. note3+android+5.1,最新的安卓5.1.1 ROOT教程(不需要刷第三方内核)
  14. (Tekla Structures二次开发)自动标注尺寸展示
  15. 全国省份GDP动态统计图表echarts.js插件
  16. 计算机电脑无法充电,iphone连接电脑无法充电怎么办
  17. 第14届蓝桥杯STEMA测评真题剖析-2022年11月27日Scratch编程初中级组
  18. 声波正演c语言程序,二维频率域声波方程正演模拟
  19. B1094 谷歌的招聘 (20 分)
  20. 六年级下册计算机电子板报教案,六年级下信息技术教案电子报刊设计河大版.doc...

热门文章

  1. 在桌面上显示你的每日计划(提醒事项)
  2. 2022中国企业安全与风险管理国际峰会
  3. 华东师范大学 数据科学与工程 829 2021考研真题
  4. 重要的统计量(期望、方差、协方差、相关系数、矩)的概念和性质
  5. c语言编程红旗,小程序10行代码实现微信头像挂红旗
  6. mysql论文的摘要格式怎么写_如何撰写论文的摘要
  7. 数据库无法打开的原因及解决办法
  8. 批处理文件的@echo off是什么意思?
  9. 误区:思维中常犯的6个基本错误
  10. Docker技术入门与实战 第二版-学习笔记-7-数据管理(volume)