MySQL学习

MySQL

1、初始MySQL

javaEE: 企业级开发 web

前端(页面渲染,展示 数据)

后台(连接点: 连接数据库 jdbc mybatis 连接前端(控制视图的跳转,给前端传递数据))

数据库(存取数据)

1.1为什么学习数据库

1.岗位需求

2.现在的世界,大数据时代—mysql集群,得数据者得天下,没有隐私

3.被迫需求:存数据 去IOE 不用国外的

4.数据库是所有软件体系中最核心的存在DBA(数据库管理员)

1.2什么是数据库

数据库(DataBase)

概念: 数据仓库, 存储数据 软件, 安装在操作系统之上的 sql 可以存储大量的数据

作用: 存数据,管理数据

1.3数据库分类

关系型数据库: Excle(SQL)
  • Mysql、oracle、 sql server、DB2、SQLLite
  • 通过表和表之间,行和列之间的关系进行数据的存储,学院信息表 考勤表
非关系型数据库: json (key : value)(NoSQL 不仅仅是sql)
  • redis、mongdb
  • 非关系型数据库, 对象存储,通过对象的自身的属性来决定

DBMS(数据库管理系统)

  • 数据库管理软件,科学有效的管理我们的数据,维护和获取数据;
  • MySQL,本质是一个数据库管理系统!

在这里插入图片描述

1.4MySQL简介

MySQL是一个**关系型数据库管理系统****,**由瑞典MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL 是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一。

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。

MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版商业版,由于其体积小、速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型网站的开发都选择 MySQL 作为网站数据库。也可以用于大型网站

前世:由瑞典MySQL AB 公司开发

今生:属于 Oracle 旗下产品

MySQL是最好的 RDBMS (Relational Database Management System,关系数据库管理系统) 应用软件之一,开源的数据库软件

5.7 版本稳定 8.0也可以

官网:https://www.mysql.com/

官网下载地址:https://dev.mysql.com/downloads/mysql/

安装建议 :

  1. 尽量不要使用.exe文件
  2. 尽可能使用安装包安装

1.5安装MySQL

1.解压安装包

2.配置环境变量 新加path就行

在这里插入图片描述

3.新建mysql配置文件ini, 把文件的扩展名打开

my.ini

在这里插入图片描述

[mysqld]

# 设置3306端口

port=3306

# 设置mysql的安装目录

basedir=D:\\mysql\mysql-8.0.18-winx64

# 切记此处一定要用双斜杠\\,单斜杠这里会出错。

# 设置mysql数据库的数据的存放目录

datadir=D:\\mysql\mysql-8.0.18-winx64\\Data
# 此处同上

# 允许最大连接数

max_connections=200

# 允许连接失败的次数。这是为了防止有人从该主机试图攻击数据库系统

max_connect_errors=10

# 服务端使用的字符集默认为UTF8

character-set-server=utf8

# 创建新表时将使用的默认存储引擎

default-storage-engine=INNODB

# 默认使用“mysql_native_password”插件认证
default_authentication_plugin=mysql_native_password

[mysql]

# 设置mysql客户端默认字符集

default-character-set=utf8

[client]

# 设置mysql客户端连接服务端时默认使用的端口

port=3306

default-character-set=utf8

4.管理员模式,打开所有的东西

5.进入bin目录下

# 安装mysql服务
mysqld -install
# 初始化数据问价
mysqld --initialize-insecure --user=mysql
# 启动mysql 服务
net start mysql  # 会显示mysql启动成功

6.进入mysql修改密码update user set password=password("123456") where user="root"; flush privileges;注释跳过密码

7.重启服务,然后进行登录mysql -uroot -p123456sql后面一定要加上分号

8.sc delete mysql清空服务

1.6无脑安装sqlyog

一些简单的操作

创建数据库

在这里插入图片描述

在这里插入图片描述

1.7连接数据库

命令行连接

mysql -uroot -p123456 --连接数据库
update mysql.user set authentication_string=password('123456') where user='root' and Host = 'localhost'; -- 修改用户的密码
flush privileges;` -- 刷新权限
-- 所有的语句都用分号结尾
-------------------------
show databases; --   查询所有的数据库

mysql> use `school`; -- 切换数据库
Database changed
show tables; --查看数据库中所以的表
describe student; -- 显示表中所有的字段的信息

-------------------------
create database mytest; -- 创建一个数据库

exit; -- 退出连接

# 是sqlyog 的注释  -- 是sql的注释  
/**/ 是多行注释
--  单行注释

数据库xxx语言增删改查 cv程序员 api程序员 crud业务程序员

DDL: 数据库定义语言

DML: 数据库操作语言

DQL: 数据库查询语言(核心一般是查询语言)

DCL:数据库控制语言

2.操作数据库

mysql的关键字不区分大小写

操作数据库>操作数据库中的表>操作数据库表中的数据

2.1操作数据库(了解,操作一遍就可以了)

1.创建数据库

CREATE DATABASE IF NOT EXISTS mytest;

2.删除数据库

DROP DATABASE IF EXISTS mytest;

3.使用数据库

USE school;

注意: 如果是使用关键词来表示数据库,那么需要加一个`来进行转移义

4.查看数据库

SHOW DATABASES; -- 展示所有的数据库

对比sqlyog的可视化操作

学习思路: 不会的操作对比sqlyog操作

2.2数据库的数据列类型

数值

tinyint十分小的类型1个字节
smallint比较小的类型2个字节
mediumint中等大小的数据3个字节
int标准的整数4个字节后面的括号里面的数字表示的是最大的显示的宽度
bigint较大的数据8个字节
float单精度浮点数4个字节
double双精度浮点数8个字节
decimal字符串的浮点数(金融计算的时候一般使用这个类型)

字符串

char字符串固定大小0-255
varchar字符串可变长度0-65535(String)
tinytext微型文本2^8-1
text文本串2^16-1(大文本)

时间和日期

dateYYYY-MM-DD日期
timeHH:mm:ss时间格式
datetimeYYYY-MM-DD HH:mm:ss最常用的时间格式
timestamp时间戳1970-1-1到现在的毫秒数
year年份表示

null

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

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

Unsigned无符号证书整数声明了该列不能为负数
Zerofill?0填充的不足的位数,用0来进行填充
自增通常理解为自增,自动在上一条记录的基础上加一通常用来设置唯一的主键,必须是证书类型,可以自定义设置起始值
非空 Null notnull假设设置为not null,如果不给他赋值,就会报错null如果不填充,就是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 '姓名',
`pwd` VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT '密码',
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别',
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

格式

CREATE TABLE [IF NOT EXISTS] `表名`(
`字段名` 列类型 [属性] [索引][注释],
`字段名` 列类型 [属性] [索引][注释],
`字段名` 列类型 [属性] [索引][注释],
    ....
)[表类型][字符集设置][注释]
-- 查看创建数据库school的语句
SHOW CREATE DATABASE school;
-- 查看创建表student的语句
SHOW CREATE TABLE student;
-- 查看表的基本结构
DESC student;

2.5数据表的类型

-- 关于数据库的引擎
/*
INNODB  默认使用
MYISAM  早些年使用
*/
MYISAMINNODB
事务支持不支持支持
数据行锁定不支持支持
外键约束不支持支持
全文索引支持不支持
较小较大约为前者的两倍

常规的使用操作:

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

在物理空间存在的位置

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

本质还是文件存储

MySQL引擎在物理文件上的区别:

  • INNODB在数据库表中只有一个*.frm文件,以及上级目录下的ibdata文件
  • MYISAM对应文件
    • *.frm — 表结构的定义文件
    • *.MYD 数据文件(Data)
    • *.MYI 索引文件

设置数据库字符集的编码

CHARSET=utf8
-- 不设置的话是mysql的默认的字符集编码(不支持中文)  最好在创建表的时候去设置
-- 1.创建表的时候就修改
-- 2.在my.ini添加字符集

2.6修改和删除表

修改

-- 修改表
--ALTER TABLE 旧的表名 RENAME `新的表名`;
ALTER TABLE `teacher` RENAME `teacher1`;
--ALTER TABLE `表名` ADD 字段 数据类型;
ALTER TABLE `teacher1` ADD age INT(3);
-- 修改表的字段  (重命名修改约束)
-- 修改表的约束
-- ALTER TABLE `表名` MODIFY 字段名字 类型;
ALTER TABLE `teacher1` MODIFY age VARCHAR(11);
-- 重命名表的字段的名字
-- ALTER TABLE `表名` CHANGE 旧的字段名 新的字段名 新的字段名的类型;
ALTER TABLE `teacher1` CHANGE age age1 INT(2);


-- 删除表的字段
ALTER  TABLE `teacher1` DROP age1;

删除

注意: 所有的删除尽量加上是否存在,以免报错

-- 删除表(如果表存在)
--DROP TABLE IF EXISTS `表名`;
DROP TABLE IF EXISTS `teacher1`;

注意点:

  • ``的引用,所有的字段名使用这个符号
  • 注释是 – 或者是/**/
  • sql关键字的大小写是不敏感的,建议写小写
  • 所有的符号全部用英文的

3.MySQL的数据管理

3.1外键(了解即可)

方式一: 在创建表的时候给表添加约束

