database09

2021-12-03
3

一:数据库

MySQL官网

概述:
1.定义:存储数据,管理数据的仓库。
2.分类:关系型数据库和非关系型数据库
  关系型(传统数据库):即数据库之间有着紧密的关系,如父子关系,或采用了关系模型
	(二维表格模型)来组织数据的数据库,
	代表:MYSQL,Oracle,Oracle、MySQL、SQLServer、Access。
	    非关系型(nosql):是一种数据结构化存储方法的集合,主要用在对并发读写能力要求极高,
	事物的一致性不太重要的地方如微博,facebook等地方
	代表:MongoDB、Redis、Solr、ElasticSearch、Hive、HBase等。
3.MYSQL数据库:
	1.服务端:用来处理具体的数据,维护和保存磁盘
	2.客户端:主要操作是数据的增删改查(CRUD)
	3.结构:数据库 -> 表(行和列) -> 数据
	数据的存放位置可以在mysql的配置文件my.ini的datadir目录查看,端口号默认为3306 。

在这里插入图片描述

4.SQL语言:结构化查询语言(Structured Query Language)简称SQL,用来操作数据库的语言,
	是一种操作标准,一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理
	关系数据库系统;同时也是数据库脚本文件的扩展名,1986年10 月由美国国家标准局(ANSI)
	通过的数据库语言美国标准,接着国际标准化组织(ISO)颁布了SQL正式国际标准,
	使用较多的是查询。
		分类:
		DML是数据操纵语言:insert插入,delete删除,update修改,select检索,
			create添加,Retrieve查询、Update修改、Delete删除;
		DDL是指数据定义语言:create table;
		DCL是指数据控制语言:grant、deny、revoke,管理员有相应的权限;
		DQL是指数据查询语言:select 语句

SQL语句(不区分大小写):

登录数据库:
mysql -uroot -proot
数据库   -u用户名  -p登录密码

C:\Users>mysql -u root -p
Enter password: ****
没有分号。
1.创建数据库:
create database 名称 ;
create database 名称 DEFAULT CHARACTER SET utf8; 
create database jasdb default character set utf8;
简写
create database jasdb charset utf8 ;
  • 创建多个数据库:
2.显示所有数据库:
show databases;

查看单个数据库:
 SHOW DATABASES LIKE 'test_db';
3.删除数据库(谨慎操作)drop database 数据库名称; 
drop database jas;
near:定位到错误的附近
打开(使用)数据库:
use 库名;
use jasdb;

