码迷,mamicode.com
首页 > 数据库 > 详细

关于数据库MySQL

时间:2021-02-16 12:38:25      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:str   特定   url   第一范式   获得   ast   删除用户   相关   出现   

数据库基础

数据库分类

关系型数据库:SQL

  • MySQL,Oracle,Sql Server,DB2,SQLite
  • 通过表和表之间,行和列之间的关系进行数据的存储

非关系型数据库:NoSQL--Not Only SQL

  • Redis,MongDB
  • 对象存储,通过对象的自身的属性来决定

BDMS数据库管理系统

  • 数据库的管理软件,管理、维护和获取数据
  • MySQL 本质就是数据库管理系统

MySQL

关系型数据库管理系统 Relational Database Management System

登陆: mysql -u root -p

MySQL的注释

--注释

所有语句以分号结尾

基础语句

show databases; --查看所有数据库

use school; --切换数据库

show tables; --查看数据库中所有的表

describe student; --查看student表的所有信息

create database westos; --创建数据库

exit; --退出连接

数据库xxx语言

DDL 定义

DML操作

DQL查询

DCL控制

操作数据库

操作数据库

  1. 创建数据库

    CREATE DATABASE name;

    CREATE DATABASE IF NOT EXISTS name; 先判断是否存在

  2. 删除数据库

    DROP DATABASE name;

    DROP DATABASE IF EXISTS name;

  3. 使用数据库

    USE name;

    如果表名或者字段名是一个特殊字符,需要加上符号`

    SElECT `user` FROM student;
    

数据库的数据类型(列的类型)

数值

  • tinyint 十分小的数据 1个字节
  • smallint 较小的数据 两个字节
  • mediumint 中等大小的数据 3个字节
  • int 标准的整数 4个字节
  • bigint 较大的数字 8个字节
  • float 浮点数 4个字节
  • double 浮点数 8个字节(存在精度问题)
  • decimal 字符串形式的浮点数 金融计算的时候一般使用decimal

字符串

  • char 字符串 固定大小 0~255
  • varchar 可变字符串 0~65535 常用的 对应String
  • tinytext 微型文本 2^8-1
  • text 文本串 2^16-1 保存大文本

其中int(M)指的是最大显示位数为M,不是最大能填M位的数

比如int(1),可以存100000进去

但是VARCHAR(M)就是最大位数了

时间和日期

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

null

  • 没有值,未知
  • 不要使用NULL进行运算,结果为NULL

数据库的字段属性(重点)

Unsigned

  • 无符号的整数
  • 不能声明为负数

zerofill

  • 0填充的
  • 不足的位数,使用0来填充

auto-increment

  • 自增
  • 通常用来设置主键,必须是整数类型
  • 可以自定义设计初始值和步长

not-null

  • 非空,不赋值就会报错

default

  • 默认的值
  • 不指定该列的值,就是默认值

拓展

/*
每一个表都存在以下五个字段
*/
id --主键
`version` --乐观锁
is_delete --伪删除
gmt_create --创建时间
gmt_update --修改时间

创建数据库表

--表的名称和字段尽量扩起来,防止和关键字冲突
--字符串使用单引号扩起来
--所有的语句后面加逗号,最后一个可以不用加
CREATE TABLE IF NOT EXISTS `student`( 
  `id` INT(4) NOT NULL AUTO_INCREMENT COMMENT ‘学号‘,	--COMMENT注释
  `name` VARCHAR(30) NOT NULL DEFAULT ‘匿名‘ COMMENT ‘姓名‘,
  `pwd` VARCHAR(20) NOT NULL DEFAULT ‘123456‘ COMMENT ‘密码‘,
  `sex` VARCHAR(2) NOT NULL DEFAULT ‘女‘ COMMENT ‘性别‘,
  `birthday` DATETIME DEFAULT NULL COMMENT ‘出生日期‘,
  PRIMARY KEY(`id`)  --主键
)ENGINE=INNODB DEFAULT CHARSET=uft8

格式:

CREATE TABLE [IF NOT EXISTS] ‘name‘(
  `字段名` 列类型 [属性] [索引] [注释],
  ...
  `字段名` 列类型 [属性] [索引] [注释]
)[表类型][字符集设置][注释]

SHOW CREATE DATABASE school --查看创建数据库的语句

SHOW CREATE TABLE student --查看student数据表的定义语句

DESC student --显示表的结构

数据表的类型(数据库引擎)

INNODB默认使用

MYISAM早些年使用的

MYISAM INNODB
事务支持 不支持 支持
数据行锁定 不支持 支持
外键约束 不支持 支持
全文索引 支持 不支持
表的大小 较小 较大,约为2倍

常规使用操作:

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

在物理空间存在的位置

所有的数据库文件都存在data目录下,一个文件夹对应一个数据库

本质还是文件的存储

设置数据库表的字符集编码

CHARSET=utf8

不设置的话是MySQL默认的字符集编码——Latin1(不支持中文)

修改和删除表

修改

--修改表名
ALTER TABLE teacher RENAME AS teacher1
--增加表的字段
ALTER TABLE teacher1 ADD age INT(11)
--修改表的字段(重命名,修改约束)
ALTER TABLE teacher CHANGE age age1 INT(11)
ALTER TABLE teacher MODIFY age VARCHAR(11)
--删除表的字段
ALTER TABLE teacher DROP age1

删除

--删除表
DROP TABLE [IF EXISTS] teacher

MySQL数据管理

外键

  • 方法一:创建的时候
CREATE TABLE `grade`(
  `gradeid` INT(11) NOT NULL AUTO_INCREMENT,
  `gradename` VARCHAR(10) NOT NULL
)ENGINE=INNODB DEFAULT CHARSET=uft8

--学生表的gardeid字段,要去引用年级表的gradeid
--定义外键key
--给这个外键添加约束(执行引用)	reference 引用
CREATE TABLE IF NOT EXISTS `student`( 
  `id` INT(4) NOT NULL AUTO_INCREMENT COMMENT ‘学号‘,	--COMMENT注释
  `name` VARCHAR(30) NOT NULL DEFAULT ‘匿名‘ COMMENT ‘姓名‘,
  `gradeid` INT(11) NOT NULL,
  PRIMARY KEY(`id`),  --主键
  KEY `FK_gradeid` (`gradeid`),
  CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=uft8
  • 方法二:修改(常用)
ALTER TABLE `student`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade`(`gradeid`)
--CONSTRAINT后面是约束名

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