-- 创建年级表
CREATE TABLE `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY(`gradeid`)
)ENGINE=INNODB CHARSET=utf8
-- 创建学生表
-- 学生表的gradeid 要引用年级表的gradeid
-- 1.定义外键
-- 2.给这个外键添加约束
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(4) NOT NULL AUTO_INCREMENT 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 '出生日期',
`gradeid` INT(10) NOT NULL COMMENT '学生的年级',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY(`id`),
KEY `FK_gradeid` (gradeid) ,
CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

删除表的时候,要删除引用的表(从表),之后再删除被引用的表(主表)

方式二: 创建表成功后添加外键约束

-- 创建年级表
CREATE TABLE `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '年级id',
`gradename` VARCHAR(50) NOT NULL COMMENT '年级名称',
PRIMARY KEY(`gradeid`)
)ENGINE=INNODB CHARSET=utf8
-- 创建学生表
-- 学生表的gradeid 要引用年级表的gradeid
-- 1.定义外键
-- 2.给这个外键添加约束
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(4) NOT NULL AUTO_INCREMENT 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 '出生日期',
`gradeid` INT(10) NOT NULL COMMENT '学生的年级',
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址',
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
-- 创建表的时候没有外键的关系
-- ALTER TABLE `表名` 
-- ADD CONSTRAINT `FK_gradeid` FOREIGN KEY (`作为外键的列`) REFERENCES `引用的表`(`引用的表的字段`);
ALTER TABLE `student` 
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gradeid`);

注意: 以上的操作都物理外键,不建议使用(避免数据库过多造成困扰,这里了解即可)

最佳实践: 数据库就是单存的表,只用来存储行和列,我们要使用外键,使用程序去解决

在企业中有要求,不得使用外键,一切外键概念必须在应用层解决(在删除和更新的时候比较方便)

3.2DML语言(全部记住)

数据库的意义: 数据存储和数据管理

DML 数据操作语言:

  • insert
  • update
  • delete
3.3添加(insert)
-- 插入语句(添加) 如果不写表的字段,就会一一匹配
-- INSERT INTO `表名`(`字段名`) VALUES('值');
INSERT INTO `grade`(`gradename`) VALUES('大二');
-- 一般写插入语句,一定要数据和字段一一对应
INSERT INTO `grade`(`gradename`) VALUES('大二');

-- 插入多个字段
-- INSERT INTO `grade`(`gradename`) VALUES('大三'),('大四');
INSERT INTO `grade`(`gradename`) VALUES('大三'),('大四');


INSERT INTO `student`(`name`,`pwd`,`sex`) VALUES('李四','aaaaaa','男'),
('王五','aaaaaa','男'),
('孙子','aaaaaa','男');

注意事项

1.字段和字段之间使用英文逗号隔开

2.字段可以省略,但是里面的值要一一对应

3.可以同时插入多条数据,values后面的值,需要使用逗号隔开

3.4修改(update)
--  修改数据  修改谁 也就是条件
-- 修改学院的名字
-- 指定条件的修改
UPDATE `student` SET `name`='陈留红' WHERE id = 1;
-- 不指定条件的修改
UPDATE `student` SET `name`='陈留红';
-- 修改多个属性的时候,一样需要使用逗号隔开

条件: where 子语句 运算符 id = 某个值或者是其他的判断条件

操作符含义范围结果
=等于5=6false
<>或者是!=不等于5<>6true
>
<
>=
<=
between…and…在某个范围内[2,5]
and我和你 &&5>1 and 1>2false
or我或你 ||5>1 or 1>2true
-- 通过多个条件修改数据,没有上限
SELECT * FROM student;
UPDATE `student` SET `name`='孙子' WHERE `name`='陈留红' AND id=1;

注意事项: 列名不能随便写,尽量带上`,条件是筛选的条件,如果没有指定,则会修改所有的列,value,是一个具体的值,也可以是一个变量,多个设置的属性使用英文隔开trim 把多余的符号干掉

-- 通过多个条件修改数据,没有上限  设置变量值 , 一般只有时间会用   
SELECT * FROM student;
UPDATE `student` SET `birthday`=CURRENT_TIME WHERE `name`='孙子';
3.5删除(delete)
-- 删除全部的数据
DELETE FROM `student`;
-- 删除数据
DELETE FROM `student` WHERE id=1;

TRUNCATE

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

-- 清空student表
TRUNCATE `student`;

DELETE和TRUNCATE的区别

相同点: 都能够删除数据,都不会删除表结构

不同点:

  • TRUNCATE 重新设置 自增列 计数器会归零
  • TRUNCATE 不会影响事务
-- 清空student表
TRUNCATE `student`;

