MySql + JDBC 数据库基础的操作(防止sql注入的方法)

1.数据库的基本组成

cmd操作数据库时出现系统错误193时

找到安装目录bin目录mysqld空文件删除即可

D:\mysql\mysql-5.7.19-win32\bin 有个mysqld的空文件,删除他即可

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-OdtnoICM-1582730576577)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200217195503003.png)]

-- 目标:创建一个school数据库
-- 创建一个学生表(列,字段) 使用SQL创建
-- 学号int 登录密码varchar(20) 姓名,性别varchar(2) ,出生日期(datetime),家庭住址(email)
-- 注意点,使用英文,表的名称和字段尽量使用``括起来
-- AUTO_INCREMENT 自增
-- 字符串使用单引号括起来
-- 所有的语句后面加,(英文的),最后一个不用加
-- comment 注解/解释/描述
-- DEFAULT 默认值
CRETE DATABASE IF NOT EXISTS school
CREATE TABLE IF NOT EXISTS `student1`(
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT'学号',
`name` VARCHAR(30) NOT NULL DEFAULT'匿名' COMMENT'姓名',
`sex` VARCHAR(2) NOT NULL DEFAULT'男' COMMENT'性别',
`pwd` VARCHAR(20) NOT NULL DEFAULT'123456'COMMENT'登录密码',
`birthday`  DATETIME DEFAULT NULL COMMENT'出生日期', 
`address` VARCHAR(20) NOT NULL COMMENT'家庭住址',
`email` VARCHAR(20) NOT NULL COMMENT'邮件',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

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

1.1 添加,修改,删除

DESC student1 -- 显示表的结构

-- 修改表名alter table 旧表名 rename as 新表名
ALTER TABLE student1 RENAME AS student2

-- 增加表的字段 alter table 表名 add 字段名 列属性
ALTER TABLE student1 ADD age INT(11)

-- 修改表的字段(重命名,修改约束)
ALTER TABLE student1 MODIFY age VARCHAR(20) -- 修改约束
ALTER TABLE student1 CHANGE age age2 INT(3)  -- 字段重命名

-- 删除表的字段
ALTER TABLE student1 DROP age2

-- 删除表(如果存在在删除)
DROP TABLE IF  EXISTS student

2.添加外键

2.1方式一:

在创建表的时候,添加约束 (麻烦,复杂不建议使用)

-- 学生表的gradeid字段 要去引用年级表的gradeid
-- 定义一个外键
-- 给这个外键添加一个约束(执行引用) references引用`grade`
CREATE DATABASE IF NOT EXISTS school
CREATE TABLE `student1`(
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT'学号',
`name` VARCHAR(30) NOT NULL DEFAULT'匿名' COMMENT'姓名',
`sex` VARCHAR(2) NOT NULL DEFAULT'男' COMMENT'性别',
`pwd` VARCHAR(20) NOT NULL DEFAULT'123456'COMMENT'登录密码',
`birthday`  DATETIME DEFAULT NULL COMMENT'出生日期', 
`gradeid` INT(10) NOT NULL COMMENT'学生的年级',
`address` VARCHAR(20) NOT NULL COMMENT'家庭住址',
`email` VARCHAR(20) NOT 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 IF NOT EXISTS `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT'年级id',
`gradename` VARCHAR(20) NOT NULL COMMENT'年级名字',
PRIMARY KEY(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

2.2方式二:

创建表成功后,添加外键约束

CREATE TABLE `grade2`(
`gradeid` INT(2) NOT NULL AUTO_INCREMENT COMMENT '年级id',
`gradename` VARCHAR(10) NOT NULL DEFAULT '匿名' COMMENT '年级姓名',
PRIMARY KEY(`gradeid`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

CREATE TABLE `student2`(
`id` INT(10) NOT NULL AUTO_INCREMENT COMMENT'学号',
`name` VARCHAR(20) NOT NULL DEFAULT'匿名' COMMENT'姓名',
`sex` VARCHAR(20) NOT NULL DEFAULT'男' COMMENT'性别',
`birthday` DATETIME DEFAULT NULL COMMENT'出生日期',
`gradeid` INT(2) NOT NULL COMMENT'学生年级',
`email` VARCHAR(20) NOT NULL COMMENT'邮件',
PRIMARY KEY(`id`)
)ENGINE=INNODB DEFAULT CHARSET=utf8

-- 创建表的时候没有外键关系
ALTER TABLE `student2`
ADD CONSTRAINT `FK_gradeid` FOREIGN KEY(`gradeid`) REFERENCES `grade2`(`gradeid`)

3.DML(数据库操作语言)

语句:

  • inset 添加
  • update 修改
  • delete 删除

3.1添加:修改 : 删除

-- 添加数据
-- insert into `表名`(`字段名1`,`字段名2`,`...`) values (`值1`),(`值2`),(`...`) 
-- 字段和字段之间使用英文隔开
-- 字段是可以省略的,但是后面的必须要一一对应
-- 同时插入多条数据values(),()逗号隔开即可
INSERT INTO `grade2`(`gradename`) VALUES('大五')
INSERT INTO `student2`(`name`,`sex`,`gradeid`,`email`) VALUES ('李四','女','2','2151252'),('旺财','女','3','2151252'),('发财','男','5','2151252')


-- 修改 upate 修改谁(条件) set 原来的值=新值
UPDATE `student2` SET `name`='张dsfc' WHERE id = 3

-- 不错的条件的情况下,会改动所有的表
UPDATE `student2` SET `name`='进宝' 

-- 修改多个属性,逗号隔开
UPDATE `student2` SET `name`='进宝',`email`='[email protected]' WHERE id=1 
-- 语法
-- update `表名` set `字段`='新值' where 条件

-- 通过多个条件定位数据
UPDATE `student2` SET `name`='奔月' WHERE `name`='进宝' AND `sex`='男'
UPDATE `student2` SET `birthday`= CURRENT_TIME WHERE id=3 

-- 删除delete 删除所有的信息,不会影响自增
DELETE FROM `student2` WHERE id='1'
-- truncate 截断 删除表自增会归零
TRUNCATE grade2

4.DQL:(数据查询语言)

(Date Query Language)数据查询语言

  • 所用到的表的SQL建库,建表 语句(数据库school,表 student ,category,grade,student

  • ,subject)

    /*
    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','[email protected]','450323198612111234'),(1001,'123456','周颖',1,2,'13500000002','河南洛阳','1981-12-31 00:00:00','[email protected]','450323198112311234'),(1002,'111111','杨文瑞',1,1,'13500000003','天津市和平区','1986-11-30 00:00:00','[email protected]','450323198611301234'),(1003,'123456','韩萌',1,3,'13500000004','上海卢湾区','1986-12-31 00:00:00','[email protected]','450323198612314234'),(1004,'123456','刘丽侠',1,4,'13500000005','北京市通州','1989-12-31 00:00:00','[email protected]','450323198612311244'),(1005,'123456','姜嘉航',2,1,'13500000006','广西桂林市灵川','1986-12-31 00:00:00','[email protected]','450323198612311214'),(1006,'123456','郑嘉祥',2,4,'13500000007','地址不详','1986-12-31 00:00:00','[email protected]','450323198612311134'),(1007,'111111','刘洋',1,1,'13500000008','北京东城区','1986-12-31 00:00:00','[email protected]','450323198612311133'),(1008,'111111','刘洋洋',1,1,'13500000009','河南洛阳','1986-12-31 00:00:00','[email protected]','450323198612311221'),(1009,'123456','刘毅',1,2,'13500000011','安徽','1986-12-31 00:00:00','[email protected]','450323198612311231'),(1010,'111111','赵杰',1,1,'13500000012','河南洛阳','1986-12-31 00:00:00','[email protected]','450323198612311044'),(1011,'111111','赵成',1,1,'13500000013','北京海淀区中关村大街*号','1984-12-31 00:00:00','[email protected]','450323198412311234'),(1012,'123456','刘恒',2,3,'13500000014','广西南宁中央大街','1986-12-31 00:00:00','[email protected]','450323198612311334'),(1013,'123456','张伟奇',2,1,'13500000015','上海卢湾区','1986-12-31 00:00:00','[email protected]','450323198612311534'),(1014,'123456','牛恩来',2,4,'13500000016','北京海淀区中关村大街*号','1986-12-31 00:00:00','[email protected]','450323198612311264'),(1015,'123456','马辉',1,4,'13500000017','广西桂林市灵川','1976-12-31 00:00:00','[email protected]','450323197612311234'),(1016,'111111','陈勉',1,1,'13500000018','上海卢湾区','1986-12-31 00:00:00','[email protected]','450323198612311251'),(1017,'123456','赵宇航',2,3,'13500000019','北京长安街1号','1981-09-10 00:00:00','[email protected]','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 */;
    
    CREATE TABLE `category` (
      `categoryid` INT(10) UNSIGNED 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 DEFAULT 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

Select查询语法: select 字段… from 表

-- 查询全部的学生  select 字段 from 表
SELECT * FROM student
-- 查询指定的字段
SELECT `StudentNo`,`StudentName` FROM student
-- 起别名 ,给结果起一个名字 as 可以给字段取别名也可以给表取别名
SELECT `StudentNo` AS 学号 ,`StudentName` AS 学生名字  FROM student AS 学生
-- 函数 Concat(a,b)合并数组 
SELECT CONCAT('姓名:',StudentName )AS 新名字 FROM student

4.1.指定查询字段

select 完整的语法

select [ all | distinct ]

{ | table * | [ table.field1[ as alias1] [,table.field2[as alias2]][…]]}*

from table_name [as table_alias]

[left | right | inner join table_name2] – 联合查询

[where …] --指定结果瞒足的条件

[group by …] – 指定结果按照那几个字段来分组

[having] – 过滤分组的记录必须满足的次要条件

[order by … ] --指定查询记录按一个或多个条件排序

[limit {[offset,]row_count | row_countoffsef offset}] – 指定查询的记录从那条至那条

注意:[]括号代表可选,{}括号代表必选的

select

-- 查询全部的学生  select 字段 from 表
SELECT * FROM student
-- 查询指定的字段
SELECT `StudentNo`,`StudentName` FROM student
-- 起别名 ,给结果起一个名字 as 可以给字段取别名也可以给表取别名
SELECT `StudentNo` AS 学号 ,`StudentName` AS 学生名字  FROM student AS 学生
-- 函数 Concat(a,b)合并数组 
SELECT CONCAT('姓名:',StudentName )AS 新名字 FROM student

-- 去重 :作用 取出select查询出的结果从重复的数据,只显示一条’
SELECT DISTINCT `StudentNo` FROM result
-- 查询系统版本(函数)
SELECT VERSION()
-- 用来计算(表达式 )
SELECT 100*5-6+8 AS 记算结果
-- 查询自增步长(变量)
SELECT @@auto_increment_increment
-- 学员考试成绩+1查看
SELECT `StudentNo`,`StudentResult`+1 AS '提分后' FROM result

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

4.2 where条件子句

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

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

逻辑运算符

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

尽量使用英文字母

-- 查询考试成绩在95~100分之间
SELECT `studentno`,`studentresult` FROM result
WHERE studentresult >=95 AND studentresult<=100

-- annd  &&
SELECT `studentno`, `studentresult`FROM result 
WHERE studentResult>=95 && Studentresult<=100

-- 模糊查询(区间)   between   在...之间
SELECT `studentno`,`studentresult` FROM result 
WHERE studentresult BETWEEN 95 AND 100

-- 除了1000号学生之外的同学的成绩
SELECT `studentno`,`studentresult` FROM result
WHERE studentno!=1000

-- != , not    取反,不是
SELECT  studentno ,studentresult FROM result
WHERE NOT studentno =1000

4.3 模糊查询:比较运算符

运 算符 语法 描述
is null a is null 如果操作符为null ,结果为真
is not null a is not null 如果操作符不为null,结果为真
between a betweeen b and c 若a在b和c之间,结果为真
like a like b SQL匹配,如果a匹配b 则结果为真
in a in (a1,a2,a3…) 假设a1,或者a2…的其中一个值中,结果为真
-- 模糊查询
-- 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 '%嘉%'

-- in(具体的一个或多个值)
-- 查询1001 1002 1003 学员
SELECT `studentno`,`studentname` FROM student
WHERE studentno IN (1001,1002,1003)

-- 查询在北京的学生
SELECT `studentno`,`studentname`,`address` FROM student
WHERE address IN ('安徽','河南洛阳')

-- null  not 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

4.4 联表查询

join 联合

七种联表查询

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-pRIRXdDe-1582730576579)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200213104252085.png)]

联表查询join查询分析思路:

*/思路:

1.分析需求, 分析查询的字段来自哪些表(联表查询)

2.确定使用哪种连接查询? 7种

确定交叉点(这两个表中那个数据是相同的)

判断的条件:学生表中的 studentno = 成绩表 studentno

*/

-- 查询所有的信息
SELECT * FROM student
SELECT * FROM result
--  inner join (中间连接)查询参加考试的同学(学号,姓名,科目编号,分数)
SELECT s.studentNo,studentName,SubjectNo,studentResult
FROM student AS s
INNER JOIN result AS r
ON s.studentNo = r.studentNo

-- right join (右边查询)
SELECT s.studentno,studentname,subjectno,studentresult
FROM student AS s
RIGHT JOIN result AS r 
ON s.studentno = r.studentno

-- left join (左边查询)
SELECT s.studentno,studentname,subjectno,studentresult
FROM student s
LEFT JOIN result r
ON s.studentno = r.studentno
操作 描述
inner join 如果表中至少有一个匹配,就返回
left join 会从左表中返回所有值,即使右表中没有匹配
right join 会从右表中返回所有值,即使左表中没有匹配

– jion(连接的表) on(判断的条件) 连接查询

– where(判断条件 ) 等值查询

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


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

-- 我要查询哪些数据  select ....
-- 从那几个表中查 from 表 as 别名 (左(left)/右(right)/中(inner)) jion 连接的表 as 别名 on 交叉条件
-- 假设存在一种多张表查询,先查询两张然后在慢慢的增加

-- from a left join b  左连接以a为基准查询b表
-- from a right jion b 右连接以b为基准查询a表 

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

表一:两张结合表

categoryid pid categoryname
2 1 信息技术
3 1 软件开发
4 3 数据库
5 1 美术设计
6 3 web开发
7 5 ps技术
8 2 办公信息

表二:拆分之一(父类)

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

表三: 拆分之一(子类)

pid catgorid categoryname
3 4 数据库
2 8 办公信息
3 6 wed开发
5 7 ps技术

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

父类 子类
信息技术 办公信息
软件开发 数据库
软件开发 web开发
美工技术 ps技术
-- 查询父子信息:把一张表看做为两张一摸一样的表
SELECT a.categoryname AS '父类', b.categoryname AS '子类'
FROM category AS a, category AS b
WHERE a.`categoryid` = b.`pid` 

-- 查询学员所属的年级(学号,姓名,年级名称)
SELECT a.studentno,studentname,gradename
FROM student AS a
INNER JOIN grade AS b
WHERE a.`GradeID`=b.`GradeId`
 
-- 查询科目所属的年级(科目名称,年级名称)
 SELECT subjectname,gradename
 FROM `subject` s
 INNER JOIN grade a
 ON s.`GradeId`= a.`GradeId`
 
 -- 查询了参加 数据库结构-1 考试的同学信息 :学号 学生姓名 科目名 分数
 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='数据库结构-2'

4.5 分页和排序

排序

 -- 排序: 升序ASC   ,降序DESC
 -- ORDER BY  排序通过这个字段来排序
 -- 查询的结果根据 成绩降序 排序
SELECT s.studentno,studentname,subjectname,studentresult
FROM student AS s
INNER JOIN result AS r
ON s.studentno = r.studentno
INNER JOIN `subject` sub
ON r.subjectno = sub.subjectno
WHERE subjectname='数据库结构-2'
ORDER BY studentresult DESC

分页

-- 分页 为了缓解数据库的压力,给人体验更好,瀑布流
-- 分页。每页只显示五条数据
-- 语法:limit起始值,页面的大小
-- 页面应用 : 当前总页数,页面大小
-- LIMIT 0,5   第一页显示五条数据
SELECT s.studentno,studentname,subjectname,studentresult
FROM student AS s
INNER JOIN result AS r
ON s.studentno = r.studentno
INNER JOIN `subject` sub
ON r.subjectno = sub.subjectno
WHERE subjectname='数据库结构-4'
ORDER BY studentresult DESC
LIMIT 0,5

-- (n-1)*pagesize,pagesize
-- 第一页  limit 0,5  (1-1)*5
-- 第二页  limit 5,5  (2-1)*5
-- 第三页  limit 10,5  (3-1)*5
-- 第n页  limit n,5  (n-1)*pagesize,pagesize
-- 【pagesize: 页面大小】
-- 【(n-1)*pagesize:起始值】
-- 【n :当前页】
-- 【数据总额/页面大小=总页数】

4.6 子查询

本质:在where语句中嵌套一个查询语句(where这个值是计算出来的)

-- 子查询
-- 查询 数据库-1 的所有考试结果(学号,科目编辑,成绩),降序排序 成绩大于80分
-- 方式一:使用连接查询
SELECT DISTINCT s.studentno,subjectname,studentresult
FROM result s
INNER JOIN `subject` d
ON s.subjectno=d.subjectno
WHERE subjectname='数据库结构-1' AND studentresult>=80
ORDER BY StudentResult DESC
-- 方式二:使用子查询(由内而外)
SELECT studentno,subjectno,studentresult
FROM result 
WHERE subjectno =(
SELECT subjectno FROM `subject`
WHERE subjectname='数据库结构-1' 
)
ORDER BY studentresult DESC

-- 查询课程为  高等数学-2 且分数不下雨80 的同学的学号和姓名
SELECT s.studentno,studentname
FROM student s
INNER JOIN result e 
ON s.studentno=e.studentno
INNER JOIN `subject` sub
ON e.subjectno =sub.subjectno
WHERE subjectname ='高等数学-2' AND studentresult>=80


-- 分数不小于80分的学生的学号和姓名
SELECT DISTINCT s.studentno,studentname
FROM student s
INNER JOIN result r
ON r.studentno =s.studentno
WHERE studentresult>=80

-- 在上面的基础上增加一个科目  高等数学-2
-- 查询 高等数学的编号
SELECT DISTINCT s.studentno,studentname
FROM student s
INNER JOIN result r
ON r.studentno =s.studentno
WHERE studentresult>=80 AND subjectno= (
SELECT subjectno FROM `subject` WHERE 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'
	)
)

4.7 分组和过滤

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

4.8 select小结

语法顺序很重要

select 去重 要查询的字段from表(注意:表和字段可以取别名)

xxx join 要连接的表 on 等值判断

where (具体的值,子查询语法)

group by (通过那个字段来分组)

having (过滤分组后的信息,条件和where是一样的,位置不同)

order by。。(通过那个字段排序)【升序/降序】

limit startlndex,pagesize(分页从那个地方开始,到那个地方结束)

select  [ all  |  distinct ]
{
    * | table * | [ table.field1[ as alias1] [,table.field2[as alias2]][.....]]}
from table_name [as table_alias]**
[left  |  right  |  inner  join  table_name2]    --  联合查询**
[where  ...]    --指定结果瞒足的条件**
[group  by  ....]   -- 指定结果按照那几个字段来分组**
[having]   -- 过滤分组的记录必须满足的次要条件**
[order  by   ... ]   --指定查询记录按一个或多个条件排序**
[limit {
    [offset,]row_count  |  row_countoffsef  offset}]   -- 指定查询的记录从那条至那条**
-- 注意:[]括号代表可选,{}括号代表必选的**

5.MySQL函数

5.1 常用函数

-- 常用函数
-- 数学运算
SELECT ABS(-1)  -- 绝对值
SELECT CEILING(9.1) -- 向上取整 
SELECT FLOOR(9.5) -- 向下取整 
SELECT RAND() -- 返回一个 0~1 之间的随机数 
SELECT SIGN(10) -- 判断一个数的符号 0-0 负数返回-1,正数返回 1 

-- 字符串函数 
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,6) -- 返回指定的子字符串 (源字符串,截取的位置,截 取的长度) 
SELECT REVERSE('清晨我上马') -- 反转 -- 查询姓 周的同学,名字 邹 
SELECT REPLACE(studentname,'周','邹') 
FROM student WHERE studentname LIKE '周%' 

-- 时间和日期函数 (记住) 
SELECT CURRENT_DATE() -- 获取当前日期 
SELECT CURDATE() -- 获取当前日期 S
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() 最大值0
min() 最小值
-- 都能够统计 表中的数据 ( 想查询一个表中有多少个记录,就使用这个count() ) 
SELECT COUNT(`BornDate`) FROM student; -- Count(字段),会忽略所有的 null值 
SELECT COUNT(*) FROM student; -- Count(*),不会忽略 null 值, 本质 计算数 
SELECT COUNT(1) FROM result; -- Count(1),不会忽略忽略所有的 null 值 本质 计算行数


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 加密后的值
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,'zhangshunag','123456'),
(2,'zhangshunag2','123456'),(3,'zhangshunag3','123456')

-- 加密
UPDATE testmd5 SET pwd=MD5(pwd) -- 全部加密
UPDATE testmd5 SET pwd=MD5(pwd) WHERE id=1

-- 插入式加密
INSERT INTO testmd5 VALUES(45,'xiaoming',MD5('123456'))

-- 如何校验 :将用户传递进来的密码,进行MD5加密,然后比对加密后的值
SELECT * FROM testmd5 WHERE `name`='xiaoming' AND pwd=MD5('123456')

6.事物

要么成功,要么失败


1.SQL执行 a给b转账 a 1000 转200 b 200

2.SQL执行 b收到a的钱 a 8000 收到b 400


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

事务原则 : ADID 原子性 ,一致性 ,隔离性 ,持久性

原子性(Atomicity)

要么成功,要的失败

一致性(Consistency)

事务前后的数据完整性要保持一致(总的数量不变)

持久性(Durability)–事务提交

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

隔离性(Isolation)

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

隔离所导致的一些问题wo

脏读:

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

不可重复读:

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

虚读(幻读):

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

执行事务

-- mysql 是默认开启事务提交的
SET autocommint =0  -- 关闭
SET autocommint =1  -- 开启(默认的)
-- 手动处理事务
SET autocommint =0 -- 关闭自动提交
-- 事务开启
START TRANSACTION  --  标记一个事务开始,从这个跟之后SQL都在同一个事务内

INSERT  xx
INSERT  xx

-- 提交:持久化(成功)
COMMIT
-- 货滚:回到原来的样子(失败)
ROLLBACK

-- 事务结束
SET autocommint =1  --  开启自动提交

-- 了解
SAVEPOINT 保存点名  -- 设置一个事务的保存点
ROLLBACK TO SAVEPOINT  保存点名  -- 回滚到保存点
RELEASE SAVEPOINT 保存点名  -- 撤销保存点

模拟场景

-- 转账
CREATE DATABASE shop CHARACTER SET utf8 COLLATE utf8_general_ci
USE shop

CREATE TABLE account(
`id `INT(10) NOT NULL AUTO_INCREMENT,
`name` VARCHAR(30) NOT NULL ,
`money` DECIMAL(9,5) NOT NULL ,
PRIMARY KEY(id)
)ENGINE=INNODB DEFAULT CHARSET=utf8

INSERT INTO account(`name`,`money`)
VALUES('A',1000.00),('B',2000.00)

-- 模拟转账:事务
SET autocommit = 0; -- 关闭自动提交
START TRANSACTION  -- 开启一个事务(一组事务)
UPDATE account SET money = money-500 WHERE `name`='A' -- 更新表account  设置钱的数目  -500
UPDATE account SET money = money+500 WHERE `name`='B' -- 更新表account  设置钱的数目  +500

COMMIT -- 提交事务 ,就被持久化了
ROLLBACK  -- 回滚

SET autocommit = 1  -- 恢复默认值

7. 索引

MySQL官方对索引的定义为:索引(index)是帮助mysql高效获取数据的数据结构 数据越大索引的好处越明显0.5s 0.0000001s 的对比

本质:索引是数据结构

7.1 索引分类

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

  • 主键索引(primary key)

    • 唯一的标识,主键不可重复,只能有一个列作为主键
  • 唯一索引(unique key)

    • 避免重复的列出现,唯一索引可以重复,多个列都可以标识位 唯一索引
  • 常规索引(key / index)

    • 默认的,index key 关键字来设置
  • 全文索引(fulltext)

    • 在特定的数据库引擎下才有,myisam
    • 快速定位数据

    基础语法

    EXPLAIN 解释 ;说明;执行计划的使用

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

-- 显示所有的索引信息 
SHOW INDEX FROM student 
-- 增加一个全文索引 (索引名) 列名
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, 
`name` VARCHAR(50) 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万数据 55.176 sec

DELIMITER $$ -- 写函数之前必须要写,标志
CREATE FUNCTION mock_data() 
RETURNS INT
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),'[email protected]',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();
     SELECT * FROM app_user WHERE `name` = '用户9999'; -- 2.152  sec 
     SELECT * FROM app_user WHERE `name` = '用户9999'; -- 1.987  sec 
     SELECT * FROM app_user WHERE `name` = '用户9999'; --  0.599  sec 
     EXPLAIN SELECT * FROM app_user WHERE `name` = '用户9999'; -- 0.002 sec
     SELECT * FROM student --0.001 sec
 
 -- 添加常规索引
-- id _ 表名 _ 字段名 
-- CREATE INDEX 索引名 on 表(字段)
CREATE INDEX id_app_user_name ON app_user(`name`); 
SELECT * FROM app_user WHERE `name` = '用户9999'; -- 0.001 sec 
SELECT * FROM app_user WHERE `name` = '用户9999'; 
EXPLAIN SELECT * FROM app_user WHERE `name` = '用户9999';

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RZRMnJf1-1582730576580)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200217203426231.png)]

添加一个常规索引运行结果如上图

删除索引运行结果如下图

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-A8l2zwgS-1582730576580)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200217203841466.png)]

索引在小数量的时候,用户不大,但是在大数据的时候,却别十分明显

7.3 索引原则

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

索引的数据结构

Hash 类型的索引

Btee : innodb 的默认数据结构

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

8.权限管理和备份

8.1 用户管理

SQL yog可视化管理

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-evXS8ktm-1582730576580)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200217223959592.png)]

SQl 命令操作

用户表: mysql.user

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

-- 创建用户 create  user 用户名  identified by '密码'
CREATE  USER zhnagshuang IDENTIFIED BY '123456'

-- 修改密码(修改当前用户密码)
SET PASSWORD = PASSWORD('123456')

-- 修改密码(修改指定用户密码)
SET PASSWORD FOR zhangshuang= PASSWORD('123456')
-- 重命名rename user 原来的名字 to 新名字
RENAME USER zhangshuang TO zhangshuang3

-- 用户授权 all privileges 全部权限     库 表
-- all privileges 给别人授权,其它都能干
GRANT ALL PRIVILEGES ON *.* TO zhangshuang3

-- 查询权限
SHOW GRANTS FOR zhangshuang3  -- 查看指定用户权限4
SHOW GRANTS FOR root@localhost  
-- root 用户权限  GRANT PROXY ON ''@'' TO 'root'@'localhost' WITH GRANT OPTION

-- 撤销权限 revoke  哪些权限 ,给谁撤销
REVOKE ALL PRIVILEGES ON *.* FROM zhangshuang3

-- 删除用户
DROP USER zhangshuang3

8.2 mysql备份

为什么要备份:

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

mysql数据库备份的方式

  • 直接拷贝物理文件

  • 在sqlyog这种可视化工具中手动导出

  • 在想要导出的表或者库中,右键,选着备份或导出

    [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Z1lsxJgo-1582730576581)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200217233116523.png)]

使用命令行导出mysqldump 命令行使用

-- 使用管理员身份运行cmd 
-- mysqldump  - h 主机 -u 用户名  -p 密码  数据库  表名  > 物理磁盘位置/(起新的)文件名
mysqldump -hlocalhost -uroot -p123456 school student > D:/a.sql

-- mysqldump  - h 主机 -u 用户名  -p 密码  数据库  表名1 表名2 表明3(同时备份多张表)  > 物理磁盘位置/(起新的)文件名
mysqldump -hlocalhost -uroot -p123456 school student > D:/b.sql

-- mysqldump  - h 主机 -u 用户名  -p 密码  数据库(本分数据库) > 物理磁盘位置/(起新的)文件名
mysqldump -hlocalhost -uroot -p123456 school  > D:/c.sql

-- 导入
-- 登录的情况下,切换到指定的数据库   mysql -urooot -p123456    切换user 数据库名
-- source 备份文件
source D:/a.sql

mysql -u用户名 -p密码  库名<备份文件(在没有登录的情况下执行)

数据库备份是作用:防止数据丢失,可以直接用来发送给朋友

9.数据库规范设计

9.1、为什么需要设计

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

糟糕的数据库设计:

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

良好的数据库设计:

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

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

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

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

收集信息,分析需求

  • 用户表(用户登录注销,用户的个人信息,写博客,创建分类)
  • 分类表 (文章分类,谁创建的)
  • 文章表 (文章的信息)
  • 评论表
  • 友链表 (友链信息)
  • 自定义表 (系统信息,某个关键的字,或者一些主字段) key : value
  • 说说表 (发表心情 … id… content….create_time)

标识实体 (把需求落地到每个字段)

标识实体 之间的关系连接

  • 写博客:user --> blog

  • 创建分类:user –> category

  • 关注:user –>user

  • 友链:links

  • 评论:user->user->blog

    表如下:

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-mEMCIMKY-1582730576581)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200218094551058.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-88hdPn2h-1582730576581)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200218094250036.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-HP3aiyxo-1582730576582)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200218094328750.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-beZDmQd5-1582730576582)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200218094442401.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-UKssrfTK-1582730576582)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200218094725660.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-zT2lCIYc-1582730576582)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200218094819270.png)]

9.2 三大范式

为什么需要数据规范化?

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

三大范式(面试题)

第一范式(1NF)

  • 原子性:确保每一列不可再分

第二范式(2NF)

  • 前提:瞒住第一范式
  • 每一张表只描述一件事

第三范式(3NF)

  • 前提:瞒足第一范式和第二范式
  • 第三范式需要确保数据表中的每一列都和逐渐直接相关联,二不能间接相关联

(数据库设计理念)

规范性和性能的问题

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

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

目标:

  1. leetcode 账号 (算法题:答题,思路)

  2. 牛客网账号 (查面试、历届面试题)

  3. 给自己一个目标 : 字节跳动、阿里、腾讯、百度、B站、虎牙、京东、顺丰、海康威视

面试:考试

提前几个月:看历届面试题

10.JDBC(重点)

10.1 数据库驱动

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

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nA8CBwvL-1582730576583)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200218103308539.png)]

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

10.2 jdbc

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

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

对于开发人员来说,我们只需要掌握 JDBC 接口的操作即可!

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fHLxRWAl-1582730576583)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200218103454399.png)]

导包:

java.sql

javax.sql

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

10.3 第一个JDBc程序

准备工作创建一个测试数据库

CREATE DATABASE jdbcStudy CHARACTER SET utf8 COLLATE utf8_general_ci;

USE jdbcStudy;

CREATE TABLE users(
    id INT PRIMARY KEY,
    NAME VARCHAR(40),
    PASSWORD VARCHAR(40),
    email VARCHAR(60),
    birthday DATE
);

INSERT INTO users(id,NAME,PASSWORD,email,birthday) 
VALUES(1,'zhansan','123456','[email protected]','1980-12-04'),
(2,'lisi','123456','[email protected]','1981-12-04'),
(3,'wangwu','123456','[email protected]','1979-12-04')

1.创建一个新的项目

2.导入数据库驱动

3.编写测试代码

package com.shuang;



import java.sql.*;

/*
 *作者;${my}
 *时间;2020-02-18-11-00
 *描述:{         }
 */
public class JDBCdemo {
     
    public static void main(String[] args) throws ClassNotFoundException, SQLException {
     
        // 1.加载驱动
        Class.forName("com.mysql.jdbc.Driver");//固定写法,加载驱动
        //2.用户信息和url
        //useUnicode=true(支持中文)&charcterEncoding(字符及编码)=utf8&useSSL(使用安全的连接)=true
        String url="jdbc:mysql://localhost:3306/jdbcstudy?useUnicode=true&charcterEncoding=utf8&useSSL=true";
        String username="root";
        String password="123456";
        //3.连接成功,数据库对象 Connection代表数据库
        // DriverManager.getConnection(驱动管理去获得连接)
        Connection connection = DriverManager.getConnection(url, username, password);
        //4. 执行sql的对象 statement
        //connection.createStatement()  创建一个对象去执行sql语句
        Statement statement = connection.createStatement();
        //5.执行sql的对象去执行sql,可能存在结果,查看返回结果
        //statement.executeQuery  使用创建的对象去执行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("pwd=" + resultSet.getObject("PASSWORD"));
            System.out.println("email=" + resultSet.getObject("email"));
            System.out.println("birth=" + resultSet.getObject("birthday"));
        }
        //6.释放连接
        resultSet.close();
        statement.close();
        connection.close();
    }
}

步骤总结:

1、加载驱动

2、连接数据库 DriverManager

3、获得执行sql的对象 Statement

4、获得返回的结果集

5、释放连接

6.理解思路

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-lzbPbXtQ-1582730576584)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200220135316783.png)]

10.4 DriverManager(驱动管理)

// DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 
Class.forName("com.mysql.jdbc.Driver"); // 固定写法,加载驱动 
Connection connection = DriverManager.getConnection(url, username, 
password); 
// connection 代表数据库对象支持(数据库设置自动提交  事务提交  事务滚回... )

connection.rollback();//回滚 
connection.commit(); //提交
connection.setAutoCommit();//自动提交

10.5 URl(网址)

String url = "jdbc:mysql://localhost:3306/jdbcstudy? 
// useUnicode=true(支持中文)&charcterEncoding(字符及编码)=utf8&useSSL(使用安全的连接)=true
useUnicode=true&characterEncoding=utf8&useSSL=true"; 
// mysql -- 3306 
//网址==协议 ://主机地址:端口号/数据库名?参数1&参数2&参数3 
// oralce -- 1521 
//jdbc:oracle:thin:@localhost:1521:sid 

10.6 Statement 执行SQL 的对象 PrepareStatement 执行SQL 的对象

都是执行sql语句的对象

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

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

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

获得指定的数据类型

resultSet.getObject(); // 在不知道列类型的情况下使用 
// 如果知道列的类型就使用指定的类型 
resultSet.getString(); 
resultSet.getInt(); 
resultSet.getFloat(); 
resultSet.getDate(); 
resultSet.getObject(); 

.... 

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-iNJu4iT8-1582730576584)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200220142218889.png)]

遍历,指针

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

10.8 释放资源

//6、释放连接 

resultSet.close(); 
statement.close(); 
connection.close(); // 耗资源,用完关掉!

11. Statement sql执行对象(不安全的)

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

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

Statement.executeQuery方法用于向数据库发送查询语句,executeQuery方法返回代表查询结果的ResultSet(结果集)对象。

11.1 使用工具类连接数据库

11.1.1 首先编写一个src下编写一个配置文件db.properties

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

11.1.2 编写一个工具类 Utils

package com.shuang.Utils;

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

/*
 *作者;${my}
 *时间;2020-02-20-16-58
 *描述:{         }
 */
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");//getClassLoader获取类加载器  getResourceAsStream //获取资源作为流
            Properties properties = new Properties();//properties  属性
            properties.load(in);//load  加载
             driver = properties.getProperty("driver");//读取资源
            url = properties.getProperty("url");
            username = properties.getProperty("username");
            password = properties.getProperty("password");

            //类驱动只用加载一次
           Class.forName(driver);
            } catch (Exception e) {
     
            e.printStackTrace();
        }
    }
    //获取连接
    public static Connection getConnection() throws Exception {
     
        return DriverManager.getConnection(url, username, password);//连接数据库并返回连接对象
      
    }
    //释放连接资源
    public static void release(Connection conn, Statement st, ResultSet re)  {
     
        if (re!=null){
     
            try {
     
                re.close();
            } catch (SQLException e) {
     
                e.printStackTrace();
            }
        }
        if (st!=null){
     
            try {
     
                st.close();
            } catch (SQLException e) {
     
                e.printStackTrace();
            }
        } if (conn!=null){
     
            try {
     
                conn.close();
            } catch (SQLException e) {
     
                e.printStackTrace();
            }
        }
    }
 }

11.1.2 编写测试类

package com.shuang;


import com.shuang.Utils.jdbcUtils;

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

/*
 *作者;${my}
 *时间;2020-02-20-17-25
 *描述:{         }
 */
public class TestInsert {
     
    public static void main(String[] args) {
     
        Connection conn = null;
        Statement st = null;
        ResultSet re = null;
            try {
     
                conn = jdbcUtils.getConnection();//获取数据库连接
                st = conn.createStatement();//数据库(createStatement)创建语句获取sql的对象
                //插入数据
                String sql = "INSERT INTO `users` (`id`,`NAME`,`PASSWORD`,`email`,`birthday`)VALUES(54,'heng','616161','[email protected]','2020-02-20')";
                int i = st.executeUpdate(sql);//执行更新

                if (i > 0) {
     
                    System.out.println("成功");
                }
            } catch (Exception e) {
     
                e.printStackTrace();
            } finally {
     
                jdbcUtils.release(conn, st, re);
            }
        }
    }

11.1.3 删除,修改 查询

(本质 就是编写sql代码,其它的编成工具类直接调用即可)

package com.shuang;


import com.shuang.Utils.jdbcUtils;

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

/*
 *作者;${my}
 *时间;2020-02-20-17-25
 *描述:{         }
 */
public class TestInsert {
     
    public static void main(String[] args) {
     
        Connection conn = null;
        Statement st = null;
        ResultSet re = null;
            try {
     
                conn = jdbcUtils.getConnection();//获取数据库连接
                st = conn.createStatement();//数据库(createStatement)创建语句获取sql的对象

                /**
                 * 增加一个用户
                 *  String sql = "INSERT INTO `users` (`id`,`NAME`,`PASSWORD`,`email`,`birthday`)VALUES(54,'heng','616161','[email protected]','2020-02-20')";
                 *    int i = st.executeUpdate(sql);//执行更新
                  */

                /**
                 * 删除一个用户
                 *  String sql="DELETE FROM `users` WHERE id= 3";
                 *  int i = st.executeUpdate(sql);
                 */

                /**
                 * 修改一个用户
                 *String sql="UPDATE users SET `NAME`='大白菜' ,`email`='[email protected]' WHERE id=4";
                 * int i = st.executeUpdate(sql);
                 */

                //查询所有的名字
                String sql="SELECT * FROM  users";
                re = st.executeQuery(sql);// 查询时使用executeUpdate(更新)和executeQuery(查询)都可以;默认为查询为executeQuery
                while (re.next()){
     
                    System.out.println(re.getString("NAME"));
                }

            } catch (Exception e) {
     
                e.printStackTrace();
            } finally {
     
                jdbcUtils.release(conn, st, re);
            }
        }
    }

11.1.3 sql注入

本质: * SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息

package com.shuang;

import com.shuang.Utils.jdbcUtils;

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

/*
 *作者;${my}
 *时间;2020-02-20-22-38
 *描述:{         }
 */
public class TestSQL注入 {
     
    public static void main(String[] args) {
     
        //模拟登陆数据
        //login("heng","61616"); 密码不正确,登陆不成功没有数据显示
        //login("heng","616161"); 密码正确 登陆成功
        login("'or'1=1","'or'1=1");//技巧  SQL注入使用额外的SQL语句欺骗服务器,来盗取所有的信息,不合法的
/**
 * SQL注入即是指web应用程序对用户输入数据的合法性没有判断或过滤不严,攻击者可以在web应用程序中事先定义好的查询语句的结尾上添加额外的SQL语句,在管理员不知情的情况下实现非法操作,以此来实现欺骗数据库服务器执行非授权的任意查询,从而进一步得到相应的数据信息
 */
    }
    public static void login(String name,String password){
     
        Connection conn = null;
        Statement st = null;
        ResultSet re = null;
        try {
     
            conn = jdbcUtils.getConnection();//获取数据库连接
            st = conn.createStatement();//数据库(createStatement)创建语句获取sql的对象
            //查询所有的名字
           // String sql="SELECT * FROM  users";
            
            // SELECT * FROM users WHERE `Name` = '' or '1=1' AND `password` = '' or '1=1';
            String sql = "select * from users where `NAME`='"+name+"' AND `password` ='"+password+"'";
            
            re = st.executeQuery(sql);//查询时使用executeUpdate(更新)和executeQuery(查询)都可以;默认为查询为executeQuery
            while (re.next()){
     
                System.out.println(re.getString("NAME"));
                System.out.println(re.getString("password"));
                System.out.println("============");
            }

        } catch (Exception e) {
     
            e.printStackTrace();
        } finally {
     
            jdbcUtils.release(conn, st, re);
        }
    }
}

12. preparedStatement 准备好的sql对象(安全的)

增加一个用户

public class TestInsert {
     
    public static void main(String[] args) {
     
        Connection conn = null;
        PreparedStatement st = null;


        try {
     
            conn = jdbcUtils.getConnection();
            //区别
            String sql = "INSERT INTO `users` (`id`,`NAME`,`PASSWORD`,`email`,`birthday`)VALUES(?,?,?,?,?)";
            st = conn.prepareStatement(sql);//预编译,先写sql 然后不执行
            // 手动给参数赋值
            st.setInt(1, 7); //id

            st.setString(2, "wnagcai");
            st.setString(3, "1232112");
            st.setString(4, "[email protected]");
        // 注意点: sql.Date  数据库  java.sql.Date()
        //     util.Date Java   new Date().getTime() 获得时间戳
            st.setDate(5, new java.sql.Date(new Date().getTime()));
            //执行
            int i = st.executeUpdate();
            if (i > 0) {
     
                System.out.println("插入成功!");
            }


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

    }
}

删除一个用户

public class TestDelete {
     

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


        try {
     
            conn = jdbcUtils.getConnection();
            //区别
            String sql = "delete from users where id=?";
            st = conn.prepareStatement(sql);//预编译,先写sql 然后不执行
            // 手动给参数赋值
            st.setInt(1, 7); //id

            //执行
            int i = st.executeUpdate();
            if (i > 0) {
     
                System.out.println("删除成功!");
            }


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

    }
}

修改一个用户信息

public class TestUpdate {
     
    public static void main(String[] args) {
     
        Connection conn = null;
        PreparedStatement st = null;


        try {
     
            conn = jdbcUtils.getConnection();
            //区别
            //使用站位符代替参数
            String sql = "update  users set name=? where id=?";
            st = conn.prepareStatement(sql);//预编译,先写sql 然后不执行
            // 手动给参数赋值
            st.setString(1, "哈弗");
            st.setInt(2, 1);

            //执行
            int i = st.executeUpdate();
            if (i > 0) {
     
                System.out.println("修改成功!");
            }


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

    }
}

根据id查询用户

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


            try {
     
                conn = jdbcUtils.getConnection();
                //区别
                //使用站位符代替参数
                String sql = "select * from users where id=?";
                st = conn.prepareStatement(sql);//预编译,先写sql 然后不执行
                // 手动给参数赋值

                st.setInt(1,2 );//传递参数

                //执行
                rs = st.executeQuery();
                if (rs.next()) {
     
                    System.out.println(rs.getString("name"));
                }


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

        }
    }

防止sql注入

package com.shuang.Safe;


import com.shuang.Utils.jdbcUtils;

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

/*
 *作者;${my}
 *时间;2020-02-26-23-09
 *描述:{         }
 */
public class Test防止sql注入 {
     
    public static void main(String[] args) {
     
        login("'' or 1=1 ", "123456");
    }

    private static void login(String username, String password) {
     
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
     
            conn = jdbcUtils.getConnection();
            //区别
            // PreparedStatement 防止SQL注入的本质,把传递进来的参数当做字符
            // 假设其中存在转义字符,比如说 ' 会被直接转义
            String sql = "select * from users where `NAME`=? and`PASSWORD`=?";
            st = conn.prepareStatement(sql);
st.setString(1,username);
st.setString(2,password);
            st = conn.prepareStatement(sql);//预编译,先写sql 然后不执行
            // 手动给参数赋值

            st.setInt(1, 2);

            //执行
            rs = st.executeQuery();//查询完会返回一个结果集
            while (rs.next()){
     
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("password"));
System.out.println("============================");
}


        } catch (Exception e) {
     
            e.printStackTrace();
        }finally {
     
            jdbcUtils.release(conn,st,rs);

        }

    }
}
         String sql = "select * from users where id=?";
                st = conn.prepareStatement(sql);//预编译,先写sql 然后不执行
                // 手动给参数赋值

                st.setInt(1,2 );//传递参数

                //执行
                rs = st.executeQuery();
                if (rs.next()) {
     
                    System.out.println(rs.getString("name"));
                }


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

        }
    }

防止sql注入

package com.shuang.Safe;


import com.shuang.Utils.jdbcUtils;

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

/*
 *作者;${my}
 *时间;2020-02-26-23-09
 *描述:{         }
 */
public class Test防止sql注入 {
     
    public static void main(String[] args) {
     
        login("'' or 1=1 ", "123456");
    }

    private static void login(String username, String password) {
     
        Connection conn = null;
        PreparedStatement st = null;
        ResultSet rs = null;
        try {
     
            conn = jdbcUtils.getConnection();
            //区别
            // PreparedStatement 防止SQL注入的本质,把传递进来的参数当做字符
            // 假设其中存在转义字符,比如说 ' 会被直接转义
            String sql = "select * from users where `NAME`=? and`PASSWORD`=?";
            st = conn.prepareStatement(sql);
st.setString(1,username);
st.setString(2,password);
            st = conn.prepareStatement(sql);//预编译,先写sql 然后不执行
            // 手动给参数赋值

            st.setInt(1, 2);

            //执行
            rs = st.executeQuery();//查询完会返回一个结果集
            while (rs.next()){
     
System.out.println(rs.getString("NAME"));
System.out.println(rs.getString("password"));
System.out.println("============================");
}


        } catch (Exception e) {
     
            e.printStackTrace();
        }finally {
     
            jdbcUtils.release(conn,st,rs);

        }

    }
}

你可能感兴趣的:(MySql + JDBC 数据库基础的操作(防止sql注入的方法))