最佳实现

  • 数据库就是单纯的表,只用来存数据,只有行和列
  • 想使用外键的话用程序去实现

DML语言

数据库意义:数据存储、数据管理

DML语言:数据操作语言

  • insert
  • update
  • delete

添加

--插入语句
--INSERT INTO 表名(字段名1,字段名2,字段名3) values(‘值1,值2,值3‘)
INSERT INTO `grade`(`gradename`) VALUES(`Jonior`)

--由于主键自增我们可以省略(如果不写字段,就默认一一匹配)
--插入多组数据
INSERT INTO persons(id_p, lastname , firstName, city )
VALUES
(200,‘haha‘ , ‘deng‘ , ‘shenzhen‘),
(201,‘haha2‘ , ‘deng‘ , ‘GD‘),
(202,‘haha3‘ , ‘deng‘ , ‘Beijing‘);
  • 字段可以省略,但是后面的值要一一对应

修改

--update 带有条件,不指定条件的话会改动所有值
UPDATE `student` SET `name`=‘Jack‘ WHERE id=1;
--UPDATE 表名 SET column_name = value WHERE 条件;

--修改多个属性
UPDATE `student` SET `name`=‘Jack‘,`age`=23 WHERE id=1;

--通过多个条件定位数据
UPDATE `student` SET `name`=‘JENNIE‘ WHERE `name`=‘Jack‘ AND sex=‘女‘;

删除

--delete from 表名 [where 条件]
DELETE FROM `student` WHERE id = 1;
--完全清空一个数据库,表的结构和索引约束不会变
TRUNCATE `student`

DELETE & TURNCATE

  • 相同点:都能删除数据,都不会删除表结构
  • 不同点:
    • TURNCATE 重新设置自增列,计数器会归零
    • TURNCATE 不会影响事务
    • 关于DELETE,重启数据库现象
      • INNODB——自增列会从1开始(存在内存中,断电即失)
      • MYISAM——继续从上一个自增量开始(存在文件中的,不会丢失)