-- 测试 DELETE 和TRUNCATE 的区别
CREATE TABLE `test`(
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '主键',
`name` VARCHAR(30) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO `test`(`name`) VALUES('zs'),('ls'),('ww');

DELETE FROM `test`; -- 不会影响自增

TRUNCATE TABLE `test`;

了解即可: delete删除的问题,重启数据库,现象:

  • INNODB 自增列会从1开始(存储在内存当中的,断电及失)
  • MYISAM 继续从上一个自增量开始(存在文件之中,不会丢失)

4.DQL查询数据(最重点)

select 语法

SELECT [ALL | DISTINCT]
{* | table.* | [table.field1[as alias1][,table.field2[as alias2]][,...]]}
FROM table_name [as table_alias]
	[left | right | inner join table_name] --联合查询
	[WHERE ...] -- 指定结果需满足条件
	[GROUP BY ...] -- 指定结果按照那几个字段来分组
	[HAVING ...] -- 过滤分组的条件满足的次要条件
	[ORDER BY ... ]  -- 指定查询记录按一个或者是多个条件排序
	[LIMIT {[offset,]row_count | row_countOFFSET offset}];
	-- 指定查询的记录从那条开始至那条

4.1DQL

(Data Query Language : 数据查询语言)

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

测试数据

/*
SQLyog Ultimate v12.08 (64 bit)
MySQL - 5.7.19 : Database - school
*********************************************************************
*/


/*!40101 SET NAMES utf8 */;

/*!40101 SET SQL_MODE=''*/;

/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
CREATE DATABASE /*!32312 IF NOT EXISTS*/`school` /*!40100 DEFAULT CHARACTER SET utf8 */;

USE `school`;

/*Table structure for table `grade` */

DROP TABLE IF EXISTS `grade`;

CREATE TABLE `grade` (
  `GradeID` int(11) NOT NULL AUTO_INCREMENT COMMENT '年级编号',
  `GradeName` varchar(50) NOT NULL COMMENT '年级名称',
  PRIMARY KEY (`GradeID`)
) ENGINE=InnoDB AUTO_INCREMENT=6 DEFAULT CHARSET=utf8;

/*Data for the table `grade` */

insert  into `grade`(`GradeID`,`GradeName`) values (1,'大一'),(2,'大二'),(3,'大三'),(4,'大四'),(5,'预科班');

/*Table structure for table `result` */

DROP TABLE IF EXISTS `result`;

CREATE TABLE `result` (
  `StudentNo` int(4) NOT NULL COMMENT '学号',
  `SubjectNo` int(4) NOT NULL COMMENT '课程编号',
  `ExamDate` datetime NOT NULL COMMENT '考试日期',
  `StudentResult` int(4) NOT NULL COMMENT '考试成绩',
  KEY `SubjectNo` (`SubjectNo`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

/*Data for the table `result` */

insert  into `result`(`StudentNo`,`SubjectNo`,`ExamDate`,`StudentResult`) values (1000,1,'2013-11-11 16:00:00',94),(1000,2,'2012-11-10 10:00:00',75),(1000,3,'2011-12-19 10:00:00',76),(1000,4,'2010-11-18 11:00:00',93),(1000,5,'2013-11-11 14:00:00',97),(1000,6,'2012-09-13 15:00:00',87),(1000,7,'2011-10-16 16:00:00',79),(1000,8,'2010-11-11 16:00:00',74),(1000,9,'2013-11-21 10:00:00',69),(1000,10,'2012-11-11 12:00:00',78),(1000,11,'2011-11-11 14:00:00',66),(1000,12,'2010-11-11 15:00:00',82),(1000,13,'2013-11-11 14:00:00',94),(1000,14,'2012-11-11 15:00:00',98),(1000,15,'2011-12-11 10:00:00',70),(1000,16,'2010-09-11 10:00:00',74),(1001,1,'2013-11-11 16:00:00',76),(1001,2,'2012-11-10 10:00:00',93),(1001,3,'2011-12-19 10:00:00',65),(1001,4,'2010-11-18 11:00:00',71),(1001,5,'2013-11-11 14:00:00',98),(1001,6,'2012-09-13 15:00:00',74),(1001,7,'2011-10-16 16:00:00',85),(1001,8,'2010-11-11 16:00:00',69),(1001,9,'2013-11-21 10:00:00',63),(1001,10,'2012-11-11 12:00:00',70),(1001,11,'2011-11-11 14:00:00',62),(1001,12,'2010-11-11 15:00:00',90),(1001,13,'2013-11-11 14:00:00',97),(1001,14,'2012-11-11 15:00:00',89),(1001,15,'2011-12-11 10:00:00',72),(1001,16,'2010-09-11 10:00:00',90),(1002,1,'2013-11-11 16:00:00',61),(1002,2,'2012-11-10 10:00:00',80),(1002,3,'2011-12-19 10:00:00',89),(1002,4,'2010-11-18 11:00:00',88),(1002,5,'2013-11-11 14:00:00',82),(1002,6,'2012-09-13 15:00:00',91),(1002,7,'2011-10-16 16:00:00',63),(1002,8,'2010-11-11 16:00:00',84),(1002,9,'2013-11-21 10:00:00',60),(1002,10,'2012-11-11 12:00:00',71),(1002,11,'2011-11-11 14:00:00',93),(1002,12,'2010-11-11 15:00:00',96),(1002,13,'2013-11-11 14:00:00',83),(1002,14,'2012-11-11 15:00:00',69),(1002,15,'2011-12-11 10:00:00',89),(1002,16,'2010-09-11 10:00:00',83),(1003,1,'2013-11-11 16:00:00',91),(1003,2,'2012-11-10 10:00:00',75),(1003,3,'2011-12-19 10:00:00',65),(1003,4,'2010-11-18 11:00:00',63),(1003,5,'2013-11-11 14:00:00',90),(1003,6,'2012-09-13 15:00:00',96),(1003,7,'2011-10-16 16:00:00',97),(1003,8,'2010-11-11 16:00:00',77),(1003,9,'2013-11-21 10:00:00',62),(1003,10,'2012-11-11 12:00:00',81),(1003,11,'2011-11-11 14:00:00',76),(1003,12,'2010-11-11 15:00:00',61),(1003,13,'2013-11-11 14:00:00',93),(1003,14,'2012-11-11 15:00:00',79),(1003,15,'2011-12-11 10:00:00',78),(1003,16,'2010-09-11 10:00:00',96),(1004,1,'2013-11-11 16:00:00',84),(1004,2,'2012-11-10 10:00:00',79),(1004,3,'2011-12-19 10:00:00',76),(1004,4,'2010-11-18 11:00:00',78),(1004,5,'2013-11-11 14:00:00',81),(1004,6,'2012-09-13 15:00:00',90),(1004,7,'2011-10-16 16:00:00',63),(1004,8,'2010-11-11 16:00:00',89),(1004,9,'2013-11-21 10:00:00',67),(1004,10,'2012-11-11 12:00:00',100),(1004,11,'2011-11-11 14:00:00',94),(1004,12,'2010-11-11 15:00:00',65),(1004,13,'2013-11-11 14:00:00',86),(1004,14,'2012-11-11 15:00:00',77),(1004,15,'2011-12-11 10:00:00',82),(1004,16,'2010-09-11 10:00:00',87),(1005,1,'2013-11-11 16:00:00',82),(1005,2,'2012-11-10 10:00:00',92),(1005,3,'2011-12-19 10:00:00',80),(1005,4,'2010-11-18 11:00:00',92),(1005,5,'2013-11-11 14:00:00',97),(1005,6,'2012-09-13 15:00:00',72),(1005,7,'2011-10-16 16:00:00',84),(1005,8,'2010-11-11 16:00:00',79),(1005,9,'2013-11-21 10:00:00',76),(1005,10,'2012-11-11 12:00:00',87),(1005,11,'2011-11-11 14:00:00',65),(1005,12,'2010-11-11 15:00:00',67),(1005,13,'2013-11-11 14:00:00',63),(1005,14,'2012-11-11 15:00:00',64),(1005,15,'2011-12-11 10:00:00',99),(1005,16,'2010-09-11 10:00:00',97),(1006,1,'2013-11-11 16:00:00',82),(1006,2,'2012-11-10 10:00:00',73),(1006,3,'2011-12-19 10:00:00',79),(1006,4,'2010-11-18 11:00:00',63),(1006,5,'2013-11-11 14:00:00',97),(1006,6,'2012-09-13 15:00:00',83),(1006,7,'2011-10-16 16:00:00',78),(1006,8,'2010-11-11 16:00:00',88),(1006,9,'2013-11-21 10:00:00',89),(1006,10,'2012-11-11 12:00:00',82),(1006,11,'2011-11-11 14:00:00',70),(1006,12,'2010-11-11 15:00:00',69),(1006,13,'2013-11-11 14:00:00',64),(1006,14,'2012-11-11 15:00:00',80),(1006,15,'2011-12-11 10:00:00',90),(1006,16,'2010-09-11 10:00:00',85),(1007,1,'2013-11-11 16:00:00',87),(1007,2,'2012-11-10 10:00:00',63),(1007,3,'2011-12-19 10:00:00',70),(1007,4,'2010-11-18 11:00:00',74),(1007,5,'2013-11-11 14:00:00',79),(1007,6,'2012-09-13 15:00:00',83),(1007,7,'2011-10-16 16:00:00',86),(1007,8,'2010-11-11 16:00:00',76),(1007,9,'2013-11-21 10:00:00',65),(1007,10,'2012-11-11 12:00:00',87),(1007,11,'2011-11-11 14:00:00',69),(1007,12,'2010-11-11 15:00:00',69),(1007,13,'2013-11-11 14:00:00',90),(1007,14,'2012-11-11 15:00:00',84),(1007,15,'2011-12-11 10:00:00',95),(1007,16,'2010-09-11 10:00:00',92),(1008,1,'2013-11-11 16:00:00',96),(1008,2,'2012-11-10 10:00:00',62),(1008,3,'2011-12-19 10:00:00',97),(1008,4,'2010-11-18 11:00:00',84),(1008,5,'2013-11-11 14:00:00',86),(1008,6,'2012-09-13 15:00:00',72),(1008,7,'2011-10-16 16:00:00',67),(1008,8,'2010-11-11 16:00:00',83),(1008,9,'2013-11-21 10:00:00',86),(1008,10,'2012-11-11 12:00:00',60),(1008,11,'2011-11-11 14:00:00',61),(1008,12,'2010-11-11 15:00:00',68),(1008,13,'2013-11-11 14:00:00',99),(1008,14,'2012-11-11 15:00:00',77),(1008,15,'2011-12-11 10:00:00',73),(1008,16,'2010-09-11 10:00:00',78),(1009,1,'2013-11-11 16:00:00',67),(1009,2,'2012-11-10 10:00:00',70),(1009,3,'2011-12-19 10:00:00',75),(1009,4,'2010-11-18 11:00:00',92),(1009,5,'2013-11-11 14:00:00',76),(1009,6,'2012-09-13 15:00:00',90),(1009,7,'2011-10-16 16:00:00',62),(1009,8,'2010-11-11 16:00:00',68),(1009,9,'2013-11-21 10:00:00',70),(1009,10,'2012-11-11 12:00:00',83),(1009,11,'2011-11-11 14:00:00',88),(1009,12,'2010-11-11 15:00:00',65),(1009,13,'2013-11-11 14:00:00',91),(1009,14,'2012-11-11 15:00:00',99),(1009,15,'2011-12-11 10:00:00',65),(1009,16,'2010-09-11 10:00:00',83),(1010,1,'2013-11-11 16:00:00',83),(1010,2,'2012-11-10 10:00:00',87),(1010,3,'2011-12-19 10:00:00',89),(1010,4,'2010-11-18 11:00:00',99),(1010,5,'2013-11-11 14:00:00',91),(1010,6,'2012-09-13 15:00:00',96),(1010,7,'2011-10-16 16:00:00',72),(1010,8,'2010-11-11 16:00:00',72),(1010,9,'2013-11-21 10:00:00',98),(1010,10,'2012-11-11 12:00:00',73),(1010,11,'2011-11-11 14:00:00',68),(1010,12,'2010-11-11 15:00:00',62),(1010,13,'2013-11-11 14:00:00',67),(1010,14,'2012-11-11 15:00:00',69),(1010,15,'2011-12-11 10:00:00',71),(1010,16,'2010-09-11 10:00:00',66),(1011,1,'2013-11-11 16:00:00',62),(1011,2,'2012-11-10 10:00:00',72),(1011,3,'2011-12-19 10:00:00',96),(1011,4,'2010-11-18 11:00:00',64),(1011,5,'2013-11-11 14:00:00',89),(1011,6,'2012-09-13 15:00:00',91),(1011,7,'2011-10-16 16:00:00',95),(1011,8,'2010-11-11 16:00:00',96),(1011,9,'2013-11-21 10:00:00',89),(1011,10,'2012-11-11 12:00:00',73),(1011,11,'2011-11-11 14:00:00',82),(1011,12,'2010-11-11 15:00:00',98),(1011,13,'2013-11-11 14:00:00',66),(1011,14,'2012-11-11 15:00:00',69),(1011,15,'2011-12-11 10:00:00',91),(1011,16,'2010-09-11 10:00:00',69),(1012,1,'2013-11-11 16:00:00',86),(1012,2,'2012-11-10 10:00:00',66),(1012,3,'2011-12-19 10:00:00',97),(1012,4,'2010-11-18 11:00:00',69),(1012,5,'2013-11-11 14:00:00',70),(1012,6,'2012-09-13 15:00:00',74),(1012,7,'2011-10-16 16:00:00',91),(1012,8,'2010-11-11 16:00:00',97),(1012,9,'2013-11-21 10:00:00',84),(1012,10,'2012-11-11 12:00:00',82),(1012,11,'2011-11-11 14:00:00',90),(1012,12,'2010-11-11 15:00:00',91),(1012,13,'2013-11-11 14:00:00',91),(1012,14,'2012-11-11 15:00:00',97),(1012,15,'2011-12-11 10:00:00',85),(1012,16,'2010-09-11 10:00:00',90),(1013,1,'2013-11-11 16:00:00',73),(1013,2,'2012-11-10 10:00:00',69),(1013,3,'2011-12-19 10:00:00',91),(1013,4,'2010-11-18 11:00:00',72),(1013,5,'2013-11-11 14:00:00',76),(1013,6,'2012-09-13 15:00:00',87),(1013,7,'2011-10-16 16:00:00',61),(1013,8,'2010-11-11 16:00:00',77),(1013,9,'2013-11-21 10:00:00',83),(1013,10,'2012-11-11 12:00:00',99),(1013,11,'2011-11-11 14:00:00',91),(1013,12,'2010-11-11 15:00:00',84),(1013,13,'2013-11-11 14:00:00',98),(1013,14,'2012-11-11 15:00:00',74),(1013,15,'2011-12-11 10:00:00',92),(1013,16,'2010-09-11 10:00:00',90),(1014,1,'2013-11-11 16:00:00',64),(1014,2,'2012-11-10 10:00:00',81),(1014,3,'2011-12-19 10:00:00',79),(1014,4,'2010-11-18 11:00:00',74),(1014,5,'2013-11-11 14:00:00',65),(1014,6,'2012-09-13 15:00:00',88),(1014,7,'2011-10-16 16:00:00',86),(1014,8,'2010-11-11 16:00:00',77),(1014,9,'2013-11-21 10:00:00',86),(1014,10,'2012-11-11 12:00:00',85),(1014,11,'2011-11-11 14:00:00',86),(1014,12,'2010-11-11 15:00:00',75),(1014,13,'2013-11-11 14:00:00',89),(1014,14,'2012-11-11 15:00:00',79),(1014,15,'2011-12-11 10:00:00',73),(1014,16,'2010-09-11 10:00:00',68),(1015,1,'2013-11-11 16:00:00',99),(1015,2,'2012-11-10 10:00:00',60),(1015,3,'2011-12-19 10:00:00',60),(1015,4,'2010-11-18 11:00:00',75),(1015,5,'2013-11-11 14:00:00',78),(1015,6,'2012-09-13 15:00:00',78),(1015,7,'2011-10-16 16:00:00',84),(1015,8,'2010-11-11 16:00:00',95),(1015,9,'2013-11-21 10:00:00',93),(1015,10,'2012-11-11 12:00:00',79),(1015,11,'2011-11-11 14:00:00',74),(1015,12,'2010-11-11 15:00:00',65),(1015,13,'2013-11-11 14:00:00',63),(1015,14,'2012-11-11 15:00:00',74),(1015,15,'2011-12-11 10:00:00',67),(1015,16,'2010-09-11 10:00:00',65),(1016,1,'2013-11-11 16:00:00',97),(1016,2,'2012-11-10 10:00:00',90),(1016,3,'2011-12-19 10:00:00',77),(1016,4,'2010-11-18 11:00:00',75),(1016,5,'2013-11-11 14:00:00',75),(1016,6,'2012-09-13 15:00:00',97),(1016,7,'2011-10-16 16:00:00',96),(1016,8,'2010-11-11 16:00:00',92),(1016,9,'2013-11-21 10:00:00',62),(1016,10,'2012-11-11 12:00:00',83),(1016,11,'2011-11-11 14:00:00',98),(1016,12,'2010-11-11 15:00:00',94),(1016,13,'2013-11-11 14:00:00',62),(1016,14,'2012-11-11 15:00:00',97),(1016,15,'2011-12-11 10:00:00',76),(1016,16,'2010-09-11 10:00:00',82),(1017,1,'2013-11-11 16:00:00',100),(1017,2,'2012-11-10 10:00:00',88),(1017,3,'2011-12-19 10:00:00',86),(1017,4,'2010-11-18 11:00:00',73),(1017,5,'2013-11-11 14:00:00',96),(1017,6,'2012-09-13 15:00:00',64),(1017,7,'2011-10-16 16:00:00',81),(1017,8,'2010-11-11 16:00:00',66),(1017,9,'2013-11-21 10:00:00',76),(1017,10,'2012-11-11 12:00:00',95),(1017,11,'2011-11-11 14:00:00',73),(1017,12,'2010-11-11 15:00:00',82),(1017,13,'2013-11-11 14:00:00',85),(1017,14,'2012-11-11 15:00:00',68),(1017,15,'2011-12-11 10:00:00',99),(1017,16,'2010-09-11 10:00:00',76);

/*Table structure for table `student` */

DROP TABLE IF EXISTS `student`;

CREATE TABLE `student` (
  `StudentNo` int(4) NOT NULL COMMENT '学号',
  `LoginPwd` varchar(20) DEFAULT NULL,
  `StudentName` varchar(20) DEFAULT NULL COMMENT '学生姓名',
  `Sex` tinyint(1) DEFAULT NULL COMMENT '性别,取值0或1',
  `GradeId` int(11) DEFAULT NULL COMMENT '年级编号',
  `Phone` varchar(50) NOT NULL COMMENT '联系电话,允许为空,即可选输入',
  `Address` varchar(255) NOT NULL COMMENT '地址,允许为空,即可选输入',
  `BornDate` datetime DEFAULT NULL COMMENT '出生时间',
  `Email` varchar(50) NOT NULL COMMENT '邮箱账号,允许为空,即可选输入',
  `IdentityCard` varchar(18) DEFAULT NULL COMMENT '身份证号',
  PRIMARY KEY (`StudentNo`),
  UNIQUE KEY `IdentityCard` (`IdentityCard`),
  KEY `Email` (`Email`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

/*Data for the table `student` */

insert  into `student`(`StudentNo`,`LoginPwd`,`StudentName`,`Sex`,`GradeId`,`Phone`,`Address`,`BornDate`,`Email`,`IdentityCard`) values (1000,'111111','周丹',1,1,'13500000001','北京海淀区中关村大街1号','1986-12-11 00:00:00','test1@qq.com','450323198612111234'),(1001,'123456','周颖',1,2,'13500000002','河南洛阳','1981-12-31 00:00:00','test1@qq.com','450323198112311234'),(1002,'111111','杨文瑞',1,1,'13500000003','天津市和平区','1986-11-30 00:00:00','test1@qq.com','450323198611301234'),(1003,'123456','韩萌',1,3,'13500000004','上海卢湾区','1986-12-31 00:00:00','test1@qq.com','450323198612314234'),(1004,'123456','刘丽侠',1,4,'13500000005','北京市通州','1989-12-31 00:00:00','test1@qq.com','450323198612311244'),(1005,'123456','姜嘉航',2,1,'13500000006','广西桂林市灵川','1986-12-31 00:00:00','test1@qq.com','450323198612311214'),(1006,'123456','郑嘉祥',2,4,'13500000007','地址不详','1986-12-31 00:00:00','test1@qq.com','450323198612311134'),(1007,'111111','刘洋',1,1,'13500000008','北京东城区','1986-12-31 00:00:00','test1@qq.com','450323198612311133'),(1008,'111111','刘洋洋',1,1,'13500000009','河南洛阳','1986-12-31 00:00:00','test1@qq.com','450323198612311221'),(1009,'123456','刘毅',1,2,'13500000011','安徽','1986-12-31 00:00:00','test1@qq.com','450323198612311231'),(1010,'111111','赵杰',1,1,'13500000012','河南洛阳','1986-12-31 00:00:00','test1@qq.com','450323198612311044'),(1011,'111111','赵成',1,1,'13500000013','北京海淀区中关村大街*号','1984-12-31 00:00:00','test1@qq.com','450323198412311234'),(1012,'123456','刘恒',2,3,'13500000014','广西南宁中央大街','1986-12-31 00:00:00','test1@qq.com','450323198612311334'),(1013,'123456','张伟奇',2,1,'13500000015','上海卢湾区','1986-12-31 00:00:00','test1@qq.com','450323198612311534'),(1014,'123456','牛恩来',2,4,'13500000016','北京海淀区中关村大街*号','1986-12-31 00:00:00','test1@qq.com','450323198612311264'),(1015,'123456','马辉',1,4,'13500000017','广西桂林市灵川','1976-12-31 00:00:00','test1@qq.com','450323197612311234'),(1016,'111111','陈勉',1,1,'13500000018','上海卢湾区','1986-12-31 00:00:00','test1@qq.com','450323198612311251'),(1017,'123456','赵宇航',2,3,'13500000019','北京长安街1号','1981-09-10 00:00:00','test1@qq.com','450323198109108311');

/*Table structure for table `subject` */

DROP TABLE IF EXISTS `subject`;

CREATE TABLE `subject` (
  `SubjectNo` int(11) NOT NULL AUTO_INCREMENT COMMENT '课程编号',
  `SubjectName` varchar(50) DEFAULT NULL COMMENT '课程名称',
  `ClassHour` int(4) DEFAULT NULL COMMENT '学时',
  `GradeID` int(4) DEFAULT NULL COMMENT '年级编号',
  PRIMARY KEY (`SubjectNo`)
) ENGINE=InnoDB AUTO_INCREMENT=18 DEFAULT CHARSET=utf8;

/*Data for the table `subject` */

insert  into `subject`(`SubjectNo`,`SubjectName`,`ClassHour`,`GradeID`) values (1,'高等数学-1',110,1),(2,'高等数学-2',110,2),(3,'高等数学-3',100,3),(4,'高等数学-4',130,4),(5,'C语言-1',110,1),(6,'C语言-2',110,2),(7,'C语言-3',100,3),(8,'C语言-4',130,4),(9,'JAVA第一学年',110,1),(10,'JAVA第二学年',110,2),(11,'JAVA第三学年',100,3),(12,'JAVA第四学年',130,4),(13,'数据库结构-1',110,1),(14,'数据库结构-2',110,2),(15,'数据库结构-3',100,3),(16,'数据库结构-4',130,4),(17,'C#基础',130,1);

/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;

4.2 指定查询字段

-- 查询指定字段
-- 查询全部的学生
SELECT * FROM `student`;
-- 查询全部的成绩
SELECT  * FROM  `result`;

-- 查询指定字段
SELECT `StudentNo`,`StudentName` FROM `student`;
-- 别名 , 给结果起一个名字  AS  可以给字段起别名,也可以给表起别名
SELECT `StudentNo` AS '学号',`StudentName` AS '学员姓名' FROM `student` AS s;

-- 函数  Concat(a,b)
SELECT CONCAT('姓名:',`studentname`) AS 新名字 FROM student;

语法:select 字段 ... from 表

注意: 有的时候,列的名字不是见名知意,可以起别名来进行

-- 去重复 distinct

-- 查询有哪些同学参加了考试
SELECT * FROM `result`;  -- 查询全部的成绩
-- 查询哪些同学参加了考试
SELECT `studentno` FROM result;
-- 发现重复数据,我们可以去重
SELECT DISTINCT `studentno` FROM `result`;

数据库的列:

-- 查看系统的版本(函数)
SELECT VERSION();

SELECT 100*3-1 AS 计算结果 -- 用来计算(计算表达式)

SELECT @@auto_increment_increment; -- 查询自增的步长(变量)
-- 学院考试成绩加一分查看
SELECT `StudentNo`,`StudentResult`+1 AS '提分后' FROM `result`;

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

select 表达式 from 表

4.3where条件子句

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

逻辑运算符

搜索的条件由一个或者是多个表达式组成! 结果为布尔值

运算符语法描述
and &&a and b a&&b逻辑与,两个都为真,结果为真
or ||a or b a||b逻辑或,两个都为假,结果为假
Not !not a !a逻辑非,真为假,假为真

尽量使用英文符号

-- =========where=============
SELECT `studentno`,`studentresult` FROM `result`;
-- 查询成绩在95 到 100 分之间的学生
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult`>95 AND `studentresult`<100;

-- 模糊查询(区间范围)
SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentresult` BETWEEN 95 AND 100;

-- 除了1000号学生之外的信息

SELECT `studentno`,`studentresult` FROM `result`
WHERE `studentno` != 1000;  -- not `studentno`=1000

模糊查询: 本质是比较运算符

运算符语法描述
IS NULLa is null如果操作符为null,则结果为真
IS NOT NULLa is not null如果操作符为null,则结果为假
BETWEENA BETWEEN B AND C若a在b和c之间,则结果为真
Likea like b如果a 能匹配到b,则结果为真
ina in (a1,a2,a3,…)如果a在a1和。。。中的一个,那么就为真

小红like红

-- =============模糊查询=================
-- 查询名字姓刘的同学
-- like结合%(代表0到任意个字符) ——(一个字符)
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE '刘%';

-- 查询名字姓刘的同学,名字后面只有一个字的
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE '刘_';

-- 查询名字姓刘的同学,名字后面只有两个字的
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE '刘__';

-- 查询名字中间有嘉字的同学_%嘉%_
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentname` LIKE '_%嘉%_';

-- ================in==============
-- 查询1001,1002,1003的学生
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentno` IN (1001,1002,1003);

-- 查询在安徽的学生  in 是具体的一个或者是多个值
SELECT `studentno`,`studentname` FROM `student`
WHERE `address` IN ('安徽','河南','洛阳');



-- ==========null 和 not null================
-- 插叙地址为null ''的同学
SELECT `studentno`,`studentname` FROM `student`
WHERE `address`='' OR `address` IS NULL;

-- 查询有出生日期的同学
SELECT `studentno`,`studentname` FROM `student`
WHERE `BornDate` IS NOT NULL;

-- 查询没有出生日期的同学
SELECT `studentno`,`studentname` FROM `student`
WHERE `BornDate` IS NULL;

注意: 在是不是null 的时候要用is,不是等于

4.4联表查询

JOIN对比

在这里插入图片描述

在这里插入图片描述

-- ============联表查询Join=================

-- 查询参加考试的同学(学号,姓名,科目编号,分数)
/*
分析需求: 分析需求的字段来自那些表
确定使用哪种连接查询
确定一个交叉点(这两个表中那个数据是相同的)
判断的条件: 学生表中的`studentno` == 成绩表中的 `studentno`
*/

-- join(连接的表) on(判断的条件) 连接查询
-- where 等值查询

-- inner join   as 可以省略
SELECT s.`studentno`,`studentname`,`subjectno`,`studentresult` 
FROM student AS `s`
INNER JOIN result AS `r`
WHERE r.`StudentNo`=s.`StudentNo`;

-- right join
SELECT `s`.`studentno`,`s`.`studentname`,`r`.`subjectno`,`r`.`studentresult` 
FROM student AS `s`
RIGHT JOIN result AS `r`
-- WHERE r.`StudentNo`=s.`StudentNo`;
ON `r`.`StudentNo`=`s`.`StudentNo`;



-- left join
SELECT `s`.`studentno`,`s`.`studentname`,`r`.`subjectno`,`r`.`studentresult` 
FROM student AS `s`
LEFT JOIN result AS `r`
-- WHERE r.`StudentNo`=s.`StudentNo`;
ON `r`.`StudentNo`=`s`.`StudentNo`;

-- 查询缺考的同学
SELECT `s`.`studentno`,`s`.`studentname`,`r`.`subjectno`,`r`.`studentresult` 
FROM student AS `s`
LEFT JOIN result AS `r`
-- WHERE r.`StudentNo`=s.`StudentNo`;
ON `r`.`StudentNo`=`s`.`StudentNo`
WHERE `r`.`studentresult` IS NULL;

-- 查询了参加了考试的同学的信息(学号,姓名,科目名称,分数)

/*
分析需求: 分析需求的字段来自那些表  student result subject
确定使用哪种连接查询
确定一个交叉点(这两个表中那个数据是相同的)
判断的条件: 学生表中的`studentno` == 成绩表中的 `studentno`
*/
SELECT `s`.`studentno` AS '学号',`studentname` AS '姓名',
`subjectname` AS '科目名称',`studentresult` AS '成绩'
FROM `student` AS `s` RIGHT JOIN `result` AS `r`
ON `s`.`studentno` = `r`.`studentno`
INNER JOIN `subject` AS `sub`
ON `sub`.`subjectno` = `r`.`subjectno`;

-- 我要查那些数据 select ....
-- 从那几个表中查询 from 表 xxxx join 连接的表  on  交叉的条件
-- 假设存在多张表查询,慢慢来,先查询两张表,然后再慢慢查询

-- from a left join b
-- from a right join b
操作描述
inner join如果表中至少有一个匹配,就返回行
left join即使右表中没有匹配,也会从左表中返回所有的值
right join会从右表中返回所有的值,即使左表中没有匹配

自连接

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

父类:

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

子类

pidcategoryidcategoryname
34数据库
28办公信息
36web开发
57美术设计

操作: 查询父类对用子类关系

父类子类
信息技术办公信息
软件开发数据库
软件开发web开发
美术设计ps技术
-- =============自连接====================
CREATE TABLE `category`(
`categoryid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '主题id',
`pid` INT(10) NOT NULL COMMENT '父id',
`categoryname` VARCHAR(50)  NOT NULL COMMENT '主题名字',
PRIMARY KEY(`categoryid`)
)ENGINE=INNODB AUTO_INCREMENT=9 CHARSET=utf8
INSERT INTO `category` (`categoryid`,`pid`,`categoryname`)
VALUES('2','1','信息技术'),
('3','1','软件开发'),
('4','3','数据库'),
('5','1','美术设计'),
('6','3','web开发'),
('7','5','ps技术'),
('8','2','办公信息');



-- 查询父子信息 把一张表拆成两张一样的表

SELECT `a`.`categoryname` AS '父栏目',`b`.`categoryname` AS '子栏目'
FROM `category` AS `a` , `category` AS `b`
WHERE `a`.`categoryid` = `b`.`pid`;

4.5分页和排序

排序

-- =================分页和排序 order by===================
-- 排序 : 升序ASC 和降序 DESC
-- order by 通过那个字段进行排序,怎么拍 
-- 查询了参加了数据库结构-1考试的同学的信息(学号,姓名,科目名称,分数)  根据成绩排序
SELECT `s`.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` AS `s` INNER JOIN `result` AS `r`
ON `s`.`studentno` = `r`.`studentno`
INNER JOIN `subject` AS `sub`
ON `r`.`subjectno` = `sub`.`subjectno`
WHERE `sub`.`subjectname` = '数据库结构-1'
ORDER BY `studentresult` ASC;

分页

-- 100万
-- 分页
-- 环境: 数据库压力  给人的体验更好   瀑布流(图片)
-- 分页, 每页只显示五条数据
-- 网页: 当前页  总的页数  页面大小
-- limit 当前页  页面的大小
-- LIMIT 1,5; -- 2到6调数据
-- limit 0,5;-- 1到5调数据
SELECT `s`.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` AS `s` INNER JOIN `result` AS `r`
ON `s`.`studentno` = `r`.`studentno`
INNER JOIN `subject` AS `sub`
ON `r`.`subjectno` = `sub`.`subjectno`
WHERE `sub`.`subjectname` = '数据库结构-1'
ORDER BY `studentresult` ASC
LIMIT 1,5; -- 1到5调数据


-- 第一页   limit 0,5    (i-1)*5
-- 第二页   limit 5,5    (i-1)*5
-- 第三页   limit 10,5
-- 第二页   limit 0,5    (n-1)*pagesize,pagesize
-- pagesize 页面的大小  (n-1)*pagesize起始值  n代表当前页
-- 总数 [n代表当前页]  
-- 总页数=总数/页面的大小

语法:limit(查询起始下标 , pagesize)

小练习:

-- 查询java第一学年 课程成绩排名前十的学生  并且分数大于80的学生的信息
-- (学号,姓名,课程名称,分数)

SELECT `s`.`studentno`,`studentname`,`subjectname`,`studentresult`
FROM `student` AS `s` INNER JOIN `result` AS `r`
ON `s`.`studentno` = `r`.`studentno`
INNER JOIN `subject` AS `sub`
ON `sub`.`subjectno` = `r`.`subjectno`
WHERE `subjectname` = 'JAVA第一学年' AND `studentresult` > 80
ORDER BY `studentresult` DESC
LIMIT 0,10;

4.6子查询

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

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

where (select * from …)

-- =============where============
-- 查询数据库结构-1的所有考试结果(学号 , 科目编号 , 成绩) ,降序排列
-- 方式一
SELECT `studentno`,`sub`.`subjectno`,`studentresult`
FROM `result` AS r 
INNER JOIN `subject` AS `sub`
ON `sub`.`subjectno` = `r`.`subjectno`
WHERE `sub`.`subjectname` = '数据库结构-1'
ORDER BY `studentresult` DESC;
-- 方式二: (使用子查询)(由里及外)
SELECT `studentno`,`subjectno`,`studentresult`
FROM `result`
WHERE `subjectno` = (
SELECT `subjectno` FROM `subject`
WHERE `subjectname` = '数据库结构-1')
ORDER BY `studentresult` DESC;
-- 分数不小于80分的学生的学号和姓名

SELECT DISTINCT `s`.`studentno`,`studentname`
FROM `student` AS `s` INNER JOIN
`result` AS `r`
ON `s`.`studentno` = `r`.`studentno`
WHERE `studentresult` > 80;

-- 在这个基础上增加一个高等数学-2  查询高等数学-2的编号
SELECT DISTINCT `s`.`studentno`,`studentname`
FROM `student` AS `s` INNER JOIN
`result` AS `r`
ON `s`.`studentno` = `r`.`studentno`
WHERE `studentresult` > 80 
AND `subjectno` = (
SELECT `subjectno` 
FROM `subject` 
WHERE `subjectname` = '高等数学-2'
); 


-- 查询课程为高等数学-2 且分数不小于80分的同学的学号和姓名
SELECT `s`.`studentno`,`studentname`
FROM `student` AS `s` 
INNER JOIN `result` AS `r`
ON `s`.`studentno` = `r`.`studentno`
INNER JOIN `subject` AS `sub`
ON `sub`.`subjectno` = `r`.`subjectno`
WHERE `studentresult` > 80 
AND `sub`.`subjectname` = '高等数学-2';
-- 嵌套再改造(过程还是由里及外) 
SELECT `studentno`,`studentname` FROM `student`
WHERE `studentno` IN (
SELECT `studentno` 
FROM `result`
WHERE `studentresult`>80 
AND `subjectno` = (SELECT `subjectno` 
FROM `subject` 
WHERE `subjectname` = '高等数学-2')
 );
 
 -- 查询c语言-1 前五名同学的成绩信息(学号 姓名 分数)
-- 使用子查询
SELECT `s`.`studentno`,`studentname`,`studentresult`
FROM `student` AS `s` 
INNER JOIN `result` AS `r`
WHERE`s`.`studentno` = `r`.`studentno`	  
AND `subjectno` = (
SELECT `subjectno`
FROM `subject`
WHERE `subjectname` = 'c语言-1'
)
ORDER BY `studentresult` DESC
LIMIT 0,5;

注意where子查询是比较快的,因为它不负责连接

4.7分组和过滤

-- 查询不同课程的平均分 最高分 最低分  平均分大于80分
-- 核心: 分组进行查询
SELECT `subjectname` , AVG(`studentresult`) AS '平均分',
MAX(`studentresult`) AS '最高分',MIN(`studentresult`) AS '最低分'
FROM `result` AS `r` INNER JOIN `subject` AS `sub`
ON `r`.`SubjectNo` = `sub`.`SubjectNo`
GROUP BY `r`.`SubjectNo`
HAVING 平均分 >= 80; -- 通过什么字段进行分组

4.8select小结

淘宝每个人登录的时候的首页都是不同的

5.MySQL函数

官网 :https://dev.mysql.com/doc/refman/5.7/en/sql-function-reference.html

5.1常用函数(并不常用)

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


-- 字符串函数
SELECT CHAR_LENGTH('即使再小的帆也能远航');  -- 字符长长度
SELECT CONCAT('我','爱','你们');  -- 拼接字符串
-- 查询,替换  从某个位置开始替换某个长度
SELECT INSERT('我爱编程helloworld',1,2,'超级热爱'); 
-- 转大写或者是小写字母
SELECT LOWER('Kuangshen');
SELECT UPPER('Kuangshen');
-- 查看是第几个字符
SELECT INSTR('kuangshen','h'); 
-- 替换指定的字符串
SELECT REPLACE('坚持就能成功','坚持','努力'); 
-- 截取指定的字符串(原字符串,截取的位置,截取的长度)
SELECT SUBSTR('狂神坚持就能成功',4);
-- 反转字符串 
SELECT REVERSE('狂神坚持就能成功');

-- 查询姓周的同学, 名字周改为邹
SELECT REPLACE(`studentname`,'周','邹') FROM `student`
WHERE `studentname` LIKE '周%';
-- 时间和日期函数(记住)
-- 获取当前日期
SELECT CURRENT_DATE();  
SELECT CURDATE();
-- 获取当前的时间
SELECT NOW();
-- 获取本地时间
SELECT LOCALTIME();
-- 系统时间
SELECT SYSDATE();
SELECT YEAR(NOW());
SELECT MONTH(NOW());
SELECT DAY(NOW());
SELECT HOUR(NOW());
SELECT MINUTE(NOW());
SELECT SECOND(NOW());

-- 系统当前的用户
SELECT SYSTEM_USER();
SELECT USER();
SELECT VERSION();

5.2聚合函数

函数名称描述
COUNT()计数
SUM()求和
AVG()平均数
MAX()最大值
MIN()最小值
-- ==========聚合函数============
-- count(指定列)  会忽略所有的null值
-- count(*) 包括了所有的列,相当于行数,在统计结果的时候,不会忽略值为null
-- count(1)  包括了忽略所有列,用1代表代码行,不会忽略列值为null
-- 列为主键 count(列名) 比count(1)快
-- 想查询一个表中有多少记录count()
SELECT COUNT(`studentname`) FROM `student`;
SELECT COUNT(*) FROM `student`;  -- 本质: 计算行数
SELECT COUNT(1) FROM `student`;

SELECT SUM(`studentresult`) AS '总和' FROM `result`;
SELECT AVG(`studentresult`) AS '平均数' FROM `result`;
SELECT MAX(`studentresult`) AS '最高分' FROM `result`;
SELECT MIN(`studentresult`) AS '最低分' FROM `result`;

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

什么是MD5:

  • 主要是增强算法的复杂度和不可逆性
  • MD5不可逆,具体的值的MD5是一样的
  • MD5破解网站的原理,背后有一个字典,MD5加密后的值 加密的前值
-- ============测试MD5加密========
CREATE TABLE `testmd5`(
`id` INT(4) NOT NULL,
`name` VARCHAR(20) NOT NULL,
`pwd` VARCHAR(50) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
-- 明文密码
INSERT INTO `testmd5` VALUES 
(1,'张三','123456'),
(2,'李四','123456'),
(3,'王五','123456'),
(4,'陈留红','123456'),
(5,'孙子','123456');
-- 加密
UPDATE `testmd5` SET pwd=MD5(pwd) WHERE id=1;
-- 加密全部的密码
UPDATE `testmd5` SET pwd=MD5(pwd);
-- 插入的时候加密
INSERT INTO `testmd5` VALUES(6,'杜志明',MD5('123456'));
-- 如何校验  : 将用户传递进来的密码进行md5加密,然后比对加密的值
SELECT * FROM `testmd5` WHERE `name`='陈留红' AND pwd=MD5('123456');

6.事务

6.1什么是事务

要么都成功,要么都失败

一一一一一一一一一一一一一一一一

1.sql执行 a给b转账 a 1000 ----》 200 b

2.sql执行 b收到a的钱 a 800 ----》 b 400

一一一一一一一一一一一一一一一一

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

innodb,在最新版的myisam也是支持的

事务原则: ACID 原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)、持久性 (Transaction) (脏读,幻读 …)

原子性 Atomicity

要么都成功,要么都失败

一致性 Consistency

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

持久性 Transaction

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

隔离性 Isolation

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

隔离所导致的一些问题:

  • 脏读: 指一个是务读取了另一个事务未提交的数据

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

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

事务

-- =========事务========
-- mysql是默认开启事务自动提交的
SET autocommit = 0; -- 关闭

-- 手动处理事务

-- 事务开启
-- 标志事务的开始,从这个之后的sql都在同一个事务内
START TRANSACTION;

 
-- 提交 持久化
COMMIT;
-- 回滚  回到原来的样子
ROLLBACK;
-- 事务结束
SET autocommit = 1; -- 开启

SAVEPOINT 保存点名;  -- 保存点名 设置一个事务的保存点
ROLLBACK TO SAVEPOINT 保存点名; -- 回滚到保存点位置
RELEASE SAVEPOINT 保存点名; -- 删除保存点

事务流程图

在这里插入图片描述

模拟场景

-- 转账
CREATE DATABASE shop CHARACTER SET utf8 
COLLATE utf8_general_ci;
USE shop;
CREATE TABLE `account`(
`id` INT(3) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) NOT NULL,
`money` DECIMAL(9,2) NOT NULL,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8
SELECT * FROM `account`;
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';  --A减500
UPDATE `account` SET `money` = `money`+500 WHERE `name`='B';  --B加500

COMMIT; -- 提交事务

ROLLBACK; -- 回滚

SET autocommit=1; -- 恢复默认值

注意: 这里是手动点的,在java中使用的是try catch,在执行失败的时候自己会回滚

7.索引

MySQL官方对索引的定义为:索引(Index) 是帮助MySQL高效获取数据的数据结构

提取句子主干,就可以得到索引的本质;索引是数据结构

7.1索引的分类

在一个表中,主键索引只能有一个,唯一索引可以有多个

  • 主键索引 PRIMARY KEY
    • 唯一的标识,主键不可重复,只能有一个主键索引
  • 唯一索引 UNIQUE KEY
    • 避免重读的列出现,唯一索引可以重复, 多个列都可以标识唯一索引
  • 常规索引 KEY/index
    • 默认的,index关键字或者是key关键字设置
  • 全文索引 FUllText
    • 在特定的数据库引擎下才有 myisam
    • 快速定位数据

基础语法

-- 索引的使用
-- 在创建表的时候给字段增加索引
-- 创建完毕后增加索引
-- 显示所有的索引信息
USE `school`;
SHOW INDEX FROM `student`;
-- 增加一个索引
-- ALTER  TABLE 数据库的表 ADD FULLTEXT INDEX `索引名`(`索引的列`);
ALTER  TABLE `school`.`student` ADD FULLTEXT INDEX `studentname`(`studentname`);
-- EXPLAIN 分析sql执行的状况

EXPLAIN SELECT * FROM `student`; -- 非全文索引

EXPLAIN SELECT * FROM `student` WHERE MATCH(`studentname`) AGAINST('刘');

7.2测试索引

CREATE TABLE `app_user`(
`id` BIGINT(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '用户的id',
`name` VARCHAR(20) DEFAULT '' COMMENT '用户的名字',
`email` VARCHAR(50) NOT NULL COMMENT '用户邮箱',
`phone` VARCHAR(20) DEFAULT '' COMMENT '手机号',
`gender` TINYINT(4) UNSIGNED DEFAULT '0' COMMENT '性别(0为男,1为女)',
`password` VARCHAR(100) NOT NULL COMMENT '密码',
`age` TINYINT(4) DEFAULT '0' COMMENT '年龄',
`create_time` DATETIME DEFAULT CURRENT_TIMESTAMP,
`update_time` TIMESTAMP NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8mb4 COMMENT 'app用户表';


-- 插入100万条数据  49.011秒插入1000000调数据
-- 必须写,当做标志
DELIMITER $$ 
CREATE FUNCTION mock_data()
RETURNS INT DETERMINISTIC
BEGIN
	DECLARE num INT DEFAULT 1000000;
	DECLARE i INT DEFAULT 0;
	WHILE i<num DO
		INSERT INTO `app_user`(`name`,`email`,`phone`,`gender`,`password`,`age`) VALUES(CONCAT('用户',i),'1844736251@qq.com',CONCAT('18',FLOOR(RAND()*((999999999-100000000)+100000000))),FLOOR(RAND()*2),UUID(),FLOOR(RAND()*100));
		SET i = i+1;
	END WHILE;
	RETURN i;
END;
SELECT mock_data();

-- 耗时 0.607秒
SELECT * FROM `app_user` WHERE `name` = '用户9999';
-- 耗时0秒
SELECT * FROM `student`;
EXPLAIN SELECT * FROM `app_user` WHERE `name` = '用户9999';
-- 创建索引相当与是使用了树  没加索引相当于是遍历,创建索引相当于是定位
-- id_表名_字段名
-- CREATE INDEX 索引名 ON `表名`(`字段名`);
CREATE INDEX id_app_user_name ON `app_user`(`name`);

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

7.3索引原则

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

索引的数据结构

Hash类型的索引,默认的是BTREE(INNODB的默认的底层的数据结构)

阅读: http://blog.codinglabs.org/articles/theory-of-mysql-index.html

8.权限管理和数据库备份

8.1用户权限

SQL yog 可视化管理

在这里插入图片描述

在这里插入图片描述

SQL命令操作

用户表: mysql.user

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

-- 用户
-- 创建用户  CREATE USER 用户名 IDENTIFIED BY '密码';
CREATE USER timous IDENTIFIED BY '123456';

-- 修改指定用户密码
SET PASSWORD = PASSWORD('123456'); -- 8版本的不行

SET PASSWORD FOR timous = PASSWORD('123456');

-- 重命名  RENAME USER 原来的名字 TO 新的名字;
RENAME USER timous TO timous2;

-- 授予全部的权限  用户授权  除了给别人授权,其他的都能干
-- GRANT ALL PRIVILEGES ON 库.表 TO 用户;
GRANT ALL PRIVILEGES ON *.* TO timous2;

-- 查询权限  
-- 查看指定用户的权限
SHOW GRANTS FOR timous2;
-- root 用户的权限 防止你删库跑路  
SHOW GRANTS FOR root@localhost;

-- 撤销权限
-- REVOKE ALL PRIVILEGES ON 库.表 FROM 用户;
REVOKE ALL PRIVILEGES ON *.* FROM timous2;

-- 删除用户
CREATE USER kuangshen;
DROP USER kuangshen;

8.2数据库备份

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

MySQL数据库备份的方式:

  • 直接拷贝物理文件
  • 使用sqlyog可视化工具中备份导出
  • 命令行导出 mysqldump 命令行使用 是在cmd里面
C:\Users\Administrator>mysqldump -hlocalhost -uroot -p123456 school student >D:/a.sql
mysqldump: [Warning] Using a password on the command line interface can be insecure.

mysqldump -h主机 -u用户名 -p密码 数据库名 表名1 表2 表3 >磁盘位置:/文件名

mysqldump -h主机 -u用户名 -p密码 数据库名 >磁盘位置:/文件名
mysql -uroot -p123456 # 登录
source d:/a.sql就可以了

# 导入 
登录的情况下直接source就可以了(导入数据库不需要切换)
mysql -uroot -p密码 库名< 备份文件

假设你要备份数据库,防止数据丢失,把数据库给朋友,sql文件给别人即可!

9.规范数据库设计
9.1为什么需要设计数据库

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

糟糕的数据库设计

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

良好的数据库设计

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

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

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

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

  • 收集信息,分析需求
    • 用户表(用户登录注销,用户的个人信息,写博客,创建分类)
    • 分类表(文章分类,谁创建的)
    • 文章表(文章的信息)
    • 友链表(友链信息)
    • 自定义表(系统信息,某个关键的字,或者一些主字段) key value
    • 评论表
    • 说说表(发表心情 id content create_time update_time)
  • 标识实体(把需求落实到每个字段)
  • 标识实体之间的关系
    • 写博客 user—》blog
    • 创建分类user----》 category
    • 关注user---->user
    • 友链; link
    • 评论: user—user----blog

9.2三大范式

为什么需要数据规范化:

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

三大范式

目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)

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

原子性: 每一列不可再分

在这里插入图片描述

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

前提: 满足第一范式

每张表只描述一件事

在这里插入图片描述

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

前提: 满足第二范式的条件下消除依赖

在这里插入图片描述

规范数据库的设计

规范性和性能问题:

阿里的规范: 关联的表不能超过三张

  • 考虑商业化的需求和目标(成本和用户的体验) 数据库的性能更加重要
  • 在规范性能问题的时候,适当的去考虑一下规范性
  • 故意给某些表增加一些冗余字段
  • 订单: 商品id—查询商品 可以直接放商品的信息
  • 故意增加一些计算列(每次增加的时候直接增加列加一,从大数据量降低为小数据量的查询: 添加索引)

10.jdbc

10.1数据库驱动

驱动: 声卡,显卡、数据库

在这里插入图片描述

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

10.2JDBC

sun公司为了假话开发人员(对数据库同一)的操作,提供了一个(java操作数据库的)规范,俗称JDBC这些规范的实现由具体的厂商去做

对开发人员来说,我们只需要掌握JDBC的接口的操作即可
在这里插入图片描述

java.sql

javax.sql

还需要导入数据库驱动包mysql-connector-java-8.0.11.jar

10.3第一个JDBC程序

创建测试数据库

CREATE DATABASE `jdbcstudy` CHARACTER SET utf8 COLLATE utf8_general_ci;

USE `jdbcstudy`;

CREATE TABLE `users`(
`id` INT,
`name`VARCHAR(40),
`password` VARCHAR(40),
`email` VARCHAR(60),
`birthday` DATE,
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8


INSERT INTO `users`(id,`name`,`password`,`email`,`birthday`)
VALUES(1,'zhangsan','123456','zs@sina.com','1980-12-04'),
(2,'lisi','123456','lisi@sina.com','1980-12-04'),
(3,'wangwu','123456','wangwu@sina.com','1980-12-04');

SELECT * FROM `users`;

1.创建一个普通项目

2.导入数据库驱动

在这里插入图片描述

3.编写测试代码

package com.tmous.test01;

import java.sql.*;

//我的第一个jdbc程序
public class JdbcFirstDemo {

    public static void main(String[] args) throws ClassNotFoundException, SQLException {
        //1.加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver"); // 固定写法,加载驱动
        //2.用户信息和url
        String url = "jdbc:mysql://127.0.0.1:3306/jdbcstudy?serverTimezone=UTC&amp&useSSL=false";
        String username = "root";
        String password = "123456";
        //3.连接成功
        Connection connection = DriverManager.getConnection(url,username,password);
        //4.执行sql的对象
        Statement statement = connection.createStatement();
        //5.执行sql
        String sql = "SELECT * FROM `users`;";
        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("password="+resultSet.getObject("password"));
            System.out.println("email="+resultSet.getObject("email"));
            System.out.println("birthday="+resultSet.getObject("birthday"));

        }
        //6、释放连接
        resultSet.close();
        statement.close();
        connection.close();

    }
}

步骤总结:

  1. 加载驱动
  2. 连接数据库DriverManager
  3. 获得执行sql的对象Statement
  4. 获得返回的结果集
  5. 释放连接

DriverManager

//1.加载驱动
//  不推荐使用   DriverManager.registerDriver(new Driver()); 本身里面已经注册过来了
Class.forName("com.mysql.cj.jdbc.Driver"); // 固定写法,加载驱动

Connection connection = DriverManager.getConnection(url,username,password); 
//代表数据库
// 可以提交或者是回滚等
//数据库设置自动提交
// 事务提交
// 事务回滚

		connection.commit();
        connection.rollback();
        connection.setAutoCommit();

URL

//2.用户信息和url
String url = "jdbc:mysql://127.0.0.1:3306/jdbcstudy?serverTimezone=UTC&amp&useSSL=false";
// mysql默认是3306   orcle默认是1521  orcle的表就是一个库  sqlserver  1433
String username = "root";
String password = "123456";

Statement 执行sql的类 PreparedStatement

String sql = "SELECT * FROM `users`;"; //编写sql

Statement statement = connection.createStatement();

statement.executeQuery(); // 查询条件返回结果集
statement.execute(); //执行任何操作
statement.executeUpdate();// 更新、插入、删除,都是用这个,返回一个受影响的行数
 statement.executeBatch();//执行多个sql

Result 查询的结果集 : 封装了所有的查询结果

获得指定的数据类型

ResultSet resultSet = statement.executeQuery(sql);//结果集中封装了对应的结果
resultSet.getObject(); // 在不知道列类型的时候使用  知道的话直接使用
resultSet.getString();
resultSet.
    
遍历,指针
//获取结果集
    while(resultSet.next()){

            System.out.println("id="+resultSet.getObject("id"));
            System.out.println("name="+resultSet.getObject("name"));
            System.out.println("password="+resultSet.getObject("password"));
            System.out.println("email="+resultSet.getObject("email"));
            System.out.println("birthday="+resultSet.getObject("birthday"));

        }

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

释放资源

//6、释放连接
resultSet.close();
statement.close();
connection.close();

10.4Statement对象

Jdbc中的statement对象用于向数据库发送sql语句,想完成数据库的增删改查,只需要通过这个对象向数据库发送增删改查语句即可。

Statement对象的executeUpdate方法,用于向数据库发送增删改的sql语句,executeUpdate执行完后,将会返回一个整数(即增删改语句导致了数据库几行数据发生了变化)

Statement.executeQuery方法返回代表查询结果的ResultSet对象

CRUD操作-create

使用executeUpdate(String sql)方法完成数据添加操作,示例操作:

Statement st = conn.createStatement();
String sql = "insert into user() values();";
int num = st.executeUpdate(sql);
if(num>0){
    System.out.println("插入成功!!!");
}

CRUD操作-delete

使用executeUpdate(String sql)方法完成数据删除操作,示例操作:

Statement st = conn.createStatement();
String sql = "delete from user where id=1;";
int num = st.executeUpdate(sql);
if(num>0){
    System.out.println("删除成功!!!");
}

CRUD操作-update

使用executeUpdate(String sql)方法完成数据删除操作,示例操作:

Statement st = conn.createStatement();
String sql = "update user set name='' where name='';";
int num = st.executeUpdate(sql);
if(num>0){
    System.out.println("更新成功!!!");
}

CRUD操作-read

使用executeQuery(String sql)方法完成数据删除操作,示例操作:

Statement st = conn.createStatement();
String sql = "select * from user where id=1;";
ResultSet resultset = st.executeQuery(sql);
while(resultset.next()){
    //根据获取列的数据类型,分别调用rs的响应方法映射到java中
}

代码实现

1.提取工具类

package com.tmous.utils;

import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

public class JdbcUtils {
    private static String driver = null;
    private static String url = null;
    private static String username = null;
    private static String password = null;

    static{

        try {
            InputStream in = JdbcUtils.class.getClassLoader().getResourceAsStream("db.properties");
            Properties properties = new Properties();
            properties.load(in);
            driver = properties.getProperty("driver");
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");
            //1.驱动只需要加载一次
            Class.forName(driver);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        return DriverManager.getConnection(url,username,password);
    }

    //释放连接资源
    public static void release(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();
            }
        }
	}
}


// db.properties
driver=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/jdbcstudy?serverTimezone=UTC&amp&useSSL=false
username=root
password=123456

2.编写增删改的代码

//增
package com.tmous.test01;

import com.tmous.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestInsert {

    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcUtils.getConnection(); //获取数据库连接
            statement = connection.createStatement();
            String sql = "INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`)" +
                    "VALUES (4,'chenliuhong','123456','chenliuhong@sina.com','1980-12-05');";
            int i = statement.executeUpdate(sql);
            if(i>0){
                System.out.println("插入成功!");
            }else{
                System.out.println("插入失败!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection , statement , resultSet);
        }
    }
}
//删
package com.tmous.test01;

import com.tmous.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestDelete {

    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcUtils.getConnection(); //获取数据库连接
            statement = connection.createStatement();
            String sql = "DELETE FROM `users` WHERE `id` = 4;";
            int i = statement.executeUpdate(sql);
            if(i>0){
                System.out.println("删出成功!");
            }else{
                System.out.println("删出失败!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection , statement , resultSet);
        }
    }
}
//改
package com.tmous.test01;

import com.tmous.utils.JdbcUtils;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestUpdate {
    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet resultSet = null;
        try {
            connection = JdbcUtils.getConnection(); //获取数据库连接
            statement = connection.createStatement();
            String sql = "UPDATE `users` SET `name`='陈留红' WHERE `id` = 1;";
            int i = statement.executeUpdate(sql);
            if(i>0){
                System.out.println("修改成功!");
            }else{
                System.out.println("修改失败!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection , statement , resultSet);
        }
    }
}

3.查询的代码

package com.tmous.test01;

import com.tmous.utils.JdbcUtils;

import javax.swing.plaf.nimbus.State;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class TestSelect {

    public static void main(String[] args) {
        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        //获取连接
        try {
            connection = JdbcUtils.getConnection();
            statement = connection.createStatement();
            String sql = "SELECT * FROM `users`;\n";
            rs = statement.executeQuery(sql);
            while(rs.next()){
                System.out.println("id="+rs.getObject("id"));
                System.out.println("name="+rs.getObject("name"));
                System.out.println("password="+rs.getObject("password"));
                System.out.println("email="+rs.getObject("email"));
                System.out.println("birthday="+rs.getObject("birthday"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection , statement , rs);
        }
    }
}

sql注入的问题

sql存在漏洞,会被攻击,导致泄漏 SQL会被拼接

package com.tmous.test01;

import com.tmous.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class SqlProblem {

    public static void main(String[] args) {
        //login("陈留红","123456"); // 正常登录
        login("'or '1=1" , "123456");// 有技巧的输入
    }

    //登录业务
    public static void login(String username , String password){

        Connection connection = null;
        Statement statement = null;
        ResultSet rs = null;
        //获取连接
        try {
            connection = JdbcUtils.getConnection();
            statement = connection.createStatement();
            String sql = "SELECT * FROM `users` where name = '"+username+"'and password = '"+password+"';";
            rs = statement.executeQuery(sql);
            while(rs.next()){
                System.out.println("name="+rs.getObject("name"));
                System.out.println("password="+rs.getObject("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection , statement , rs);
        }
    }
}

在这里插入图片描述

10.5PreparedStatement

PreparedStatement可以防止sql注入,并且效率更好。

增删改代码

// 增
package com.tmous.test01;

import com.tmous.utils.JdbcUtils;

import java.sql.*;

public class TestInserts {

    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            connection = JdbcUtils.getConnection();

            //区别  : 使用问号占位符代替参数
            String sql  = "INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`) VALUES (?,?,?,?,?);";

            st = connection.prepareStatement(sql); //预编译的sql

            //手动给参数赋值
            st.setInt(1,4);
            st.setString(2,"老狗");
            st.setString(3,"123456");
            st.setString(4,"1844736@qq.com");
            st.setDate(5, new java.sql.Date(new java.util.Date().getTime()));

            int i = st.executeUpdate();
            if(i>0){
                System.out.println("插入成功!");
            }else{
                System.out.println("插入失败!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection , st , null);
        }
    }
}
//删
package com.tmous.test01;

import com.tmous.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

//测试
public class TestDeletes {

    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            connection = JdbcUtils.getConnection();

            //区别  : 使用问号占位符代替参数
            String sql  = "delete from `users` where id=?";

            st = connection.prepareStatement(sql); //预编译的sql

            //手动给参数赋值
            st.setInt(1,4);


            int i = st.executeUpdate();
            if(i>0){
                System.out.println("删出成功!");
            }else{
                System.out.println("删出失败!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection , st , null);
        }
    }
}
//改
package com.tmous.test01;

import com.tmous.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestUpdates {

    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            connection = JdbcUtils.getConnection();

            //区别  : 使用问号占位符代替参数
            String sql  = "update `users` set `name` = ? where id = ?";

            st = connection.prepareStatement(sql); //预编译的sql

            //手动给参数赋值
            st.setString(1,"小明");
            st.setInt(2,1);

            int i = st.executeUpdate();
            if(i>0){
                System.out.println("更新成功!");
            }else{
                System.out.println("更新失败!");
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection , st , null);
        }
    }
}

防止sql注入

package com.tmous.test01;

import com.tmous.utils.JdbcUtils;

import java.sql.*;

public class SqlProblems {

    public static void main(String[] args) {
        //login("lisi","123456"); // 正常登录
        login("'or '1=1" , "123456");// 有技巧的输入
    }

    //登录业务
    public static void login(String username , String password){

        Connection connection = null;
        PreparedStatement st =  null;
        ResultSet rs = null;
        //获取连接
        try {
            connection = JdbcUtils.getConnection();
            String sql = "SELECT * FROM `users` where `name` = ? and `password` = ?;";
            st = connection.prepareStatement(sql);

            st.setString(1,username);
            st.setString(2,password);

            rs = st.executeQuery();
            while(rs.next()){
                System.out.println("name="+rs.getObject("name"));
                System.out.println("password="+rs.getObject("password"));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils.release(connection , st , rs);
        }
    }
}

PreparedStatement防止sql注入的本质,把传递进来的参数当做字符,假设其中存在转义字符,就直接忽略,`会被直接转义。

10.7 使用IDEA连接数据库

在这里插入图片描述

在这里插入图片描述

选择数据库
在这里插入图片描述

在这里插入图片描述

更新数据
在这里插入图片描述

在这里插入图片描述

如果mysql连接失败,下面的可能能帮助:

在这里插入图片描述

10.8事务

要么都成功要么都失败ACID

原子性: 要么全部完成,要么全部失败

一致性: 总数不变

隔离性: 多个进程互不干扰

持久性: 一旦提交不可逆,持久化到数据库了

隔离性的问题:

脏读: 一个事务读取了另一个没有提交的事务

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

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

代码实现

1.开启事务conn.setAutoCommit(false);

2.一组业务执行完毕提交事务

3.可以在catch语句中显示的定义回滚语句,默认也是失败就会回滚的

package Transaction;

import com.tmous.utils.JdbcUtils;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestTransaction2 {

    public static void main(String[] args) {

        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            conn  = JdbcUtils.getConnection();
            //关闭数据库的自动提交,自动会开启事务
            conn.setAutoCommit(false);//开启事务

            String sql1 = "update `account` set `money` = `money` - 100 where `name` = 'A'";
            st = conn.prepareStatement(sql1);
            st.executeUpdate();

            int x = 1/0; // 报错 ,失败,自动回滚

            String sql2 = "update `account` set `money` = `money` + 100 where `name` = 'B'";
            st = conn.prepareStatement(sql2);
            st.executeUpdate();

            //业务完毕,提交业务
            conn.commit();
            System.out.println("操作成功!!!");

        } catch (SQLException e) {
            //如果失败,则默认回滚
            try {
                conn.rollback(); // 如果失败,回滚事务
            } catch (SQLException ex) {
                ex.printStackTrace();
            }
            e.printStackTrace();
        }finally {
            JdbcUtils.release(conn , st , rs);
        }
    }
}

10.9数据库连接池

数据库连接----执行完毕-----释放 连接-----释放是十分浪费系统资源的

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

10 SQL 5个连接 直接拿到conn 不需要连接 用完释放

最小连接数: 5 10 100 按照需求

最大连接数: 10 业务最高承载上限超过的就排队等待

编写连接池需要 实现一个接口datasource

开源数据源实现

DBCP

C3P0

Druid: 阿里巴巴的

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

DBCP

需要用到的jar包commons-dbcp-1.4 commons-pool-1.6

dbcpconfig.properties

#<!-- 连接设置 -->
driverClassName=com.mysql.cj.jdbc.Driver
url=jdbc:mysql://127.0.0.1:3306/jdbcstudy?serverTimezone=UTC&amp&useSSL=false
username=root
password=123456

#<!--初始化连接  -->
initialSize=10

#<!--最大连接数量 -->
maxActive=50

#<!--最大空闲连接  -->
maxIdle=20

#<!--最小空闲连接-->
minIdle=5

#<!--超时等待时间以毫秒为单位-->
maxWait=60000

#JDBC驱动建立时附带的连接属性的格式必须为  属性名=properties
connectionProperties=useUnicode=true;characterEncoding=UTF8

# 指定由连接池所创建的连接的自动提交状态
defaultAutoCommit=true

#driver default 指定由连接池所创建的连接的只读状态
# 如果没有设置该值 则setReadOnly 方法将不被调用
defaultReadOnly=

# driver default 指定由连接池所创建的连接的事务的级别
defaultTransactionIsolation=READ_UNCOMMITTED

DBCP帮助类

package com.tmous.utils;

import org.apache.commons.dbcp.BasicDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

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 getConnection() throws SQLException {
        //从数据源中获取连接
        return dataSource.getConnection();
    }

    //释放连接资源
    public static void release(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();
            }
        }
    }
}

测试DBCP

package TestPool;

import com.tmous.utils.JdbcUtils;
import com.tmous.utils.JdbcUtils_DBCP;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestDbcp {

    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            connection = JdbcUtils_DBCP.getConnection();

            //区别  : 使用问号占位符代替参数
            String sql  = "INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`) VALUES (?,?,?,?,?);";

            st = connection.prepareStatement(sql); //预编译的sql

            //手动给参数赋值
            st.setInt(1,4);
            st.setString(2,"老狗");
            st.setString(3,"123456");
            st.setString(4,"1844736@qq.com");
            st.setDate(5, new java.sql.Date(new java.util.Date().getTime()));

            int i = st.executeUpdate();
            if(i>0){
                System.out.println("插入成功!");
            }else{
                System.out.println("插入失败!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils_DBCP.release(connection , st , null);
        }

    }
}

c3p0

c3p0-0.9.5.5,mchange-commons-java-0.2.15导入依赖的jar就行

帮助类:

package com.tmous.utils;

import com.mchange.v2.c3p0.ComboPooledDataSource;
import org.apache.commons.dbcp.BasicDataSourceFactory;

import javax.sql.DataSource;
import java.io.InputStream;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.Properties;

public class JdbcUtils_C3P0 {

    private static ComboPooledDataSource dataSource = null;

    static{

        try {
            dataSource = new ComboPooledDataSource("MySQL"); // 配置文件写法

            //代码版配置
//            dataSource = new ComboPooledDataSource();
//            dataSource.setDriverClass();
//            dataSource.setUser();
//            dataSource.setPassword();
//            dataSource.setJdbcUrl();
//            dataSource.setMaxPoolSize();
//            dataSource.setMinPoolSize();


        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    //获取连接
    public static Connection getConnection() throws SQLException {
        //从数据源中获取连接
        return dataSource.getConnection();
    }

    //释放连接资源
    public static void release(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();
            }
        }
    }
}

c3po配置文件:c3p0-config.xml

<?xml version="1.0" encoding="UTF-8"?>
<c3p0-config>
    <default-config>
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useSSL=false&amp;serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </default-config>

    <named-config name="MySQL">
        <property name="driverClass">com.mysql.cj.jdbc.Driver</property>
        <property name="jdbcUrl">jdbc:mysql://localhost:3306/jdbcstudy?useSSL=false&amp;serverTimezone=UTC</property>
        <property name="user">root</property>
        <property name="password">123456</property>

        <property name="acquireIncrement">5</property>
        <property name="initialPoolSize">10</property>
        <property name="minPoolSize">5</property>
        <property name="maxPoolSize">20</property>
    </named-config>

<!--  可以配置多套数据源  -->

</c3p0-config>

测试类:

package TestPool;

import com.tmous.utils.JdbcUtils_C3P0;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;

public class TestC3P0 {

    public static void main(String[] args) {
        Connection connection = null;
        PreparedStatement st = null;
        ResultSet rs = null;

        try {
            connection = JdbcUtils_C3P0.getConnection();

            //区别  : 使用问号占位符代替参数
            String sql  = "INSERT INTO `users`(`id`,`name`,`password`,`email`,`birthday`) VALUES (?,?,?,?,?);";

            st = connection.prepareStatement(sql); //预编译的sql

            //手动给参数赋值
            st.setInt(1,5);
            st.setString(2,"老狗");
            st.setString(3,"123456");
            st.setString(4,"1844736@qq.com");
            st.setDate(5, new java.sql.Date(new java.util.Date().getTime()));

            int i = st.executeUpdate();
            if(i>0){
                System.out.println("插入成功!");
            }else{
                System.out.println("插入失败!");
            }

        } catch (SQLException e) {
            e.printStackTrace();
        }finally {
            JdbcUtils_C3P0.release(connection , st , null);
        }
    }
}

结论

无论是使用什么数据源,本质还是一样的,接口都是没变的(DataSource),方法就不会变,也就是测试类的代码基本都不会变

Druid: 阿里的数据源,比较高级的

----业务级别的MySQL学习

有兴趣的人

-----运维级别MySQL

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值