退出数据库(在命令行窗口(DOS窗口):

退出 exit/quit
清屏 cls



二:数据表:

概述
定义:数据表是一种由标记的列和行组成的可视化工具,用于排列计算机数据库中包含的信息。
它可以用来组织不同的数据,也可以使数据易于操作和分析。数据表以网格格式显示信息。

表字段:
	命名规则:字段名以字母开头,尽量不要使用拼音代替;长度不要超过30个字符(不同数据库版本长度限制可能会有不同);
	不能使用SQL的保留字,如where,order,group等;只能使用字符a-z、A-Z、0-9、$ 等;
	Oracle习惯全大写:USER1,mysql习惯全小写:user1;多个单词用下划线隔开。

字符:
	char固定字符串长度,不足使用空格填充,最多容纳2000个字符,char(10)存储abc,占10位。
		查询速度极快但浪费空间。
	varchar:可变字符串长度,最多容纳4000个字符,varchar(10)存储abc,只占3位。
		查询稍慢,但节省空间。Oracle为varchar2
	大文本: 大量文字(不推荐使用,尽量使用varchar替代),在utf8编码中一个汉字占3个字节。

数字
	tinyint,int整数类型
	float,double小数类型
	numeric(5,2) decimal(5,2)—也可以表示小数,表示总共5位,其中可以有两位小数
	decimal和numeric表示精确的整数数字。

日期
	date 包含年月日
	time时分秒
	datetime包含年月日和时分秒
	timestamp时间戳,不是日期,而是从1970年1月1日到指定日期的毫秒数。

图片
	blob 二进制数据,有4中类型,可以存放图片、声音,容量4g。早期有这样的设计。
	但其缺点非常明显,数据库庞大,备份缓慢,这些内容去备份多份价值不大。
	在数据库迁移时过大,迁移时间过久。所以目前主流都不会直接存储这样的数据,
	而只存储其访问路径,文件则存放在磁盘上。

在这里插入图片描述

1.创建表:
create table 表名(字段1,字段2,...);
字段1:字段名称 字段类型(字段长度)。
如: create table tb1 (id int(10)) charset utf8 ;
create table tb_door(id int(11),name varchar(100),tel varchar(20),address text(40));
2.查看所有表:
 mysql> show tables;
+-----------------+
| Tables_in_jasdb |
+-----------------+
| tb_door         |
| tb_order        |
| test1           |
+-----------------+

2.1:查看表结构:
mysql> desc tb_door;
+-------+--------------+------+-----+---------+-------+
| Field | Type         | Null | Key | Default | Extra |
+-------+--------------+------+-----+---------+-------+
| id    | int(11)      | YES  |     | NULL    |       |
| name  | varchar(100) | YES  |     | NULL    |       |
| tel   | varchar(20)  | YES  |     | NULL    |       |
| money | decimal(7,2) | YES  |     | NULL    |       |
+-------+--------------+------+-----+---------+-------+

 mysql>SHOW CREATE TABLE tb_door;
+---------+------------------------+
| Table   | Create Table                                                                                                                                                                                                                                                                         |
+---------+-------------------------+
| tb_door | CREATE TABLE `tb_door` (
  `id1` int(9) DEFAULT NULL,
  `id2` int(3) DEFAULT NULL,
  `name` varchar(100) DEFAULT NULL,
  `tel` varchar(20) DEFAULT NULL,
  `id` char(11) DEFAULT NULL,
  `id4` int(8) DEFAULT NULL,
  UNIQUE KEY `id` (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 |
+---------+-----------------------------+


3.修改表的列:
3.1添加列(add)alter table tb_door add column money numeric(7,2);
修改   表     表名   添加 列/字段  列名  列的类型  7是数字的个数,2是小数的为数
                              
开头添加:
alter table tb_door add id1 int(3) first; #first关键字放在语句的末尾。

中间位置添加:
注意,只能在某个已有字段的后面添加新字段,不能在它的前面添加新字段
ALTER TABLE 表名 ADD 新字段名 数据类型 [约束条件] AFTER 已经存在的字段名;
alter table tb_door add id2 int(3) after id1;

3.2删除列(drop)alter table tb_door drop column  money ;
修改   表     表名    删除 列       列名

一次删除多个列:
alter table tb_door drop id,name,tel,....;

删除check约束(检查约束)的列:(需要先删除约束后删除列)
alter table 表名 drop constraint 约束名;
alter table 表名 drop column 列名;

3.3修改列(modify)alter table 表名 modify  列名 列的类型( 列的约束);
alter table student modify sex varchar(2);

修改列名(change)
alter table 表名 change  列名 新的列名 列的类型( 列的约束);
alter table student change sex gender varchar(2);

3a:修改表名:
#修改表名的语法:alter table rename to/as new_tablename;
alter table tb1 rename to tb2;  

3b:修改表的字符集
alter table 表名 character set 字符集
alter table student character set gbk;
4.删除表:
```sql
drop (删除表):删除内容和定义,释放空间。
简单来说就是把整个表去掉.以后要新增数据是不可能的,除非新增一个表。
drop table tb_door;

truncate (清空表中的数据):
删除内容、释放空间但不删除定义(保留表的数据结构),drop不同的是,只是清空表数据而已。
truncate table 表名称 ;

执行速度,一般来说: drop> truncate > delete
5.表字段约束(constraints);
五大约束
1.-主键约束(Primay Key Coustraint)主键列的数据: 唯一性,非空性
2.-唯一约束 (Unique Counstraint)唯一性,可以空,但只能有一个
3.-检查约束 (Check Counstraint) 对该列数据的范围、格式的限制(如:年龄、性别等)
4.-默认约束 (Default Counstraint) 该数据的默认值,如男性较多默认设置为男
5.-外键约束 (Foreign Key Counstraint) 需要建立两表间的关系并引用主表的列

alter table 表名 
add constraint 列名 约束名;

[主键约束PK]primary key 
alter table abc add column id int(20) primary key(id);

1.新建一数据表,里面有字段id,将id设为为主键 
mysql> create table g(
	#字段名 字段类型 主键        自增
    -> id int    primary key  auto_increment,
    -> name varchar(100),
    -> age int
    -> );				
mysql> insert into g values(null,'Reimu',18); #主键的值不用自己设置null,数据库会自增
mysql> select * from g;
+----+------+------+
| id | name | age  |
+----+------+------+
|  1 | Reimu|   18 |
+----+------+------+


[唯一性约束]unique
alter table tb_door add column id char(11) unique; 

create table d(
tel  char(11)  unique  #唯一约束
);
insert into d values('12345678911');
insert into d values('12345678911');#报错,值相同


[检查约束]check
#与版本有关,有时未必会生效
alter table tb_door
add constraint age check(age between 15 and 40);#检查约束,数据在15-40保存
-- 数据需要满足检查条件才执行相对应的SQL语句。
CREATE TABLE b(
id INT PRIMARY KEY AUTO_INCREMENT,
age INT,
CHECK(age<200 AND age>0) #检查约束
);


[默认约束]default
alter table tb_door
add constraint address default('#') for address;

-- 给字段设置默认值而不是有默认的null
CREATE TABLE a(
id INT PRIMARY KEY AUTO_INCREMENT,
sex VARCHAR(10) DEFAULT '男' #默认约束
);

[外键约束 FK] foreign key(a) references(b)
#外键约束:防止了冗余的数据,通过外键来描述两张表的关系
#特点是:当子表中添加数据时,子表的主键值必须取自主表,当主表删除数据时,子表没有相关的记录
alter table tb_door
add constraint age foreign key(age1) references tel(age1);


[非空约束 ]not null
哪个字段添加了非空约束,该字段值不能为空,使用not null
mysql> create table b(
 	-> password varchar(100) not null  #给字段添加非空约束
    -> );
mysql> insert into b values('abc');  #password字段设置了值,执行OK
mysql> insert into b values(null); #password字段值不能设置成null,否则不符合非空约束,报错!

约束分类:
非空约束 not null;唯一约束 unique;主键约束 primary key;外键约束 foreign key;默认约束 default;检查约束 check




三:表内容:

对数据进行增查改删(crud):增加(Create),查询(Retrieve),更新(Update),删除(Delete)

1:查询tb_door表中的所有记录:
1.1#select 列名 from 表名;
SELECT * FROM tb_door;#查询所有列
SELECT dname FROM tb_door; #查询时使用字段名代替了*
SELECT 一列 二列  FROM emp;#二列显示的内容被一列替换
SELECT dname,loc FROM tb_door; #查询多个字段的值时用逗号隔开
SELECT empno a FROM emp; #设置别名为a,列名后用空格隔开
SELECT ename 匹配 FROM emp;

1.2:查询tb_door表中的总记录数
select count(*) from tb_door;
select count(1) from tb_door;
SELECT COUNT(*) FROM emp WHERE job='员工';
SELECT 1 FROM table WHERE job='员工' LIMIT 1;
#改用LIMIT 1,让数据库查询时遇到一条就返回,不要再继续查 


1.3:条件查询
1.3.1:去重distinct
mysql> SELECT DISTINCT loc FROM dept; #查询部门的地址
+-------+
| loc   |
+-------+
| 一区  |
| 一区1 |
+-------+
1.3.2where链接查询的条件
#select 字段名1 from 表名2 where 字段名=字段值3;

#1.查询编号为1的部门信息
SELECT *FROM dept WHERE deptno=1;#等于
SELECT *FROM dept WHERE deptno>1; #大于
SELECT *FROM dept WHERE deptno<2;#小于
SELECT *FROM dept WHERE deptno!=1; #不等
SELECT *FROM dept WHERE deptno<>1; #表示!=,同上
#统计2019年以前入职的员工信息
SELECT * FROM emp WHERE hiredate<'2019-1-1';
SELECT * FROM emp WHERE YEAR(hiredate)<2019;

#2.查询名称为一号的部门编号
SELECT deptno FROM dept WHERE dnane='一号';

#3.查询部门地址为二区,编号为3的部门名称
SELECT dname FROM dept WHERE loc='二区' AND deptno=3 #并且关系
SELECT dname FROM dept WHERE loc='二区' OR deptno=3 #或者关系

#3.1查询工资范围在5000~10000内的员工信息
SELECT * FROM emp WHERE sal>5000 AND sal<10000 #(5000,10000)
SELECT * FROM emp WHERE sal BETWEEN 5000 AND 10000 #[5000,10000]

#4.查询部门名称为一号2,一号3的部门地址
SELECT loc FROM dept WHERE dname IN('一号2','一号3');
SELECT * FROM dept WHERE deptno NOT IN(10,20,30);

1.3.3like模糊查询
通配符-->%:代表0-n个字符
通配符-->_(下划线):代表1个字符
 #查询名字包含a的员工信息
 #查询名字包含a的员工信息
 SELECT *FROM emp WHERE ename LIKE 'a%'; #以a开头,查询效率最高
 SELECT *FROM emp WHERE ename LIKE '%a%'; #中间包含a
 SELECT *FROM emp WHERE ename LIKE '%a'; #以a结尾
 SELECT *FROM emp WHERE ename LIKE 'a_'; #a后面只有一个字符
 
1.3.4between..and:查询
SELECT *FROM emp WHERE hiredate BETWEEN '2017-1-1' AND '2019-12-31';
SELECT *FROM emp WHERE YEAR (hiredate)>=2017 AND YEAR(hiredate)<=2019;

 1.4:limit:分页,限制数据展示的条目
 SELECT *FROM emp LIMIT n;#显示前n条数据
 SELECT *FROM emp LIMIT n,m;#n-->从第n+1条开始,m-->查询几条数据
#展示两条员工信息
SELECT * FROM emp LIMIT 2 #取前几条
SELECT * FROM emp LIMIT 2,3#从n+1条数据开始展示,总共展示的条数

1.5:order by:排序,默认升序asc,降序DESC--字典顺序
SELECT * FROM emp ORDER BY sal ASC #按照sal排序,默认升序
SELECT * FROM emp ORDER BY sal DESC #降序
SELECT * FROM emp ORDER BY ename #按照字母升序顺序
SELECT * FROM emp ORDER BY hiredate #按照数字大小升序排
SELECT * FROM emp ORDER BY job; #汉字排序时会查utf8里对应的数字,按照数字升序排序
2.修改tb_door表中id为1的记录
update tb_door set tel=555 where id=1;
3.删除tb_door表中id为2的数据
Delete from tb_door where id=2;
DELETE FROM USER WHERE id BETWEEN 1 AND 5;#删除表中1到5行的记录
DELETE FROM USER WHERE id DESC LIMIT 5;#倒叙排序后删除前五条的记录
DELETE FROM USER WHERE id ASC LIMIT 5;#正序排序后删除前五条记录
4.向tb_door表中添加记录
insert into tb_door values(null,'四季',666);
插入数据     表名      赋值  与表里的字段相对应

--  对sql使用的事物进行优化,mysql需要开启两个事物,浪费了时间和资源。
INSERT INTO userjas VALUE(NULL,'博丽灵梦',123);
INSERT INTO userjas VALUE(NULL,'雾雨魔理沙',123);

-- 批量插入,一次执行多个高效,但全对才插入
INSERT INTO userjas VALUE
(NULL,'早苗',123),
(NULL,'文',123);

-- 只给指定字段设置值,其它字段使用默认值
insert into userjas (loc) values ('东风谷');
INSERT INTO userjas (id,NAME) VALUES (9,'琪露诺');




四:注释:

单行注释可以使用#注释符,#注释符后直接加注释内容。
格式: #注释内容

单行注释可以使用--注释符,--注释符后需要加一个或多个空格,注释才能生效。如下:
格式: -- 注释内容

多行注释使用/* */注释符。
/*
  第一行注释内容
  第二行注释内容
*/




五:基础函数:

#基础函数
1.转大写(upper)SELECT ename,UPPER(ename) '大写' FROM emp;#
SELECT UPPER(ename) FROM emp;
2.转小写(lower)SELECT LOWER(ename) FROM emp;

#upper(a)把a的值变大写,lower(a)把a的值变小写
SELECT dname,UPPER(dname),LOWER('ABC'),LOWER(dname) FROM dept;

3.查询长度(length)#在utf8中,一个字母/数字长度为1,一个汉字长度为3
length(a);
SELECT ename,LENGTH(ename) FROM emp;
SELECT ename,job,LENGTH(job) FROM emp;

mysql> SELECT ename,LENGTH(ename),job,LENGTH(job) FROM emp;
+-------+---------------+------+-------------+
| ename | LENGTH(ename) | job  | LENGTH(job) |
+-------+---------------+------+-------------+
| jack  |             4 | ??   |           6 |
| TOMY  |             4 | ??   |           6 |
| ha    |             2 | ???  |           9 |
| leo   |             3 | ??   |           6 |
| liu   |             3 | ??   |           6 |
+-------+---------------+------+-------------+

mysql> set character_set_results=gbk;#修改编码
mysql> SELECT ename,LENGTH(ename),job,LENGTH(job) FROM emp;
+-------+---------------+--------+-------------+
| ename | LENGTH(ename) | job    | LENGTH(job) |
+-------+---------------+--------+-------------+
| jack  |             4 | 副总   |           6 |
| TOMY  |             4 | 总监   |           6 |
| ha    |             2 | 总经理 |           9 |
| leo   |             3 | 员工   |           6 |
| liu   |             3 | 员工   |           6 |
+-------+---------------+--------+-------------+

4.截取字符串(substr)#substr(a,b)-->a是截取谁,b是从那个字符开始
#substr(a,b,c)-->a是截取谁,b是从那个字符开始,c是截取的长度
SELECT ename ,SUBSTR(ename,2) FROM emp;
SELECT ename ,SUBSTR(ename,2,1) FROM emp;

mysql> SELECT ename,SUBSTR(ename,2),SUBSTR(ename,2,1) FROM emp ;
+-------+-----------------+-------------------+
| ename | SUBSTR(ename,2) | SUBSTR(ename,2,1) |
+-------+-----------------+-------------------+
| jack  | ack             | a                 |
| TOMY  | OMY             | O                 |
| ha    | a               | a                 |
| leo   | eo              | e                 |
| liu   | iu              | i                 |
+-------+-----------------+-------------------+
  
5.拼接字符串
#concat(a,b,c)-a是字段名,b是想要拼接的内容,c是想要拼接的内容
SELECT ename,CONCAT(ename,123)FROM emp
mysql> SELECT ename,CONCAT (ename,23,'hello') FROM emp;
+-------+---------------------------+
| ename | CONCAT (ename,23,'hello') |
+-------+---------------------------+
| jack  | jack23hello               |
| TOMY  | TOMY23hello               |
| ha    | ha23hello                 |
| leo   | leo23hello                |
| liu   | liu23hello                |
+-------+---------------------------+

6.替换字符:
#replace(a,b,c)-a是字段名,b是要被替换的字符,c是新数据
#replace(str,from_str,to_str)#字符存在就会被替换,可以加入限制
SELECT dname,REPLACE(dname,'o','666') FROM dept
SELECT ename,REPLACE (ename,'ha','helka') FROM emp

mysql> SELECT ename, REPLACE (ename,'a','34')FROM emp;
+-------+--------------------------+
| ename | REPLACE (ename,'a','34') |
+-------+--------------------------+
| jack  | j34ck                    |
| TOMY  | TOMY                     |
| ha    | h34                      |
| leo   | leo                      |
| liu   | liu                      |
+-------+--------------------------+

mysql> SELECT ename, REPLACE (ename,'a','34')FROM emp WHERE empno=300;
+-------+--------------------------+
| ename | REPLACE (ename,'a','34') |
+-------+--------------------------+
| ha    | h34                      |
+-------+--------------------------+

7.替换空值
#ifnull(a,b)-a是字段名,b是要把null替换成的值
mysql> SELECT comm,IFNULL(comm,1000) FROM emp;
+--------+-------------------+
| comm   | IFNULL(comm,1000) |
+--------+-------------------+
|   NULL |              1000 |
|   2000 |              2000 |
|   1000 |              1000 |
| 200.12 |            200.12 |
| 200.58 |            200.58 |
+--------+-------------------+

8.数值的运算
mysql> SELECT sal,comm,sal+comm FROM emp;
+-------+--------+----------+
| sal   | comm   | sal+comm |
+-------+--------+----------+
| 90000 |   NULL |     NULL |
| 10000 |   2000 |    12000 |
|  8000 |   1000 |     9000 |
|  3000 | 200.12 |  3200.12 |
|  3500 | 200.58 |  3700.58 |
+-------+--------+----------+

mysql> SELECT sal,comm,sal+ IFNULL(comm,0) FROM emp;#为空赋值0
+-------+--------+---------------------+
| sal   | comm   | sal+ IFNULL(comm,0) |
+-------+--------+---------------------+
| 90000 |   NULL |               90000 |
| 10000 |   2000 |               12000 |
|  8000 |   1000 |                9000 |
|  3000 | 200.12 |             3200.12 |
|  3500 | 200.58 |             3700.58 |
+-------+--------+---------------------+

#对小数的处理:
round-->四舍五入取整
SELECT comm,ROUND(comm) FROM emp;#取整
SELECT comm,ROUND(comm,1) FROM emp;#保留1位小数

ceil-->向上取整 
mysql> SELECT comm,CEIL(comm) FROM emp;#向上取整

floor-->向下取整
mysql> SELECT comm,FLOOR(comm) FROM emp;#向下取整

mysql> SELECT comm,ROUND(comm),CEIL(comm),FLOOR(comm) FROM emp;
+--------+-------------+------------+-------------+
| comm   | ROUND(comm) | CEIL(comm) | FLOOR(comm) |
+--------+-------------+------------+-------------+
|   NULL |        NULL |       NULL |        NULL |
|   2000 |        2000 |       2000 |        2000 |
|   1000 |        1000 |       1000 |        1000 |
| 200.12 |         200 |        201 |         200 |
| 200.58 |         201 |        201 |         200 |
+--------+-------------+------------+-------------+

9.对日期的处理
mysql> SELECT NOW();#2021-11-01 15:53:15 
mysql> SELECT YEAR('2021-11-1');#2021
#对日期的处理:now获取当前系统时间,year获取年,month获取月,day获取天
mysql> SELECT NOW(),YEAR(NOW()),MONTH(NOW()),DAY(NOW());
+---------------------+-------------+--------------+------------+
| NOW()               | YEAR(NOW()) | MONTH(NOW()) | DAY(NOW()) |
+---------------------+-------------+--------------+------------+
| 2021-11-01 15:54:32 |        2021 |           11 |          1 |
+---------------------+-------------+--------------+------------+

#对日期的处理:HOUR获取时,MINUTE获取分,SECOND获取秒
mysql> SELECT NOW(),HOUR(NOW()),MINUTE(NOW()),SECOND(NOW());
+---------------------+-------------+---------------+---------------+
| NOW()               | HOUR(NOW()) | MINUTE(NOW()) | SECOND(NOW()) |
+---------------------+-------------+---------------+---------------+
| 2021-11-01 15:54:55 |          15 |            54 |            55 |
+---------------------+-------------+---------------+---------------+

10.生成一个 32位的唯一id
mysql>  SELECT UUID();
+--------------------------------------+
| UUID()                               |
+--------------------------------------+
| 8185eac7-3aec-11ec-9518-ec8eb573f8cb |
+--------------------------------------+

11.转义符号:\,'当为普通的字符使用而不是字符串的标记。
 SELECT 'xi'an';
 SELECT "xi'an";
mysql>  SELECT 'xi\'an';
+-------+
| xi'an |
+-------+
| xi'an |
+-------+



12.其他

数值型函数
函数名称 作 用
ABS 求绝对值
SQRT 求二次方根
MOD 求余数
CEIL 和 CEILING 两个函数功能相同,都是返回不小于参数的最小整数,即向上取整
FLOOR 向下取整,返回值转化为一个BIGINT
RAND 生成一个0~1之间的随机数,传入整数参数是,用来产生重复序列
ROUND 对所传参数进行四舍五入
SIGN 返回参数的符号
POW 和 POWER 两个函数的功能相同,都是所传参数的次方的结果值
SIN 求正弦值
ASIN 求反正弦值,与函数 SIN 互为反函数
COS 求余弦值
ACOS 求反余弦值,与函数 COS 互为反函数
TAN 求正切值
ATAN 求反正切值,与函数 TAN 互为反函数
COT 求余切值
字符串函数
函数名称 作 用
LENGTH 计算字符串长度函数,返回字符串的字节长度
CONCAT 合并字符串函数,返回结果为连接参数产生的字符串,参数可以使一个或多个
INSERT 替换字符串函数
LOWER 将字符串中的字母转换为小写
UPPER 将字符串中的字母转换为大写
LEFT 从左侧字截取符串,返回字符串左边的若干个字符
RIGHT 从右侧字截取符串,返回字符串右边的若干个字符
TRIM 删除字符串左右两侧的空格
REPLACE 字符串替换函数,返回替换后的新字符串
SUBSTRING 截取字符串,返回从指定位置开始的指定长度的字符换
REVERSE 字符串反转(逆序)函数,返回与原始字符串顺序相反的字符串
日期和时间函数
函数名称 作 用
CURDATE 和 CURRENT_DATE 两个函数作用相同,返回当前系统的日期值
CURTIME 和 CURRENT_TIME 两个函数作用相同,返回当前系统的时间值
NOW 和 SYSDATE 两个函数作用相同,返回当前系统的日期和时间值
UNIX_TIMESTAMP 获取UNIX时间戳函数,返回一个以 UNIX 时间戳为基础的无符号整数
FROM_UNIXTIME 将 UNIX 时间戳转换为时间格式,与UNIX_TIMESTAMP互为反函数
MONTH 获取指定日期中的月份
MONTHNAME 获取指定日期中的月份英文名称
DAYNAME 获取指定曰期对应的星期几的英文名称
DAYOFWEEK 获取指定日期对应的一周的索引位置值
WEEK 获取指定日期是一年中的第几周,返回值的范围是否为 0〜52 或 1〜53
DAYOFYEAR 获取指定曰期是一年中的第几天,返回值范围是1~366
DAYOFMONTH 获取指定日期是一个月中是第几天,返回值范围是1~31
YEAR 获取年份,返回值范围是 1970〜2069
TIME_TO_SEC 将时间参数转换为秒数
SEC_TO_TIME 将秒数转换为时间,与TIME_TO_SEC 互为反函数
DATE_ADD 和 ADDDATE 两个函数功能相同,都是向日期添加指定的时间间隔
DATE_SUB 和 SUBDATE 两个函数功能相同,都是向日期减去指定的时间间隔
ADDTIME 时间加法运算,在原始时间上添加指定的时间
SUBTIME 时间减法运算,在原始时间上减去指定的时间
DATEDIFF 获取两个日期之间间隔,返回参数 1 减去参数 2 的值
DATE_FORMAT 格式化指定的日期,根据参数返回指定格式的值
WEEKDAY 获取指定日期在一周内的对应的工作日索引
聚合函数
函数名称 作 用
MAX 查询指定列的最大值
MIN 查询指定列的最小值
COUNT 统计查询结果的行数
SUM 求和,返回指定列的总和
AVG 求平均值,返回指定列数据的平均值
#统计查询格式:
SELECTFROM ? COUNT(?) FROM ? 
WHERE ? 
GROUP BY ?  #分组:查询时出现混合列,按非聚合列分组。
HAVING ?

SELECT AVG(sal),ename FROM emp WHERE depton=2;#报错,聚合列和费聚合列混合
进行分组解决:
查询结果当中出现了混合列,包含聚合列和非聚合列时必须分组。
通常按照非聚合列分组。
SELECT AVG(sal),ename FROM emp GROUP BY deptno;

#having:
-- 5统计每个岗位的平均薪资,只要>=10000的
SELECT AVG(sal) a,job FROM emp
#where avg(sal)>=10000
#where a>1000   #where里面不能用别名,也不能出现聚合函数
GROUP BY job #按照非聚合列分组
HAVING a>=10000 ;#分组后的过滤,a是别名

-- 6统计每年入职的人数,只要19年的
SELECT YEAR(hiredate) a,COUNT(1) FROM emp
GROUP BY a  #按照非聚合列分组
HAVING a=2019;  #

SELECT YEAR(hiredate) a,COUNT(1) FROM emp
WHERE YEAR(hiredate)=2019
GROUP BY YEAR(hiredate);

/*
where的执行顺序,执行时机先于having,所以where比having高效。
*/






流程控制函数
函数名称 作 用
IF 判断,流程控制
IFNULL 判断是否为空
CASE 搜索语句







六:拓展

1.事务(transaction)
 概念:
 数据库的事务(Database Transaction):是指作为单个逻辑工作单元执行的一系列操作,只有全都执行或者都不执行。
 即:事务就是将一堆的SQL语句(通常是增删改操作)绑定在一起执行,要么都执行成功,要么都执行失败,即都执行成功
 才算成功,否则就会恢复到这堆SQL执行之前的状态。
 
 事务的四个特性(ACID)
   一般来说,事务是必须满足4个条件(ACID):原子性(Atomicity,或称不可分割性)、一致性(Consistency)、
   隔离性(Isolation,又称独立性)、持久性(Durability)。
   
	原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。
	事务在执行过程中如果发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。
	
	一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的
	预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。
	
	隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于
	交叉执行而导致数据的不一致。
	
	持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

 隔离级别:
	读未提交(Read uncommitted):安全性最差,可能发生并发数据问题,性能最好;
	读提交(read committed): Oracle默认的隔离级别,性能较差,安全性较好;
	可重复读(repeatable read):MySQL默认的隔离级别,安全性较好,性能一般;
	串行化(Serializable): 表级锁,读写都加锁,效率低下,安全性高,不能并发。
	从上到下,性能越来越差,安全性越来越好。
 
 查询mysql的隔离级别
 在默认情况下,MySQL每执行一条SQL语句,都是一个单独的事务。如果需要在一个事务
 中包含多条SQL语句,那么需要手动开启事务和结束事务。

请添加图片描述

#开启事务:
start transaction;

#处理事务:
在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务;
事务处理可以用来维护数据的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行;
事务用来管理 insertupdatedelete 语句,因为这些操作才会“破坏”数据,查询select语句是不会的;
MySQL默认数据库的事务是开启的,执行SQL后自动提交。
MySQL的事务也可以改成手动提交,那就有两个步骤:先开启,写完SQL后,再手动提交。

#结束事务:
commit(提交事务)#多条语句时,批量执行,事务提交,有了事务,多步操作就形成了原子性操作,高并发下也不会引起数据错乱
BEGIN; #关闭事务的自动提交,相当于start transaction
INSERT INTO user (id) VALUES(25);#成功
INSERT INTO user (id) VALUES(5);#已经存在5了,会失败
COMMIT; #手动提交事务。

rollback(回滚事务)#多条语句,批量执行,insert插入重复的主键导致失败时,事务回滚
BEGIN;
INSERT INTO user (id) VALUES(15);
INSERT INTO user (id) VALUES(35);#存在了
ROLLBACK;#事务回滚,就不会再提交了


mysql> start transaction;
Query OK, 0 rows affected (0.00 sec)


mysql> SELECT @@tx_isolation;
+-----------------+
| @@tx_isolation  |
+-----------------+
| REPEATABLE-READ |
+-----------------+
MySQL的默认事务隔离级别,它确保同一事务的多个实例在并发读取数据时,会看到同样的数据行。
2.多表联查(重点)1.笛卡尔积即直集,用逗号隔开多张表
查询过程中,先在内存中构建一个大大的结果集,然后再进行数据的过滤。那这个
构建过程,和所使用的内存资源,包括过滤时的判断,都是既耗费资源,又浪费时间,所以一般都是禁止3张表以上的联查。

SELECT * FROM dept,emp;
SELECT * FROM dept,emp 
WHERE dept.deptno=emp.deptno; #描述两个表的关系

#1.查询部门名称和员工表的所有数据
SELECT dname 部门名称,emp.* FROM dept,emp
WHERE dept.deptno=emp.deptno;

#2.查询部门的所有和员工的名字,只要部门的名称叫一号
SELECT dept.*,emp.ename FROM dept,emp
WHERE dept.deptno=emp.deptno
AND dept.dname='一号';

#3.查询所有部门和员工的数据,条件是部门编号>1
SELECT * FROM dept,emp
WHERE dept.deptno=emp.deptno #表关系
AND emp.deptno>1; #业务条件

#4.查询课程表和老师表的所有数据,只要王老师的数据
SELECT * FROM courses,teachers
WHERE courses.tno=teachers.tno
AND teachers.tname LIKE '王%';

#5.查询计算机导论课程的总分
SELECT SUM(degree) FROM scores,courses
WHERE courses.cno=scores.cno
AND courses.cname='计算机导论';

-- 2.连接查询,用join连接多张表
SELECT * FROM dept JOIN emp;
SELECT * FROM dept JOIN emp
ON dept.deptno=emp.deptno;

#1.查询部门名称和员工表的所有数据
SELECT dname 部门名称,emp.* FROM dept JOIN emp
ON dept.deptno=emp.deptno;

#2.查询部门的所有和员工的名字,只要部门的名称叫一号
SELECT dept.*,emp.ename FROM dept JOIN emp
ON dept.deptno=emp.deptno
WHERE dept.dname='一号';

#3.查询所有部门和员工的数据,条件是部门编号>1
SELECT * FROM dept JOIN emp
ON dept.deptno=emp.deptno #表关系
WHERE emp.deptno>1; #业务条件

#4.查询课程表和老师表的所有数据,只要王老师的数据
SELECT * FROM courses,teachers
ON courses.tno=teachers.tno
WHERE teachers.tname LIKE '王%';

#5.查询计算机导论课程的总分
SELECT SUM(degree) FROM scores,courses
ON courses.cno=scores.cno
WHERE courses.cname='计算机导论';


测试 三种连接的区别????
有两种连接查询:内连接和外连接(左外连接,右外连接)
inner join:取两张表的交集
left join:左边表的所有和右边满足条件的,不满足的添加null
right join:右边表的所有和左边满足条件的,不满足的添加null
连接查询的效率:小表驱动大表,
把结构简单或者数据量少的表放在前面作为左表
因为左表会查所有数据,右表只查满足了条件的那些数据
   

-- 2.1.左连接(lift join)
#取左边的所有内容和右边满足条件的,不满足的添加null
SELECT * FROM dept LEFT JOIN emp
ON dept.deptno=emp.deptno;

-- 2.2.右链接(right join)
#取右边表的所有内容和左边表满足条件的,不满足的添加null。
SELECT * FROM emp RIGHT JOIN dept
ON dept.deptno=emp.deptno;

-- 2.3.内连接(inner join)
#取交集,取左右表都满足的条件
SELECT *FROM  dept INNER JOIN emp
ON dept.deptno=emp.deptno;


-- 子查询(subquery): 
#概念:子查询是指嵌入在其他select语句中的select语句,也叫嵌套查询。
#子查询执行效率低慎用。记录少时效率影响不大、图方便直接使用,记录多时最好使用其它方式替代。
-- 1.单行子查询用= ;多行子查询:in
#子查询:第一次要查的内容,第二次要查的内容
-- 第一次查询的结果作为第二次的条件
# 1.查询计算机导论课程的总分
#第一次查:根据cname查到cno为3-105
SELECT cno FROM courses WHERE cname='计算机导论';
#第二次查:根据cno查该课程的总分
SELECT SUM(degree) FROM scores WHERE cno='3-105';
#改为子查询即嵌套查询
SELECT SUM(degree) FROM scores WHERE cno=(
SELECT cno FROM courses WHERE cname='计算机导论'
);

#2.查询易天老师能讲的课程名称
SELECT tno FROM teachers WHERE tname='易天';
SELECT cname FROM courses WHERE tno=804;
SELECT cname FROM courses WHERE tno=(
SELECT tno FROM teachers WHERE tname='易天'
);

#3.查询accounting部门员工的名字
SELECT ename FROM emp WHERE deptno=(
SELECT deptno FROM dept WHERE dname='accounting'
);

#4.查询在二区办公的员工名字
-- SQL错误(1242):Subquery returns more than 1 row;
-- 即子查询返回多于1行:这时需要用in
SELECT ename FROM emp WHERE deptno in(
SELECT deptno FROM dept WHERE loc='二区'
);

#5.查询高于平均工资的员工信息。
SELECT * from emp WHERE sal>(
SELECT AVG(sal) FROM emp #平均工资
);

#总合
#1.查询 research部门的所有的员工和姓名
-- 1.笛卡尔积
SELECT emp.ename,emp.sal FROM dept,emp
where emp.deptno=dept.deptno
and dept.dname='research';
-- 2.链接查询
SELECT emp.ename,emp.sal FROM emp INNER JOIN dept
on emp.deptno=dept.deptno
where dept.dname='research';
-- 3.子查询
SELECT emp.ename,emp.sal FROM emp WHERE deptno=(
SELECT deptno FROM dept WHERE dname='research'
);

#2:查询李军的平均分
-- 1.笛卡尔积
SELECT AVG(scores.degree) FROM scores,students
WHERE students.sno=scores.sno
AND students.sname='李军';
-- 2.连接查询
SELECT AVG(scores.degree) FROM scores join students
ON  students.sno=scores.sno
WHERE  students.sname='李军';
-- 3.子查询:
SELECT AVG(scores.degree)FROM scores WHERE sno=(
SELECT sno  from students WHERE sname='李军'
);

#3:查询陈冰能讲的课程名
-- 1.笛卡尔积
SELECT courses.cname FROM courses,teachers
 WHERE courses.tno= teachers.tno 
 AND teachers.tname='陈冰';
 -- 2.连接查询
 SELECT courses.cname FROM courses join teachers
 on courses.tno= teachers.tno 
where teachers.tname='陈冰';
-- 3.子查询
SELECT cname FROM courses WHERE tno =(
SELECT tno FROM teachers WHERE tname='陈冰'
);
 
表关联 association

	定义:关联表代表了表与表之间的关系,它们之间形成了自己的一个小圈子。
			表的关系分类:
				一对一(one to one):公民与身份证号;
				一对多(one to many):最常见,部门和员工;
				多对一(mang to one):员工和部门;
				多对多(mang to many):老师和学生。
	设计方式:表以s结尾去标识复数;字段多以表的首字母为开头,在多联表查询时方便查询出和了解是那个表的字段。
	
			
3.索引 index
定义 :
	索引是一种排好序的快速查找的数据结构,它帮助数据库高效的进行数据的检索。在数据之外,数据库系统还维护着
	满足特定查找算法的数据结构(额外的存储空间),这些数据结构以某种方式指向数据,这样就可以在这些数据结构
	上实现高效的查找算法。这种数据结构就叫做索引。一般来说索引本身也很大,不可能全部存储在内存中,因此往往
	以索引文件的形式存放在磁盘中。目前大多数索引都采用BTree树方式构建。索引的作用相当于一本图书的目录,
	可以根据目录中的页码快速的查找到所需要的内容。一般在创建表时就添加索引,需要经常查询索引列的数据时,
	才需要在表中添加索引。
	
	优点:提高查询的效率,原则上使用索引一定高效;加速了表和表之间的连接;创建唯一索引时保证了数据表中
		每行的唯一性;使用分组或排序语句进行数据检索时,可以减少查询或分组排序的时间。
	缺点:本身使用单独的空间即需要占用物理空间,不能随处添加索引,对表中的数据进行添加修改和删除时,
		索引也需要动态的维护,降低了数据的维护速度。

 分类:	
单值索引(普通索引):一个索引只包括一个列,一个表可以有多个列;
唯一索引:索引列的值必须唯一不能重复,但允许有空值;主键会自动创建唯一索引;
主键索引:在表定义主键时会自动创建主键索引,主键索引是唯一索引的特定类型,可以获得最佳性能结果;
复合索引:一个索引同时包括多列;
候选索引,聚集索引,非聚集索引。
#索引
#步骤:1.创建索引   2.使用索引。
-- 1.查看索引
SHOW INDEX FROM 表名;
SHOW INDEX FROM emp;

-- 2.创建索引
#创建单值索引
CREATE INDEX 索引名 ON 表名(字段名);
CREATE INDEX ename_index ON emp(ename);
#创建唯一索引:一个索引包含一列,值要唯一
CREATE UNIQUE INDEX 索引名 ON 表名(字段名);
CREATE UNIQUE INDEX dname_index ON dept(dname);
#复合索引:
#一个索引包含多个字段,用时要遵循最左原则,否则复合索引失效
#失效的情况:按照 2 3 23 ,没有包含最左边的,应该为(1 12 13 123)
create index 索引名 on 表名(字段名1,字段名2,字段名3);
CREATE INDEX fuheindex ON emp(ename,job,deptno); 
EXPLAIN SELECT * FROM emp WHERE ename='jack' #生效
EXPLAIN SELECT * FROM emp WHERE job='总监' #失效
EXPLAIN SELECT * FROM emp WHERE ename='jack' AND job='副总' #生效
EXPLAIN SELECT * FROM emp WHERE job='副总'AND ename='jack'#生效
 
-- 3.使用索引,发起select语句
SELECT * FROM emp WHERE ename='jack1';
 
-- 4.观察是否使用了索引,检查SQL的执行效率,
--使用(explain),查看possible_key的字段的值
EXPLAIN SELECT * FROM emp WHERE ename='jack1';

-- 5.删除索引
alter table 表名 drop INDEX 索引名;
ALTER TABLE emp DROP INDEX jobindex;

4.视图View
 概念:
	是可视化的表,视图当做是一个特殊的表,把sql执行的结果,直接缓存到了视图中。
	下次还要发起相同的sql,直接查视图,现在使用的较少。
    #视图:
#步骤:创建视图+使用视图
/*
优点:提高了SQL语句的复用性;
屏蔽了业务表的复杂性;
数据共享;
缺点:浪费了空间;
一旦创建不能更改,无法优化empview;
是一张单独的表,且存放了业务表的数据造成了数据的重复。
*/
#查询名字里有a的员工信息
SELECT * FROM emp WHERE ename LIKE '%a%';

-- 1.创建视图
#CREATE VIEW 视图名 AS select语句;
CREATE VIEW empview AS
SELECT * FROM emp WHERE ename LIKE'%a%';

-- 2.使用视图
SELECT * FROM empview;






5.SQL优化

查询SQL尽量不要使用select *,而是具体字段
避免在where子句中使用or来连接条件
使用varchar代替char
尽量使用数值替代字符串类型
查询尽量避免返回大量数据,若数据量很大,通常采用分页,一页习惯10/20/50/100条。
使用explain分析你SQL执行计划,Explain主要看SQL是否使用了索引
是否使用了索引(index)及其扫描类型
创建name字段的索引,按名字查询的情况较多
优化like语句,模糊查询最好以确定的字符为开头进行查询(‘a%’),索引才会生效
字符串怪现象,数字加入单引号或双引号成为字符串之后索引才会生效
索引不宜太多,一般5个以内
索引不适合建在有大量重复数据的字段上
where限定查询的数据
避免在where中对字段进行表达式操作
避免在where子句中使用!=或<>操作符
去重distinct过滤字段要少
where中使用默认值代替null
批量插入性能提升
批量删除优化
伪删除设计
提高group by语句的效率
复合索引最左特性
排序字段创建索引
删除冗余和重复的索引
不要有超过5个以上的表连接
inner join 、left join、right join,优先使用inner join
in子查询的优化
尽量使用union all替代union




6.SQL需求:

需求 语句
查询所有记录
只查询指定列
查询id为?的记录
模糊查询记录
查询之间范围之间的所有记录
查询满足两个条件的记录
按?升序查询记录
以?升序、?降序查询记录
查询总数
聚合函数分组
max(?),min(?)
保留一位小数
合并重复内容
不合并重复内容
查询记录
从1位置(第二条)开始,总共取3条
7.SQL的执行顺序
(1) FROM [left_table] 选择表
(2) ON <join_condition> 链接条件
(3) <join_type> JOIN <right_table> 链接
(4) WHERE <where_condition> 条件过滤
(5) GROUP BY <group_by_list> 分组
(6) AGG_FUNC(column or expression),... 聚合
(7) HAVING <having_condition> 分组过滤
(8) SELECT (9) DISTINCT column,... 选择字段、去重
(9) ORDER BY <order_by_list> 排序
(10) LIMIT count OFFSET count; 分页

8.范式
定义:在数据库当中,设计数据库时要求遵循一定的规则,该规则为了让数据库更加优化合理,
符合某种关系级别的集合,该规则即范式。

三范式:
设计表时用到的一些范式即需要遵守的规则,
范式分为六种
第一范式(1NF):表里的字段,不可分割,指的是字段的值就是最小单位
第二范式(2NF):在第一范式的基础上产生,指的是表里都需要设计主键/主关键字/主属性,
			即非主属性完全依赖于主关键字。
第三范式(3NF):在第二范式的基础上产生,属性之间不应该去依赖别的表时表之间的关系太复杂,为了避免数据的冗余。

9.SQL攻击
–1,模拟SQL攻击的现象
//出现了问题:SQL攻击:
//1,本质上就是因为SQL中出现了特殊符号#,#号在SQL中是注释的意思(测试时使用固定的用户名jack’#),
//使得SQL的语义发生改变.
//2,Statement传输器在执行SQL时遇到了SQL拼接,把#当做了注释用!!
解决了问题:SQL攻击:
    //1,本质上就是因为SQL中出现了特殊符号#,当普通字符用而不是注释
    //2,PreparedStatement 传输器在执行SQL时遇到了SQL拼接时直接写?占位符
    //PreparedStatement好处:SQL简单,安全(解决SQL攻击),高效
    //模拟用户登录,从单元测试改成main()原因是IDEA单元测试方法无法键盘输入2,扩展: 程序优化
1.JDBC的前两步,重复的写了很多次,优化这种现象来提高代码的复用性/高内聚.
package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
//封装了注册驱动,获取连接.
//目的:获取连接,并返回给调用者
public class JDBCUtils {
    
    
    /**目的:获取连接,并返回给调用者 */
    static public Connection get() throws Exception{
    
    
        //1,注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2,获取连接
        String url="jdbc:mysql://localhost:3306/cgb2109?characterEncoding=utf8";
        Connection c = DriverManager.getConnection(url, "root", "root");
        return c; //返回给调用者
    }
}

package cn.tedu.jdbc;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
//需求:利用新的传输器,向dept表里插入数据
public class Test3 {
    
    
    public static void main(String[] args) throws Exception{
    
    
        //TODO  利用工具类里封装好的方法
        Connection c = JDBCUtils.get();
        //3,传输器
        String sql ="insert into dept values(null,?,?)";//SQL骨架
        PreparedStatement p = c.prepareStatement(sql);
        //设置SQL中的参数--给第几个?设置啥值
        p.setObject(1,"php开发部");
        p.setObject(2,"北京");
        //4,执行SQL
        p.executeUpdate();//执行增删改的SQL,返回影响行数
        //5,处理结果
        //6,释放资源
        c.close();
        p.close();
    }
}

2.更改
package Test;
import java.sql.Connection;
import java.sql.DriverManager;
 class JDBCutil {
    
    
    static public Connection get1() throws Exception {
    
    
        //1.注册驱动
        Class.forName("com.mysql.jdbc.Driver");
        //2.连接数据库
//jdbc:连接mysql数据库的协议//本机ip:端口号/数据库的名字?characterEncoding=编码
        Connection c = DriverManager.getConnection
                ("jdbc:mysql:///jasdb?characterEncoding=utf8", "root", "root");
        return c;
    }
}

import java.util.Scanner;
public class inpt {
    
    
    public static  String[] input(){
    
    
        System.out.println("输入用户名:");
        String str1=new Scanner(System.in).nextLine();
        System.out.println("输入密码:");
        String str2=new Scanner(System.in).nextLine();
        String[] s1={
    
    str1,str2};
        return s1;
    }
}

package Test;
import Inp.inpt;
import java.sql.*;
public class test1 {
    
    
    private Connection c;
    public static void main(String[] args) throws Exception {
    
    
        //1.解决SQL注入登录
        play1();
        //注册
      //  play2();
    }
    private static void play2() throws Exception {
    
    
        //调用工具类里封装好的方法
        Connection c = JDBCutil.get1();
        //3.获取传输器
        String sql="insert into user values(null,?,?)";
        PreparedStatement p = c.prepareStatement(sql);
        //以数组的形式调用类里的方法
        String[] saq= inpt.input();
        String use1=saq[0], pwd1=saq[1];
        //设置SQL中的参数
        p.setObject(1,use1);
        p.setObject(2,pwd1);

        //4.执行SQL语句
        //executeQuery();查询的SQL语句
      //executeUpdate();执行增删改的SQL语句
        p.executeUpdate();
        System.out.println("添加成功");

        //5.处理结果集
        //释放资源
        p.close();
        c.close();
    }

    private static void play1() throws Exception {
    
    
        //调用工具类
        Connection c = JDBCutil.get1();
        //3.获取传输器
        //3.1:会被SQL注入
        //Statement s = c.createStatement();
        //3.2:准备执行预编译的SQL
//        System.out.println("输入用户名:");
//        String name1=new Scanner(System.in).nextLine();
//        System.out.println("输入密码:");
//        String pwd1=new Scanner(System.in).nextLine();
        //以数组的形式调用类里的方法
        String[] saq = inpt.input();
        String name1 = saq[0], pwd1 = saq[1];
        String sql = "select * from user where name=? and pwd=?";
        //准备执行预编译的SQL
        PreparedStatement s = c.prepareStatement(sql);
        //设置SQL中的参数
        s.setObject(1, name1);//给第一个?  设置值
        s.setObject(2, pwd1);

        //4.执行SQL语句
        //s.executeQuery();//查询的SQL语句
        // s.executeUpdate();//执行增删改的SQL语句
        ResultSet r = s.executeQuery();
        //5.处理结果集
        Object o = r.getObject(1);
        System.out.println(o);
            //6.释放资源
            r.close();
            s.close();
            c.close();
        }
    }
}

相关信息

评论