DQL语言数据库查询(重点!!)

DQL

data query language

  • 所有的查询操作 Select
  • 数据库最核心的语句
  • 使用频率最高的语句

指定查询字段

--查询全部的字段 SELECT 字段 FROM 表名
SELECT * FROM student

--查询指定字段
SELECT `studengNo`,`studentName` FROM student

--使用别名(字段、表都可以起别名)
SELECT `studengNo` AS 学号 FROM student AS s

--函数 CONCAT拼接字符串(姓名:Lisa)
SELECT CONCAT(‘姓名:‘,studentName) AS 新名字 FROM student

去重distinct

--查询有哪些同学参加了考试
SELECT * FROM result --查询全部考试成绩
SELECT `studentNo` FROM result --同学No.里面有重复(一个人好几科)
SELECT DISTINCT `studentNo` FROM result --去重

数据库的列(表达式)

SELECT VERSION()	--查询系统版本(函数)
SELECT 100*3-1 AS 结果	--用于计算(表达式)
SELECT @@auto_increment_increment --查询自增的步长(变量)

--学生成绩加一分查看
SELECT `studentNo`,`studentResult`+1 AS ‘提分后‘ FROM result

WHERE条件子句

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

逻辑运算符 结果为boolean值

  • a AND b a&&b
  • a OR b a||b
  • NOT a !a
SELECT studentNo, studentResult FROM result --查询所有成绩
SELECT studentNo, studentResult FROM result WHERE studentResult>=95 AND studentResult<=100

--模糊查询(区间)
SELECT studentNo, studentResult FROM result WHERE studentResult BETWEEN 95 AND 100 --between and 是闭区间

SELECT studentNo, studentResult FROM result WHERE NOT studentNo = 1000

模糊查询:比较运算符

运算符 语法 描述
IS NULL a is null 如果为null,真
IS NOT NULL a is not null 如果不为null,真
BETWEEN a between b and c a在bc之间,真
LIKE a like b SQL匹配,a匹配b,真
IN a in (a1,a2,a3,...) a在a1a2...中某一个,真
--查询姓刘的同学
--LIKE+‘‘:%代表0个到多个字符、_代表一个字符
SELECT studentName FROM student WHERE studentName LIKE ‘刘%‘
--刘后面两个字的
SELECT studentName FROM student WHERE studentName LIKE ‘刘__‘
--名字当中有嘉
SELECT studentName FROM student WHERE studentName LIKE ‘%嘉%‘

--in操作:具体的一个或者多个值
SELECT studentName FROM student WHERE studentNo IN (1001,1002,1003);

联表查询

JOIN

七种JOIN

![image-20210205194200770](/Users/wangyiran/Library/Application Support/typora-user-images/image-20210205194200770.png)

/*
思路:
1.分析需求,分析查询的字段来自哪些表
2.确定使用哪种连接查询?
确定交叉点(相同数据)
判断的条件:studentNo = studentNo 就连起来了
*/
--查询参加考试的同学(学号姓名科目编号分数)
SELECT s.studentNo, studentName, subjectNo, studentResult 
FROM student As s
INNER JOIN result AS r
WHERE s.studentNo = r.studentNo;
--INNER JOIN 获得的是两个表格中都有的人的信息

SELECT s.studentNo, studentName, subjectNo, studentResult 
FROM student As s
LEFT JOIN result AS r
ON s.studentNo = r.studentNo;
--LEFT JOIN 获得的是student表格中全部的信息,s有r没有的信息补NULL

SELECT s.studentNo, studentName, subjectNo, studentResult 
FROM student As s
RIGHT JOIN result AS r
ON s.studentNo = r.studentNo;
--RIGHT JOIN 获得的是result表格中全部的信息,r有s没有的信息补NULL

--eg:找到缺考的人(即没有成绩)
SELECT s.studentNo, studentName, subjectNo, studentResult 
FROM student As s
LEFT JOIN result AS r
ON s.studentNo = r.studentNo
WHERE studentResult IS NULL;

使用ON和WHERE的区别?

  • on条件是在生成临时表时使用的条件,它不管on中的条件是否为真,都会返回表中的记录。例如LEFT JOIN就是返回左边表数据的全部
  • where条件是在临时表生成好后,再对临时表进行过滤的条件,条件不为真的就全部过滤掉。例如LEFT JOIN是左边表中满足WHERE条件的数据

其实以上结果的关键原因就是left join,right join,full join的特殊性,不管on上的条件是否为真都会返回left或right表中的记录,full则具有left和right的特性的并集。 而inner join没这个特殊性,则条件放在on中和where中,返回的结果集是相同的。on为了反映外连接中一方的全连接,而where没有这个功能,内连接配对是可以的。

--三个表连接
--student、result、subject
SELECT s.studentNo, `studentName`, `subjectName`, `studentResult`
FROM student s
RIGHT JOIN result r
ON s.studentNo = r.studentNo
INNER JOIN subject sub
ON r.subjectNo = sub.subjectNo

自连接

自己的表和自己连接,即:一张表拆为两张一样的表

SELECT a.categoryName AS ‘parent‘, b.categoryName AS ‘son‘
FROM category AS a, category AS b
WHERE a.categoryid = b.pid

分页和排序

limit & order by

排序

--order by:升序ASC、降序DESC
--根据JAVA成绩的降序排序
SELECT s.studentNo, studentName, subjectName, studentResult
FROM student s
INNER JOIN result r
ON s.studentNo = r.studentNo
INNER JOIN subject sub
ON r.subjectNo = sub.subjectNo
WHERE subjectName = ‘JAVA‘
ORDER BY studentResult DESC

分页

缓解数据库压力、给人的体验更好

--每页只显示五条数据
--limit 起始值,页面大小
--LIMIT (N-1)*5, PageSize.  N:当前页数
SELECT s.studentNo, studentName, subjectName, studentResult
FROM student s
INNER JOIN result r
ON s.studentNo = r.studentNo
INNER JOIN subject sub
ON r.subjectNo = sub.subjectNo
WHERE subjectName = ‘JAVA‘
ORDER BY studentResult DESC
LIMIT 1,5 --从第2个开始,5个(第一个起始值是0)

子查询

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

==查询JAVA的所有考试结果,降序排列
SELECT studentNo,r.subjectNo,studentResult
FROM result r
INNER JOIN subject sub
ON r.subjectNo = sub.subjectNo
WHERE subjectName = ‘JAVA‘
ORDER BY subjectResult DESC

==方法2:使用子查询(有里及外)
SELECT studentNo, subjectNo, subjectResult
FROM result
WHERE subjectNo = (
  SELECT subjectNo FROM subject WHERE subjectName = ‘JAVA‘
)
SELECT DISTINCT s.studentNo, studentName
FROM student s
INNER JOIN result r
ON r.studentNo = s.studentNo
WHERE studentResult>=80 AND subjectNo =(
	SELECT subjectName FROM subject
  WHERE subjectName = ‘JAVA Programming‘
)

MySQL函数

常用函数
=====数学运算
SELECT ABG(-8) ==绝对值
SELECT CEILING(9.4) ==向上取整
SELECT FLOOR(9.4) ==向下取整
SELECT RAND() ==返回一个0-1之间的随机数
SELECT SIGN(-8) ==判断一个数的符号	返回0,-1,1

=====字符串函数
SELECT CHAR_LENGTH(‘shaking chloe‘) ==字符串长度
SELECT CONCAT(‘shaking‘,‘Gladys‘) ==拼接字符串
SELECT INSERT(‘HELLO WORLD‘,1,2,‘SERIEN‘) ==查询,从某个位置开始替换某个长度 
SELECT LOWER(‘WDHA‘) ==小写
SELECT UPPER(‘duged‘) ==大写
SELECT INSTR(‘GLADYS‘,‘Y‘) ==返回第一次出现的子串的索引
SELECT PEPLACE(‘越努力,越幸运‘,‘努力‘,‘坚持‘) ==替换出现的指定字符串
SELECT SUBSTRING(‘越努力,越幸运‘,6,2) ==从某位开始截取多少个字符串
SELECT REVERSE(‘越努力,越幸运‘) ==反转字符串

=====查询姓周的同学改为姓何
SELECT REPLACE(studentName,‘周‘,‘何‘) FROM student
WHERE studentName LIKE ‘周%‘ 

=====时间和日期函数
SELECT CURRENT_DATE() ==获取当前日期
SELECT CURDATE() ==获取当前日期
SELECT NOW() ==获取当前时间
SELECT LOCALTIME() ==本地时间
SELECT SYSDATE() ==系统时间
SELECT YEAR(NOW()) ==还可以用MONTH DAY HOUR MINUTE SECOND
=====系统
SELECT SYSTEM_USER()
SELECT USER()
SELECT VERSION()
聚合函数(常用)
函数名称 描述
COUNT() 计数
SUM() 求和
AVG() 平均值
MAX() 最大值
MIN() 最小值
SELECT COUNT(studentName) FROM student;	==COUNT(字段),会忽略所有的null
SELECT COUNT(*);	==不会忽略所有的null
SELECT COUNT(1);	==不会忽略所有的null
/*三个COUNT的区别
列名为主键,count(列名)比COUNT(1)快
列名不为主键,COUNT(1)快
如果表多个列且没有主键,则COUNT(1)的执行效率优于COUNT(*)
如果有主键,COUNT(主键)的执行效率是最优的
如果只有一个字段,那么COUNT(*)最优
*/

=====查询不同课程的平均分、最高分、最低分
==根据不同的课程分组
SELECT subjectName, AVG(studentResult),MAX(studentResult),MIN(studentResult)
FROM result r
INNER JOIN subject sub
ON r.subjectNo = sub.subjectNo
GROUP BY r.subjectNo	==通过什么字段分组
HAVING AVG(studentResult)>80
/*
分组之后的过滤条件要用HAVING
HAVING必须在GROUP BY后面,不能调换顺序
*/

数据库级别的MD5加密(扩展)

MD5:增强算法复杂度和不可逆性

UPDATE student SET pwd=MD5(pwd) WHERE id=1 ==加密
UPDATE student SET pwd=MD5(pwd)	==加密全部的密码
==插入的时候加密
INSERT INTO student VALUES(104,‘Shaking‘,MD5(‘19970104‘))
==如何校验:将用户传递进来的密码进行MD5加密,然后比对
SELECT * FROM student WHERE name=‘Shaking‘ AND pwd=MD5(‘19970104‘)

事务

什么是事务

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

事务原则:ACID原则 原子性、一致性、隔离性、持久性

Atomicity原子性:要么一起成功,要么一起失败

Consistency一致性:针对一个事务操作前与操作后的状态一致

Isolation隔离性:针对多个用户同时操作,主要是排除其他事务对本次事务的影响

Durability持久性:表示事务结束后的数据不随着外界原因导致数据丢失

? 事务没有提交,恢复到原状

? 事务已经提交,持久化到数据库了,一旦提交就不可逆

事务的隔离级别

脏读

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

不可重复读

在一个事务内读取表中的某一行数据,多次读取结果不同(不一定是错误,只是某些场合不对)

虚读(幻读)

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

测试事务实现转账

==mysql是默认开启事务自动提交的
SET autocommit = 0 ==关闭
SET autocommit = 1 ==开启(默认)

==手动处理事务
SET autocommit = 0	==关闭自动提交
==事务开启
START TRANSACTION ==标记一个事务的开始,从这之后的sql都在一个事务内
INSERT xx
==提交:持久化(成功)
COMMIT
==回滚:回到原来的样子(失败)
ROLLBACK
==事务结束
SET autocommit = 1	==开启自动提交

====了解即可====
SAVEPOINT name ==设置一个事务的保存点
ROLLBACK TO SAVEPOINT name ==回滚到保存点
RELEASE SAVEPOINT name ==撤销保存点

索引

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

索引的分类

  • 主键索引 PRIMARY KEY
    • 唯一的标识,主键不可重复,只能有一个列作为主键
  • 唯一索引 UNIQUE KEY
    • 避免重复的列出现,唯一索引可以重复,多个列都可以标识为UNIQUE KEY
  • 常规索引 KEY / INDEX
    • 默认的
  • 全文索引 FullText
    • 在特定的数据库引擎下才有
    • 快速定位数据

索引的使用

  1. 在创建表的时候给字段增加索引
  2. 创建完毕后,增加索引

基础语法

===显示所有的索引信息
SHOW INDEX FROM student
===增加一个索引	索引名(列名)
ALTER TABLE `student` ADD FULLTEXT INDEX `studentName`(studentName);
---CREATE INDEX 索引名 ON 表(字段)
CREATE INDEX id_app_user_name ON app_iser(`name`);

===分析SQL执行的状况
EXPLAIN SELECT * FROM student; ==常规索引,非全文索引
EXPLAIN SELECT * FROM student WHERE MATCH(studentName) AGAINST(‘刘‘);

不加索引的查询是遍历。

索引在大数据的时候区别十分明显

索引原则

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

索引的数据结构

Hash类型的索引

Btree:INNODB的默认索引

数据库权限管理和备份

用户管理

SQL 命令操作

用户表:mysql.user

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

--创建用户
CREATE USER shaking IDENTIFIED BY ‘123456‘--BY 密码
--修改密码(当前用户)
SET PASSWORD = PASSWORD(‘111111‘)
--修改密码(指定用户)
SET PASSWORD FOR shaking = PASSWORD(‘111111‘)
--重命名
RENAME USER shaking TO chloe
--用户授权
GRANT ALL PRIVILEGES ON *.* TO shaking --全部权限,库.表
--ALL PRIVILEGES除了给别人授权,都能做
--查询权限
SHOW GRANTS FOR shaking --指定用户
SHOW GRANTS FOR root@localhost --root后面要加地址
--撤销权限
REMOVE ALL PRIVILEGES ON *.* FROM shaking
--删除用户
DROP USER shaking

数据库备份

保证重要的数据不丢失

数据转移

备份方式

  • 直接拷贝物理文件

  • 在可视化工具中备份导出

  • 命令行:mysqldump

    导出:mysql -h域名 -u用户名 -r密码 库 表1 表2... 导出位置

    terminal:mysql -hlocalhost -uroot -p123456 school student /user/desktop

    导入:登陆的情况下,切换到指定的数据库

    teminal: source /user/desktop/a.sql

规范数据库设计

为什么需要设计

当数据库比较复杂的时候

良好的数据库:

  • 节省内存空间
  • 保证数据的完整性(不使用物理外键)
  • 方便开发系统

数据库设计

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

三大范式

为什么需要数据规范化?

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

三大范式

第一范式

1NF:要求数据库表的每一列都是不可分割的原子数据项

第二范式

2NF:满足第一范式的基础上,非码属性必须完全依赖于候选码

确保每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键)

(每张表只描述一件事情)

第三范式

3NF:在2NF的基础上,任何非主属性不依赖于其他非主属性(消除传递依赖)

确保每一列数据都和主键直接相关,而不是间接相关

规范性和性能的问题

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

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

JDBC

数据库驱动

程序通过数据库驱动操作数据库

JDBC

为了简化开发人员的(对数据库统一)操作,提供了一个(Java操作数据库)规范,俗称JDBC

开发人员只需要掌握JDBC接口的操作即可

相关包:

Java.sql

Javax.sql

和一个数据库驱动包

JDBC程序

  • 创建数据库
  • 创建一个普通项目
  • 导入数据库驱动
    • lib文件夹,放入驱动,还要add library
  • 编写测试代码
public class JdbcFirstDemo{
  public static void main(String[] args){
    //1.加载驱动
    Class.forName("com.mysql.jdbc.Driver");//固定写法
    //2.用户信息和url
    String url = "jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&useSSL=true";//中文&编码&使用安全
    String username = "root";
    String password = "123456";
    //3.连接成功,数据库对象 Connection代表数据库
    Connection connection = DriverManager.getConnection(url,uername,password);
    //4.执行SQL的对象 Statement 执行SQL的对象
    Statement statement =  connection.createStatement();
    //5.执行SQL的对象 去执行SQL
    String sql = "SELECT * FROM users";
    ResultSet resultSet = statement.excuteQuery(sql);//返回的结果集,结果集中封装了全部查询出来的结果
    while(resultSet.next()){
      System.out.println("id="+resultSet.getObject("id"));
      System.out.println("name="+resultSet.getObject("NAME"));
    }
    //6.释放连接
    resultSet.close();
    statement.close();
    connection.close();//消耗资源,用完关掉!  
  }
}

URL

String url = "jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&useSSL=true";

//jdbc:mysql://localhost:3306/数据库名?参数一&参数二&参数三

Conntecion

//代表数据库
//事务自动提交
connection.setAutoCommit();
//事务提交
connection.commit();
//事务回滚
connection.rollback();

Statement

//执行SQL的对象
//查询操作返回ResultSet
statement.excuteQuery();
//执行任何sql
statement.excute();
//更新、插入、删除都用这个,返回受影响的行数
statement.excuteUpdate();//增删改都用这个

ResultSet

//查询的结果集
//获得指定的数据类型:
//不知道列类型的情况下
resultSet.getObject();
//知道列的类型
resultSet.getString();
resultSet.getInt();
resultSet.getDate();
...

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

SQL注入的问题

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

SELECT * FROM user WHERE user=‘ ‘ or ‘1=1‘ AND password=‘ ‘ or ‘1=1‘;

这样可以把所有的信息都盗取出来

PreparedStatement对象

可以防止sql注入,并且效率更高

把传递进来的参数当作字符

假设其中存在转义字符,会被直接转义

//增删改
public class JdbcFirstDemo{
  public static void main(String[] args){
    
    Class.forName("com.mysql.jdbc.Driver");//固定写法
    
    String url = "jdbc:mysql://localhost:3306/jdbcstudy?userUnicode=true&characterEncoding=utf8&useSSL=true";//中文&编码&使用安全
    String username = "root";
    String password = "123456";
    
    Connection conn = DriverManager.getConnection(url,uername,password);
    
    //区别
    //使用?占位符替代参数
    String sql = "INSERT INTO users(id,name,password,birthday) VALUES(?,?,?,?)";
    //String sql = "DELETE FROM users WHERE id=?";
    //String sql = "UPDATE users SET `name`=? WHERE id=?";
    PreparedStatement st =  connection.prepareStatement(sql);//预编译SQL,先写SQL,然后不执行
    
    //手动给参数赋值
    st.setInt(1, 4);//第一个参数是第几个参数
    st.setString(2, "SHAKING");
    st.setString(3, "123456");
    //sql.Date	数据库
    //util.Date	Java	new Date().getTimw()获得时间戳
    st.setDate(4, new java.sql.Date(new Date().getTime()));
    
    //执行
    int i = st.executeUpdate();
    if(i>0){
      System.out.println("插入成功");
    }
    
    st.close();
    connection.close();//消耗资源,用完关掉!  
  }
}
//查
String sql = "SELECT * FROM users WHERE id=?";
PreparedStatement st =  connection.prepareStatement(sql);
st.setInt(1, 2);
rs = st.executeQuery();
if(rs.next()){
  System.out.println(rs.getString("NAME"));
}

事务

要么都成功,要么都失败

ACID 原则

隔离性的问题:

脏读:读取到未提交的事务

不可重复读:在一个事务内,重复读取同一个表格,数据发生了改变

虚读(幻读):在一个事务内,读取到了别人插入的数据,导致前后读出来结果不一致

代码实现

  1. 开启事务 conn.setAutoCommit(false); 关闭自动提交的同时开启事务
  2. 一组业务执行完毕,提交事务
  3. 可以在catch语句中定义回滚语句,但是默认事务执行失败会自动回滚

数据库连接池

连接--释放 十分浪费系统资源

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

最小连接数(常用连接数):10

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

等待超时:100ms

开源数据源实现

DBCP

C3P0

Druid:阿里巴巴

使用这些数据库连接池之后,我们在项目开发中就不需要编写连接数据库的代码了

DBCP: dataSource = BasicDataSourceFactory.createDataSource(properties);

C3P0: dataSource = new ComboPooledDataSource("MySQL");

本质一样,DataSource接口不变,方法就不会变

关于数据库MySQL

标签:str   特定   url   第一范式   获得   ast   删除用户   相关   出现   

原文地址:https://www.cnblogs.com/GladysJiu/p/14399977.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!