MySql
CMD下Mysql的启动,链接,退出
Mysql启动
1.手动:cmd->services.msc->启动MySql
开启,关闭服务下两种在管理员权限下运行:
2.net stop mysql(停止服务)
3.net start mysql(开始服务)
Mysql登录
本机mysql -uroot -proot(mysql -u用户 -p密码)
远程mysql -hip -u链接目标的密码
通用:mysql --host=ip --user=root --password=连接目标的密码
举例:mysql --host=127.0.0.1 --user=root --password=root
Mysql退出
本机 exit
远程 quit
Mysql目录结构
安装目录
数据目录
Mysql语法
1.sql语句可以单行或多行书写,以;结尾
2.语句不区分大小写,关键字可以大写
3.单行注释与多行注释
单行:-- 注释内容,# 注释内容(注意--后跟一个空格,#可以不跟)
多行:/* */(与JAVA一样);
Mysql命令分类
DDL
1.操作数据库CRUD,增删改查
C:create创建
创建数据库: create database 数据库名字
create database if not exists 数据库名字;(如果存在就不创建了)
create database 数据库名字 character set gbk;
创建表:create 表名(列名1 数据类型1
列名2 数据类型2,
......
列名 n,数据类型n) //最后一列不加逗号;
复制表:create table 表名 like 表名
R:Retrieve 查询
查询所有的数据库的名称:show databases
查询某个数据库中的所有表名称:show tables
查询表结构:desc 表名
U:Update 修改
修改数据库的字符集:alter database 数据库名称 character set 字符集名
修改表名 alter table 表名 rename to 新的表名
修改表 的字符集 alter table 表名 character set 字符集格式;
添加一列:alter table 表名 add 列名 数据类型
修改列的名称和类型:
修改名称和类型 alter table 表名 change 列名 新列名 数据类型
修改类型 alter table 表名 modify 列名 新数据类型
D:delete删除
删除数据库: drop database 数据库名称
drop database if exists 数据库名称
删除表: drop table 表名
drop table if exists 表名
删除列:alter table 表名 drop 列名
使用数据库
查询当前正在使用的数据库:select database();
使用数据库: use 数据库名称;
Mysql里的数据类型
图形化编写MySQL
DML:增删改表中数据
添加数据
insert into 表名(列名1,列名2...列名n)values(值1,值2.....值n)
INSERT INTO ss(id NAME,age) VALUES(1,'mike',18);
省略列名将会给所有列添加值;但必须全部添加,否则会报错;
除了数字类型,其他类型需要使用引号(单双均可)引起来;
查询数据
select * from 表名(查询表中所有数据)
SELECT * FROM ss;
删除数据
delete from 表名[where 条件],不加where将删除表中所有记录;
SELECT * FROM ss;
清空表:truncate table 表名(首先删除表,再创建一个一模一样的空表);
修改数据
update 表名 set 列名1=值1,列名2=值2 [where 条件];不加任何条件会修改所有记录;
DQL
查询语句:
select
字段列表
from
表明列表
where
条件列表
group by
分组字段
having
分组之后的条件
order by
排序
limit
分页
基础查询
1.查询多个字段
select 字段名1 as 别名,字段名2....from 表名;
2.去除重复:使用distinct
select DISTINCT 字段名1,... FROM student4;
3.计算列
select 字段名1 +字段名2....from 表名;
排除null:select 字段名3,字段名1 +ifnull(字段名2,代替值)....from 表名;计算1,2的和;
4.起别名
在列后使用as,as可以省略;
SELECT NAME AS 数学,math +IFNULL(english,0)AS 总分 FROM student4;
条件查询
运算符:
>,<,>=,<=,=,!=,<>
between ... and...
in,like is null,and ,or ,not;
SELECT *FROM student4;
#大于20岁
SELECT * FROM student4 WHERE age>20;
#大于等于20
SELECT * FROM student4 WHERE age>=20;
#等于20岁
SELECT * FROM student4 WHERE age=20;
#不等于20岁
SELECT * FROM student4 WHERE age!=20;
#不等于20岁
SELECT * FROM student4 WHERE age<>20;
#小于20
SELECT * FROM student4 WHERE age<20;
#小于等于20
SELECT * FROM student4 WHERE age<=20;
#20~40岁之间
SELECT * FROM student4 WHERE age BETWEEN 20 AND 40;
SELECT * FROM student4 WHERE age>=20 AND age<=40;
#查询22岁,19岁,25岁的信息;或者
SELECT*FROM student4 WHERE age=22 OR age=19 OR age=25;
SELECT*FROM student4 WHERE age IN (22,19,23,25);
#查询null:null不能使用比较符来判断;使用is判断
SELECT*FROM student4 WHERE age IS NULL;
SELECT*FROM student4 WHERE age IS NOT NULL;
模糊查询:like;类似正则表达式;
格式:
举例
#查询姓马的人 SELECT NAME FROM student4 WHERE NAME LIKE '马%'; #查询第二个字是马的人 SELECT NAME FROM student4 WHERE NAME LIKE '_化%'; #查询姓名是三个字的人; SELECT NAME FROM student4 WHERE NAME LIKE '__'; #查询姓名中包含马的人 SELECT NAME FROM student4 WHERE NAME LIKE'%德%';
排序查询
语法:order by 子句
order by 排序字段1 排序方式1,排序字段2 排序方式2......
排序方式:升序(ASC)默认,DESC 降序;
多条件排序:如果有多个排序条件,则当前一个条件值一样时,才会判断第二条件;
#按照数学成绩排名,如果数学成绩一样则按照英语成绩排名
UPDATE student4 SET math=99 WHERE age=18; -- 修改
SELECT *FROM student4;
SELECT *FROM student4 ORDER BY math ASC,english ASC;
数学是第一条件,英语是第二条件
聚合函数
将一列数据作为整体进行纵向的计算;
count :计算个数
max:计算最大值
min:计算最小值
sum:计算和
avg:计算平均值
注意:聚合函数计算时排除null, 一般选择主键作为count的参数;
SELECT COUNT(NAME)FROM student4;
SELECT COUNT(IFNULL(NAME,0))FROM student4;
SELECT MAX(math)FROM student4;
SELECT SUM(math)FROM student4;
SELECT SUM(IFNULL(english,0))FROM student4;
SELECT AVG(english)FROM student4;
分组查询
语法:group by 分组字段,注意分组后查询的字段(select 之后的内容):聚合函数或者分组字段;
#按照性别分组,分别查询男,女同学的平均分
SELECT sex,AVG(math)FROM student4 GROUP BY sex;
复合语句:
#按性别分组,分别查询男女的平均分,要求:分数低于70的人,不参与分组;
SELECT sex,COUNT(id)FROM student4 WHERE math>50 GROUP BY sex;
分组之后继续划分: having子句,写在:“group by 分组字段”之后;
#按性别分组,分别查询男女的平均分,要求:分数低于70的人,不参与分组,分组之后人数要大于两个人;
SELECT sex,COUNT(id)FROM student4 WHERE math>50 GROUP BY sex HAVING COUNT(id)>2;
SELECT sex AS 性别 ,COUNT(id) AS 人数 FROM student4 WHERE math>50 GROUP BY sex HAVING 人数>2;
分页查询
语法:limit 开始的索引,每一页查询的条数;该语句是方言操作;
SELECT *FROM student4 LIMIT 0,3;从0开始,每一页显式3条数据
运行后结果:
开始的索引的计算公式:开始的索引=(当前页码-1)*查询条数;
约束
概念:对表中的数据进行限定,保证数据的正确性,有效性和完整性;
分类:
主键约束:primary key 含义:非空且唯一,此外一张表只能有一列为主键
非空约束:not null 某一列的值不能为null;
唯一约束:unique 某一列的值不能重复,可以为null,但只能有一个为null;
外键约束:foreign key 设计多张表的操作
非空约束添加方式
1.创建表时在列的后面加not null;
2.创建表后在后续修改列时添加或删除;即修改列命令:
修改名称和类型 alter table 表名 change 列名 新列名 数据类型
修改类型 alter table 表名 modify 列名 新数据类型
1.创建表时在列的后面加not null; CREATE TABLE stu1( id INT, NAME VARCHAR(20)NOT NULL -- name为非空; ); 2.后续修改列时添加或删除;即修改列命令 ALTER TABLE stu1 MODIFY NAME VARCHAR(20); ALTER TABLE stu1 MODIFY NAME VARCHAR(20) not null;
唯一约束添加方式
1.创建表时添加
2.创建表后在后续修改时添加或删除,注意:添加与非空约束一样,使用修改列命令,但删除使用drop index +列名的形式,即删除列的形式。
删除唯一约束:alter table 表名 drop index 列名
添加唯一约束: alter table 表名 modify 列名 新数据类型(在原数据类型后加上unique)
CREATE TABLE stu1( id INT, phone_number VARCHAR(20) UNIQUE-- 手机号应该是唯一的, ); INSERT INTO stu1(id,phone_number)VALUES(1,13839897109); #删除约束 ALTER TABLE stu1 DROP INDEX phone_number;-- 使用删除索引的形式,才能删除唯一约束 ALTER TABLE stu1 MODIFY phone_number VARCHAR(20);#无法删除唯一约束 #添加约束,与非空约束一样,使用修改列命令 ALTER TABLE stu1 MODIFY phone_number VARCHAR(20) UNIQUE;
主键约束添加方式
1.创建表时添加主键
2.创建表后在后续修改时添加或删除;
创建后删除:alter table 表名 drop primary key
创建后添加:alter table 表名 modify 列名 新数据类型(在原数据类型后加primary key)
#创建时添加主键
CREATE TABLE stu2 (
id INT PRIMARY KEY ,-- id是主键;
NAME VARCHAR(20)
);
SELECT *FROM stu2;
#创建后删除主键
ALTER TABLE stu2 MODIFY id INT PRIMARY KEY;
#创建后添加主键
ALTER TABLE stu2 DROP PRIMARY KEY;
主键约束-自动增长
1.创建表时,添加主键约束,并完成主键自增长;
2.创建表后,添加或删除自动增长;
删除:alter table 表名 modify 列名 新数据类型(原数据类型,不加auto_increment和primary_key)
添加:alter table 表名 modify 列名 新数据类型(原有数据类型后加auto_increment);
#创建时添加自动增长
CREATE TABLE stu3 (
id INT PRIMARY KEY AUTO_INCREMENT,#给id添加主键约束
NAME VARCHAR(20)
);
SELECT *FROM stu3;
#创建后删除
ALTER TABLE stu3 MODIFY id INT;
#创建后添加
ALTER TABLE stu3 MODIFY id INT AUTO_INCREMENT;
外键约束添加方式
1.创建表时添加外键约束,语法:
create table 表名(
......
外键列,
constraint 外键名 foreign key (外键列名称) references 主表名称(主表列名称);
);
外键名:本表明_主表名_fk
2.创建表后在后续修改时添加或删除外键约束
删除语法:alter table 表名 drop foreign key 外键名
添加外键:alter table 表名 add constraint 外键名 foreign key (外键列名称) references 主表名称(主表列名称)
级联操作:改变主表的内容,本表的内容也会改变;
级联更新,更新主表会影响本表,
级联删除,删除主表部分信息会删除本表包含主表被删除信息的行;
级联更新:
alter table 表名 add constraint 外键名 foreign key (外键列名称) references 主表名称(主表列名称)on update cascade
级联删除:
alter table 表名 add constraint 外键名 foreign key (外键列名称) references 主表名称(主表列名称)on delete cascade
级联删除是指在删除主表中的数据时,相应的在关联表中也会将相关数据一并删除的操作。例如,在删除stu表中id为2的学生时,由于sc表中有对应的成绩记录,级联删除会将stu表和sc表中对应的数据一起删除。
级联更新是指在更新主表中的数据时,相应的在关联表中也会将相关数据一并更新的操作。例如,在stu表中将id为3的学生更改为id为6时,由于sc表中有对应的成绩记录,级联更新会将stu表和sc表中对应的数据一起更新。
以上是在创建表时通过外键约束使用ON DELETE CASCADE和ON UPDATE CASCADE来实现级联删除和级联更新的示例。在创建stu表和sc表时,通过设置FOREIGN KEY (sid) REFERENCES stu(sid) ON DELETE CASCADE ON UPDATE CASCADE,当stu表中的数据被删除或更新时,sc表中相应的数据也会被删除或更新。
CREATE TABLE namer( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(32) ); DROP TABLE namer; INSERT INTO namer(id,NAME)VALUES(1,"董事部"),(2,"财务部"),(3,"研发部"); SELECT *FROM namer; CREATE TABLE stu6( id INT PRIMARY KEY AUTO_INCREMENT, NAME VARCHAR(21), pid INT, CONSTRAINT stu6_namer_fk FOREIGN KEY (pid)REFERENCES namer(id) ); DROP TABLE stu6; INSERT INTO stu6(id ,NAME,pid)VALUES(1,"小王",1),(2,"小张",1),(NULL,"小李",3); SELECT *FROM stu6; #删除外键 ALTER TABLE stu6 DROP FOREIGN KEY stu6_namer_fk; #添加外键,设置级联更新 ALTER TABLE stu6 ADD CONSTRAINT stu_namer_fl FOREIGN KEY(pid) REFERENCES namer(id) ON UPDATE CASCADE ON DELETE CASCADE;
数据库设计-多表设计
多表间的关系
一对一:人和身份证
一对多(多对一):部门和员工
多对多:学生和课程
一个学生有许多课程,一个课程有许多课程选择
一对多:添加外键来实现
员工与部门属于一对多,在员工内设置外键与部门的主键关联。
#一对多;员工与部门
CREATE TABLE dep(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20) UNIQUE
);
INSERT INTO dep(id,NAME)VALUES(1,"财务部"),(2,"销售部");
SELECT *FROM dep;
CREATE TABLE emp(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(20),
dept_id INT,
CONSTRAINT emp_dep_fk FOREIGN KEY (dept_id) REFERENCES dep (id) ON UPDATE CASCADE ON DELETE CASCADE
);
INSERT INTO emp(id,NAME,dept_id) VALUES(1,"mike",1),(2,"nike",2);
SELECT *FROM emp;
多对多:借助中间表
中间表至少包含两个字段,两个字段作为两张表的外键,分别指向两张表的主键。
一对一:加唯一约束的外键
一对一关系实现,可以在任意一方添加唯一外键指向另一方的主键。外键需要有唯一约束。
旅游线路关系实现:
三张表:旅游线路分类1,旅游线路2,用户3,1与2之间是一对多,2与3之间是多对多,使用中间表实现,添加外键时不使用constraint 外键名,直接用
foreign key (外键列名称) references 主表名称(主表列名称)
否则会添加失败;代码如下:
#旅游线路分类,
#cid 分类主键,自动增长
#分类名称,非空,唯一,字符串100;
CREATE TABLE fenlei(
id INT PRIMARY KEY AUTO_INCREMENT,
cname VARCHAR(100) NOT NULL UNIQUE
);
INSERT INTO fenlei(cname)VALUES ('周边游'),('出境游'),('国内游'),('泰澳游');
SELECT *FROM fenlei;
DROP TABLE fenlei;
#旅游线路表
/*
rid 旅游线路主键,自动增长
rname 旅游线路名称非空,唯一,字符串 100
price 价格
rdate 上架时间,日期类型
cid 外键,所属分类
*/
CREATE TABLE tab_route(
rid INT PRIMARY KEY AUTO_INCREMENT,
rname VARCHAR(100) NOT NULL UNIQUE,
price INT,
rdate DATE,
cid INT,
FOREIGN KEY (cid) REFERENCES fenlei(id)
);
DROP TABLE tab_route;
INSERT INTO tab_route VALUES
(NULL, '【厦门+鼓浪屿+南普陀寺+曾厝垵 高铁 3 天 惠贵团】尝味友鸭面线 住 1 晚鼓浪屿', 1499,
'2018-01-27', 1),
(NULL, '【浪漫桂林 阳朔西街高铁 3 天纯玩 高级团】城徽象鼻山 兴坪漓江 西山公园', 699, '2018-02-22', 3),
(NULL, '【爆款¥1699 秒杀】泰国 曼谷 芭堤雅 金沙岛 杜拉拉水上市场 双飞六天【含送签费 泰风情 广州往返 特价团】', 1699, '2018-01-27', 2),
(NULL, '【经典•狮航 ¥2399 秒杀】巴厘岛双飞五天 抵玩【广州往返 特价团】', 2399, '2017-12-23',2),
(NULL, '香港迪士尼乐园自由行 2 天【永东跨境巴士广东至迪士尼去程交通+迪士尼一日门票+香港如心海景酒店暨会议中心标准房 1 晚住宿】', 799, '2018-04-10', 4);
SELECT * FROM tab_route;
#用户表
/*
uid 用户主键,自增长
username 用户名长度 100,唯一,非空
password 密码长度 30,非空
name 真实姓名长度 100
birthday 生日
sex 性别,定长字符串 1
telephone 手机号,字符串 11
email 邮箱,字符串长度 100
*/
CREATE TABLE tab_user(
uid INT PRIMARY KEY AUTO_INCREMENT,
username VARCHAR(100)NOT NULL UNIQUE,
PASSWORD VARCHAR(30)NOT NULL,
NAME VARCHAR(100),
birthday DATE,
sex CHAR(1) DEFAULT '男',
telephone VARCHAR(11),
email VARCHAR(100)
);
-- 添加用户数据
INSERT INTO tab_user VALUES
(NULL, 'cz110', 123456, '老王', '1977-07-07', '男', '13888888888', '66666@qq.com'),
(NULL, 'cz119', 654321, '小王', '1999-09-09', '男', '13999999999', '99999@qq.com');
SELECT * FROM tab_user;
#创建收藏表
/*
创建收藏表 tab_favorite
rid 旅游线路 id,外键
date 收藏时间
uid 用户 id,外键
rid 和 uid 不能重复,设置复合主键,同一个用户不能收藏同一个线路两次
*/
CREATE TABLE tab_favorite(
rid INT,
DATE DATETIME,
uid INT,
#创建复合主键
PRIMARY KEY(rid,uid),
FOREIGN KEY(rid) REFERENCES tab_route(rid),
FOREIGN KEY(uid) REFERENCES tab_user(uid)
);
DROP TABLE tab_favorite;
-- 增加收藏表数据
INSERT INTO tab_favorite VALUES
(1, '2018-01-01', 1), -- 老王选择厦门
(2, '2018-02-11', 1), -- 老王选择桂林
(3, '2018-03-21', 1), -- 老王选择泰国
(2, '2018-04-21', 2), -- 小王选择桂林
(3, '2018-05-08', 2), -- 小王选择泰国
(5, '2018-06-02', 2); -- 小王选择迪士尼
SELECT * FROM tab_favorite;
数据库设计范式:数据库设计原则
归纳:
1.每一列都是不可分割的原子数据项
2.非码属性必须完全依赖于码(消除非主属性对主码的部分函数依赖)
3.消除传递依赖(任何非主属性不依赖于其他非主属性);
总结:
数据库的设计必须遵循以上三条,否则就要使用外键创立另外的表;工作中也使用以上三条来验证数据库的合理性。
数据库的备份和还原方式
1.命令行方式(不常用)
备份语法:mysqldump -u用户名 -p密码 数据库的名称 > 保存的路径
还原语法:
1.登录数据库
2.创建数据库
3.使用数据库
4.执行文件
2.图形化界面方式
多表查询
语法:
select
列名列表
from
表名列表
where......
注意:要完成多表查询,就必须消除笛卡尔积所有的无用数据。 (笛卡尔积:两个集合A,B的所有集合情况)
多表查询分类
内连接查询方式
隐式内连接:使用where条件消除无用的数据;
显示内连接:select 字段列表 from 表名1 inner join 表名2 on 加入条件
#内连接需要确定从哪些表查询,查询条件是什么,查询哪些字段(列)
#隐式内连接
SELECT
t1.`name`,t1.`gender`,t2.`name`
FROM
emp1 t1,dept t2 #用 t1 代替emp1,t2代替dept
WHERE
t1.`dept_id`=t2.`id`;
#显式内连接
SELECT * FROM emp1 INNER JOIN dept ON emp1.`dept_id`=dept.`id`;
#内连接需要确定 从哪些表查询,查询条件是什么,查询哪些字段(列)
外连接查询
1.左外连接:select 字段列表 from 表1 left outer join 表2 on 条件
2.右外连接 select 字段列表 from 表1 right outer join 表2 on 条件
内连接,左外连接,右外连接的区别
左外连接查询的是左表所有数据以及交集部分。内连接只查询交集部分,右外连接查询的是右表所有数据以及交集部分;
左右表是按照书写时先后顺序来区分的,如表1是左表,表2是右表;
子查询
概念:查询中嵌套查询,称嵌套查询为子查询
#查询工资最高的员工信息
#1.查询最高的工资是多少
SELECT MAX(salary)FROM emp1;
#2.查询员工信息,并且工资等于9000的员工
SELECT *FROM emp1 WHERE emp1.`salary`=9000;
#一条语句完成
SELECT *FROM emp1 WHERE emp1.`salary`=(SELECT MAX(salary)FROM emp1);
子查询的情况1:查询结果是单行单列的
子查询可以作为条件,使用运算符去判断如>,<>=,<= ,=;
#查询员工工资小于平均工资的人
SELECT * FROM emp1 WHERE emp1.`salary`<(SELECT AVG(salary) FROM emp1);
子查询的情况2:查询结果是多行单列的
查询的结果是多行单列的,可以使用运算符in 来判断
#查询财务部所有员工信息
#1查询财务部的id
SELECT id FROM dept WHERE NAME="财务部" OR NAME="市场部";
#2查询id=财务部的员工的信息
SELECT * FROM emp1 WHERE dept_id=3 OR dept_id=2;
#复合语句
SELECT *FROM emp1 WHERE dept_id IN (2,3);
SELECT *FROM emp1 WHERE dept_id IN (SELECT id FROM dept WHERE NAME="财务部" OR NAME="市场部");
子查询的情况3:查询结果是多行多列的
多行多列的子查询可以作为一张虚拟表进行表的查询
#查询员工入职日期是2011-11-11以后的员工信息和部门信息
#员工信息
SELECT *FROM emp1 WHERE emp1.`join_date`>'2011-11-11';
SELECT
*
FROM
dept t1,(SELECT *FROM emp1 WHERE emp1.`join_date`>'2011-11-11') t2
WHERE
t1.`id`=t2.dept_id;
事务
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
事务的步骤:
1.开启事务 start transaction
2.核心语句(sql语句)
3.回滚 rollback
4.提交 commit
首先在语句开头写下 start transaction ,之后书写要执行的语句,在末尾写下rollback和commit;类似于try,catch语句;
示例:张三给李四转账500:查询张三账户余额是否大于五百->张三账户余额 -500->李四账户余额+500.如果张三账户-500后程序崩溃了,此时张三账户减少,李四账户没有增加,就会出现问题,为避免这一问题,引入事务管理
CREATE TABLE account(
id INT PRIMARY KEY AUTO_INCREMENT,
NAME VARCHAR(10),
balance DOUBLE
);
INSERT INTO account(NAME,balance) VALUES("张三",1000),('李四',1000);
SELECT *FROM account;
#开启事务
START TRANSACTION;
UPDATE account SET balance =balance+500 WHERE NAME='张三';
UPDATE account SET balance =balance+500 WHERE NAME='李四';
#没有问题,提交
COMMIT;
#有问题,回滚
ROLLBACK;
#设当张三账号上-500 元,服务器崩溃了。李四的账号并没有+500 元,数据就出现问题了。
#我们需要保证其中一条 SQL 语句出现问题,整个转账就算失败。
#只有两条 SQL 都成功了转账才算成功。这个时候就需要用到事务
修改默认提交方式
set @@autocommit = 0
查看事务的默认提交方式
select @@autocommit ; -- 1代表自动提交,0代表手动提交
自动提交与手动提交的区别
自动提交与手动提交的区别:自动提交下所有的修改都是有效的,而手动提交下如果没有提交,那么所有的修改都是临时的,再关闭程序后,数据库将恢复修改前的状态。每次修改都必须写入commit。Mysql默认的是自动提交,可以通过上述两个命令修改提交方式。
事务的四大特征
原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败
持久性:事务提交或回滚后,事务会持久化的保存数据
隔离性:多个事务之间相互独立。
一致性:事务操作前后,数据总量不变。
事务的隔离级别
概念:多个事务之间是隔离的,相互独立的。如果多个事务操作同一批数据,会引发一些问题,设置不同的隔离级别就可以解决这些问题。
多个事务操作同一批数据引发的问题:
脏读:一个事务读到另一个事务没有提交的数据
不可重复读(虚读):同一个事务中,两次读取到的数据不一样
幻读:一个事务操作(DML)数据表中所有记录,另一个事务添加了一条事务,则第一个事务查询不到自己的修改。
隔离级别:
read uncommitted:读未提交 不commit也会显示修改后的结果
产生的问题:脏读 ,不可重复读,幻读
read committed:读已提交 (Orcale默认)修改方commit后会显示结果;
产生的问题:不可重复读,幻读
repeatable committed:可重复读 (Mysql默认)两边同时commit,才会显示修改后的结果
产生的问题:幻读
serializable :串行化 直接给数据库加锁,修改方commit后才会显示结果
可以解决所有问题;
注意:隔离界别从小到大安全性越来越高,但效率越来越低;
隔离级别表格:
隔离级别 | 效果 | |
read uncommitted | 读未提交 | 不commit也会显示修改后的结果 |
read committed | 读已提交 | 修改方commit后会显示结果; |
repeatable committed | 可重复读 | 两边同时commit,才会显示修改后的结果 |
serializable | 串行化 | 直接给数据库加锁,修改方commit后才会显示结果 |
注意:隔离界别从小到大安全性越来越高,但效率越来越低; 隔离级别就是为了不同线程操纵同一内存单元而出现的。 |
数据库设置隔离级别
set global transaction isolation level 级别字符串;
数据库查询隔离级别:
select @@tx_isolation;
带设置隔离级别的sql语句流程
设置级别(set global transaction isolation level 级别字符串; 只有关闭后再开才会有效)
开启事务(start transaction, 两边同时开才有效)
进行操作(日常语句)
commit (提交,不同隔离级别的区别就在于commit是否提交,是否同时提交)
DCL管理用户,授权
管理用户
添加用户
#创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
CREATE USER 'zhangsan'@'localhost' IDENTIFIED BY '123';
删除用户
#删除用户
DROP USER '用户名'@'主机名';
DROP USER 'zhangsan'@'localhost';
修改用户密码
#修改密码
SET PASSWORD FOR '用户名'@'主机名'=PASSWORD('新密码');
UPDATE USER SET PASSWORD=PASSWORD('新密码')WHERE USER='用户名';
UPDATE USER SET PASSWORD=PASSWORD('12334')WHERE USER='lisi';
SET PASSWORD FOR 'lisi'@'%'=PASSWORD('456');
查询用户
#查询用户
#切换mysql数据库
USE mysql;
#查询user表
SELECT*FROM USER;
# 通配符 %表示可以在任意主机使用用户登录数据库
mysql中忘记用户密码处理步骤
mysql中忘记用户密码处理步骤 |
1.cmd--> net stop mysql 停止mysql服务(需要在管理员权限下运行) |
2。使用无验证方式启动mysql服务 :mysqld --skip-grant-tables(执行后,在新打开的窗口中输入mysql就能开启mysql服务) |
3.使用sql语句修改密码:
|
4.关掉窗口->打开任务管理器->结束掉mysql进程->再打开mysql服务->在管理员权限下打开cmd ,之后输入net start mysql |
5.输入新密码即可 |
授权
查询用户权限
#查询权限
SHOW GRANTS FOR '用户名'@'主机名';
SHOW GRANTS FOR 'lisi'@'%';
授予权限
#授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
GRANT SELECT ON db3.`account` TO 'lisi'@'%'; #授予lisi 对db3.account表select 的权限
#授予lisi 对所有表所有权限;使用通配符,所有权限:ALL 所有库的所有表:*.*
GRANT ALL ON *.* TO 'lisi'@'%';#之后lisi可以对所有表使用所有命令
撤销权限
#撤销权限
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
#撤销lisi 对所有表所有权限;使用通配符,所有权限:ALL 所有库的所有表:*.*
REVOKE UPDATE ON *.* TO 'lisi'@'%';#之后lisi不能对任何表进行任何操作
JDBC概念
jdbc步骤:
导入jar包
在模块下新建文件夹(Dierctory),将jar文件复制到文件夹中,右键jar文件,选择Add as library
注册驱动
Class.forName("com.mysql.jdbc.Driver");将Driver类的代码块加载入内存;
获取数据库连接对象 Connection
定义sql
获取执行sql语句的对象Statement
执行sql,接受返回结果
处理结果
释放资源
public static void main(String[] args) throws ClassNotFoundException, SQLException {
//导入jar包
//注册驱动
//新建一个文件夹lib,将jar包拖动到文件夹中
//选中lib右键,单击 add as library
Class.forName("com.mysql.jdbc.Driver");
//获取数据库连接对象 Connection
Connection conn= DriverManager.getConnection("jdbc:mysql://localhost:3306/db3","root","root");
//三个参数:要链接的数据库,用户名,密码
//定义sql
String sql="update account set balance =500 where id=1";
//获取执行sql语句的对象Statement
Statement stmt=conn.createStatement();
//执行sql,接受返回结果
int count= stmt.executeUpdate(sql);
//处理结果
System.out.println(count);
//释放资源
stmt.close();
conn.close();
}
JDBC类详解
DriverManager 驱动管理对象
功能:注册驱动 注册与给定的驱动程序 DriverManager
-
-
static void
registerDriver(Driver driver)
-
Class.forName("com.mysql.jdbc.Driver");将Driver类的代码块加载入内存;通过查看源码,发现com.mysql.jdbc.Driver类存在静态代码块,该语句将使用mysql接口。注意mysql5之后的驱动jar包可以省略注册驱动的步骤
static {
try {
java.sql.DriverManager.registerDriver(new Driver());
} catch (SQLException E) {
throw new RuntimeException("Can't register driver!");
}
}
总的来说 Class.forName("com.mysql.jdbc.Driver");是第一步,任何使用mysql的程序都需要
获取数据库链接
获取数据库连接的方法:
方法各参数的意义:
url:指定连接的路径(网络连接电脑的ip地址,端口),有固定语法(jdbc:mysql//ip地址:端口号/数据库名称)例子:"jdbc:mysql://localhost:3306/db3",即连接ip地址为本机,端口为3306,名为db3的数据库。
注意:如果连接的是本机的mysql服务器,且mysql服务默认端口为3306.则url可以简写为:"jdbc:mysql:///数据库名称",即省略掉ip名和端口号;
user:用户名
password:密码
Connection 数据库连接对象
功能:
1.获取执行sql的对象
Statement createStatement();
PreparedStatement prepareStatement(String sql);
2.管理事务:封装相关对象来开启,回滚,关闭事务
开启事务:void setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务;
关闭事务 commit();
回滚事务:rollback();
Statement执行sql的对象
1.执行sql:boolean execute(String sql) 执行sql语句,可能返回多个结果(不常使用);
2.int executeUpdate(String sql):执行DML(insert,update,delete)语句,DDL语句(create,alter ,drop语句),返回值是影响的行数(通过返回行数判断DML执行是否成功,小于0说明失败);
3.ResultSet executeQuery(String sql)执行DQL语句(select语句)常用
ResultSet结果集对象
封装查询语句的结果方法:
next();游标向下移动一行,用来获取数据
getXxx();获取数据Xxx代表数据类型next()会指向一行,getXxx()获取该行某个类型的元素;
getXxx(int)传入列的编号,得到列的值,参数为列所在编号,从1 开始,如1代表第一列的数据,
getXxx(String)传入列的名称,得到列的值
注意:使用步骤:
1.游标向下移动,根据next()的返回值判断是否有数据(next返回值是boolean类型的)
2.获取数据
public class jdbcdemo5 { public static void main(String[] args) { Connection conn=null; Statement stmt=null;ResultSet rest=null; try { //注册驱动 Class.forName("com.mysql.jdbc.Driver"); //获取连接 conn= DriverManager.getConnection("jdbc:mysql:///db3","root","root"); //获取执行sql的对象 stmt=conn.createStatement(); //sql语句 String sql="select * from account"; rest= stmt.executeQuery(sql); //处理结果 //让游标向下移动一行; while(rest.next()){ //获取数据 int id= rest.getInt(1); String name= rest.getString("name"); double balance= rest.getDouble(3); System.out.println(id+"---"+name+"---"+balance); } } catch (ClassNotFoundException e) { throw new RuntimeException(e); }catch (SQLException e) { throw new RuntimeException(e); } finally{ if(rest!=null){ try { rest.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if(conn!=null){ try { conn.close(); } catch (SQLException e) { throw new RuntimeException(e); } } if(stmt!=null){ try { stmt.close(); } catch (SQLException e) { throw new RuntimeException(e); } } } } }
抽取JDBC工具类,抽取重复代码,简化书写
注册驱动
抽取一个方法获取连接对象
需求:不想传递参数(麻烦),还得保证工具类的通用性
释放资源
public class jdbc_utils {
private static String url;
private static String user;
private static String password;
private static String driver;
static {
//读取资源文件,获取值
try {
//创建Properties,将字符串读入内存,
Properties pro=new Properties();
//获取src路径下的文件的方式--->ClassLoader 类加载器,可以将src下的资源加载如内存;使用反射
//反射:从当前对象获取信息,进而使用
ClassLoader classLoader= jdbc_utils.class.getClassLoader();
URL res= classLoader.getResource("jdbc.properties");//传递的是文件名,返回URL对象
String path= res.getPath();
pro.load(new FileReader(path));
//从文件中获取数据,赋值
url=pro.getProperty("url");
user=pro.getProperty("user");
password=pro.getProperty("password");
driver=pro.getProperty("driver");
//注册驱动
Class.forName(driver);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (ClassNotFoundException e) {
throw new RuntimeException(e);
}
}
//获取连接,返回连接对象
//通过配置文件解决:不想传递参数,还得保证工具类的通用性的需求;
public static Connection getConnection() throws SQLException {
return DriverManager.getConnection(url,user,password);
}
//释放资源
public static void close(Statement stmt, Connection conn){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
//释放资源
public static void close(Statement stmt, Connection conn, ResultSet res){
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(res!=null){
try {
res.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
}
PreparedStatement执行sql的对象
sql注入问题:在拼接sql时,有一些sql的特殊关键字参与字符串的拼接,会造成安全问题;
解决sql注入问题:使用preparedStatement对象来解决;使用预编译sql可以解决sql注入问题
预编译sql:参数使用?作为占位符替代,我们只需给?赋值即可;代码如下:
//定义sql
String sql = " select *from user where username=? and password=? ";
//获取执行sql的对象
pstmt = conn.prepareStatement(sql);
//给?赋值
pstmt.setString(1,username);
pstmt.setString(2,password);
//执行sql语句,查询
rs = pstmt.executeQuery();
使用jdbc控制事务
事务指包含多个步骤的业务操作,多个步骤要么同时成功,要么同时失败,jdbc中使用Connection来管理事务
1.开启事务:setAutoCommit(bollean autocommit):调用该方法设置参数为false,开启事务
建立连接后,就开启事务
2.提交事务:commit(),try语句的最后
3.回滚事务:rollback();catch语句中
代码示例
public static void main(String[] args) {
Connection conn=null;
PreparedStatement pstmt2=null;
PreparedStatement pstmt1=null;
//获取数据库连接
try {
conn= jdbc_utils.getConnection();
//开启事务
conn.setAutoCommit(false);
//定义sql,加钱,减钱
String sql1="update account set balance =balance-? where id=?";
String sql2="update account set balance =balance+? where id=?";
//获取执行sql的对象
pstmt1= conn.prepareStatement(sql1);
pstmt2=conn.prepareStatement(sql2);
//设置参数
pstmt1.setDouble(1,500);
pstmt1.setDouble(2,1);
pstmt2.setDouble(1,500);
pstmt2.setDouble(2,2);
//执行语句
pstmt1.executeUpdate();
pstmt2.executeUpdate();
//提交事务
conn.commit();
} catch (Exception e) {
//回滚
try {
if(conn!=null)
conn.rollback();
} catch (SQLException ex) {
throw new RuntimeException(ex);
}
throw new RuntimeException(e);
}
finally
{
jdbc_utils.close(pstmt1,conn);
jdbc_utils.close(pstmt1,null);
}
}
jdbc连接池
数据库连接池
存放数据库连接的容器,当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户访问数据库时,从容其中获取连接对象,访问完后,将连接对象归还给容器;
c3p0连接池使用步骤
1.导入jar包:将图中三个文件复制到同意模块下的文件夹中,并 add as library;
2.定义配置文件:将 c3p0-config.xml复制到src下
3.连接池的参数:可以定义自己的连接池参数
ComboPoolDataSource为空参时将使用默认的连接池,如果传入字符串对象,将使用名为字符串的连接池参数;
4.创建核心对象,数据库连接池对象 ComboPooledDataSource;
5.获取连接 getConnection
注意:如果Connection对象来自连接池,那么close()方法将归还资源而非释放资源。
public class c3p0demo2 {
public static void main(String[] args) throws SQLException {
//获取连接池,使用默认配置
DataSource ds=new ComboPooledDataSource();
//获取连接处,使用指定名称的配置
//获取连接对象
Connection conn=ds.getConnection();
System.out.println(conn);
new c3p0demo2().testNamedConfig();
}
public void testNamedConfig() throws SQLException {
//获取连接处,使用指定名称的配置
DataSource ds=new ComboPooledDataSource("otherc3p0");
for (int i = 0; i <8 ; i++) {
Connection conn=ds.getConnection();
System.out.println(i+" "+conn);
}
}
}
Druid使用步骤
1.导入jar包 druid-1.0.9.jar以及数据库驱动jar包,注意要在src的同一模块下导入文件,并add as library
2.定义配置文件:必须是properties形式的,可以放置在任意的目录下,不必放在src下,但需要手动加载。手动加载代码的方法有两种
Properties pro=new Properties(); /*常规方法,将druid.properties加载近内存 ClassLoader cs= druiddemo1.class.getClassLoader(); URL u=cs.getResource("druid.properties"); String s=u.getPath(); pro.load(new FileReader(s)); */ //新方法,直接获取字节流 InputStream is= druiddemo1.class.getResourceAsStream("druid.properties"); //获取资源的字节流 pro.load(is);
3.获取数据库连接池对象:通过工厂类来获取 DruidDataSoourceFactory
//获取连接池对象 DataSource ds= DruidDataSourceFactory.createDataSource(pro);
4.获取连接:getConnection
//获取链接 Connection conn=ds.getConnection();
整体代码如下:
public static void main(String[] args) throws Exception { //导入jar包 //定义配置文件 //加载配置文件 Properties pro=new Properties(); /*常规方法,将druid.properties加载近内存 ClassLoader cs= druiddemo1.class.getClassLoader(); URL u=cs.getResource("druid.properties"); String s=u.getPath(); pro.load(new FileReader(s)); */ //新方法,直接获取字节流 InputStream is= druiddemo1.class.getResourceAsStream("druid.properties"); //获取资源的字节流 pro.load(is); //获取连接池对象 DataSource ds= DruidDataSourceFactory.createDataSource(pro); //获取链接 Connection conn=ds.getConnection(); System.out.println(conn); }
定义jdbc_utils工具类,简化连接池代码
1.定义一个类jdbc_utils,
2.提供静态代码块加载配置文件,初始化连接池对象
3.提供方法:
获取连接方法
释放方法
获取连接池
public class jdbc_utils {
//定义成员变量
private static DataSource ds;
//初始化赋值
static{
try {
//加载配置文件
Properties pro=new Properties();
InputStream is= jdbc_utils.class.getClassLoader().getResourceAsStream("druid.properties");//获取资源的字节流
pro.load(is);
//赋值
ds= DruidDataSourceFactory.createDataSource(pro);
} catch (IOException e) {
throw new RuntimeException(e);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
//获取链接
public static Connection getConnection() throws SQLException {
return ds.getConnection();
}
//释放资源
public static void close(Statement stmt, Connection conn) {
if(stmt!=null){
try {
stmt.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
if(conn!=null){
try {
conn.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
}
//释放资源
public static void close(ResultSet rs, Statement stmt, Connection conn){
if(rs!=null){
try {
rs.close();
} catch (SQLException e) {
throw new RuntimeException(e);
}
}
close(stmt,conn);
}
//获取连接池
public static DataSource getDataSource(){
return ds;
}
}
Spring jdbc:jdbc template
Spring 框架对JDBC的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
步骤:
1.导入jar包:
2.创建JDBCTemplate对象。依赖于数据源DataSource
3.调用JDBCTemplate方法来完成CRUD的操作;常用方法如下:
update():执行DMl语句,增删改语句
queryForMap():查询结果将结果集封装为map集合
queryForList():查询结果将结果封装为list集合
query():查询结果,将结果封装为javabean对象
queryForObject:查询结果,将结果封装为对象
JavaWeb
软件架构
C/S架构 Client/Server 客户端/服务器端
用户本地有一个客户端程序,远程有一个服务器端程序
优点:用户体验好
缺点:开发,安装,部署,维护麻烦
B/S架构:Browser/Server 浏览器/服务器端
只需要一个浏览器,用户通过不同的网址(URL),访问不同的服务器端程序
优点:开发,安装,部署,维护简单
缺点:应用过大时用户的体验会受到影响;对硬件要求过高。
注意:JavaWeb是B/S架构
B/S架构详解:
静态资源详解
使用静态网页开发技术发布的资源。
特点:所有用户访问,得到的结果是一样的。如:文本,图片,音频,视频;如果用户请求的是静态资源,那么服务器会直接将静态资源发送给浏览器,浏览器内置了静态资源的解析引擎,可以展示静态资源。
动态资源详解
使用动态网页及时发布的资源
特点:所有用户访问,得到的结果可能不一样。如jsp/servlet,php,asp.....如果用户请求的是动态资源,服务器将会执行动态资源,转换为静态资源,再发送给浏览器(因为浏览器只能解析静态资源)。
静态资源三剑客:HTML,CSS,JavaScript
HTML:搭建基础网页,展示页面的内容,
CSS:用于美化页面,完成页面的美化和布局
JavaScript:控制页面的元素,让页面有一些动态的效果
HTML
Hyper Text Markup Language 超文本标记语言
超文本:用超链接的方法,将各种不同空间的文字信息组织在一起的网状文
标记语言:有标签构成的语言。<标签名称>如html,xml;标记语言不是编程语言。
HTML语法:文件名.html或.htm
标签
1.标签分类:1.围堵标签,如开始标签<html>和结束标签:</html>,围堵标签是可以嵌套的标签
<html>
<head>
<title>title</title>
</head>
<body>
<font color='red'>Hello World</font>
</body>
</html>
2.自闭和标签:开始标签和结束标签在一起,如<br/>
3.在开始标签中可以定义属性,属性有键值对构成,值可以用引号(单,双均可)引起来。
4.html标签不区分大小写,但是建议使用小写。
文本标签 和文本有关的标签
<h1> to <h6> 标题标签,格式为:<h1>xx</h1> <h1>~<h6>h1~h6的字号不同,其余相同,
<p> 段落标签,格式为<p>xx</p>
<br/> (<br>) 换行
<hr> 显示一条水平线,格式: <hr />或者<hr color="red" width="200" size="10" align="left"/>可以设置线的颜色和宽度,粗细,对齐方式分别为红,200,10,左对齐
水平线的属性有:
color 颜色
width 宽度,赋值方式:
1.数值,单位是像素(px),width='20',20像素
2.百分比,相比于屏幕的大小,
size 粗细
align :center,left,right
<b> 字体加粗 格式:<b>百日衣衫尽</b>
<i> 字体斜体 <i>白日依山尽</i>
<font> 字体标签(修改字体的字号,大小,风格等)语法:<font>xxxxx<font/>
属性包括:
color色彩,赋值方式:
1.red,green,blue; <font color="red" size="5" face="楷体">白日依山尽 <font/>
2.RGB(值1 ,值2,值3)<font color=rgb(0,22,200) size="5" face="楷体">白日依山尽 <font/>
3.#值1值2值3(00~FF之间,采用16进制)
<font color="#3626F1" size="5" face="楷体">白日依山尽 <font/>
size大小()赋值方式
face:字体(楷体等)
<center> <center> <font color="red" size="5" face="楷体">白日依山尽 <font/> </center>
作用:可以让文本居中
标签汇总表格
标签名称 | 作用 | 示例 |
<h1> to <h6> | 标题标签 | <h1>xx</h1> |
<p> | 段落标签 | <p>xx</p> |
<br/> | 换行 | 单独一个<br/> |
<hr> | 显示一条水平线 | <hr color="red" width="200" size="10" align="left"/> |
<b> | 字体加粗 | <b>百日衣衫尽</b> |
<i> | 字体斜体 | <i>白日依山尽</i> |
<font> | 字体标签(修改字体的字号,大小,风格等) | <font color="red" size="5" face="楷体">白日依山尽 <font/> |
<center> | 可以让文本居中 | <center> <font color="red" size="5" face="楷体">白日依山尽 <font/> </center> |
特殊字符的显示
图片标签
自闭和标签:<img />
示例:<img src="image/banner_1.jpg" align="right" alt="古镇" width="500" />
src用于指定图片的路径(一般写相对路径 ./代表当前目录如./image/1.jpg,如果不写./则系统默认为当前路径。../代表后退上一级目录,如./代表同一模块下的文件,../则是上一级项目下的文件)
列表标签
有序列表
ol:
li:
<ol type="A" start="5">
<li>睁眼</li>
<li>看手机</li>
<li>穿衣服</li>
<li>洗漱</li>
</ol>
无序列表
ul:
li:
<ul type="circle">
<li>睁眼</li>
<li>看手机</li>
<li>穿衣服</li>
<li>洗漱</li>
</ul>
链接标签
<a> </a> 重要属性:<a href=""></a>
href代表要访问的资源,不仅指网络资源,也可以指内存中的资源
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>链接标签</title>
</head>
<body>
<!--链接标签-->
<a href="https://mp.csdn.net/mp_blog/creation/editor/133555152?not_checkout=1" target="_self">点我</a> <!--self在本页面打开-->
<a href="https://mp.csdn.net/mp_blog/creation/editor/133555152?not_checkout=1" target="_blank">点我</a> <!--在新页面打开-->
<a href="./公司简介.html" target="_blank">点我</a> <!--在新页面打开--> <!--访问内存中的资源-->
<a href="mailto:1911684644@qq.com">联系我们</a>
<a href="https://mp.csdn.net/mp_blog/creation/editor/133555152?not_checkout=1"> <img src="../image/banner_1.jpg"></a> <!--点击图片访问链接-->
</body>
</html>
div和span
语义化标签 控制文本样式
提高程序的可读性
header:<header></header>
footer:<footer></footer>
表格标签
HTML标签:表单标签
<form action ="#" method="get">
用户名:<input nmae="username"><br>
密码: <input name="password"><br>
<input type="submit" value="登录">
</form>
JavaScript
语法: 定义变量:var 变量名=初始化值,访问变量:alert(变量名);
运算符
运算符 | 作用 | |
typeof运算符 | typeof(变量名) | |
一元运算符 | ++,--,+(),+,- | +,-用于类型转换 |
算术运算符 | +,-,*,/,% | |
赋值运算符 | =,+=,-= | |
比较运算符 | >,<,>=,<=,==,=== | 类型相同,直接比较,类型不同,先转换在比较,字符串按照字典顺序比较。运算符返回boolean。 ===:在比较前,先判断类型,如果类型不一样,直接返回false;即及比较类型,也比较值 |
逻辑运算符 | &&,||,! | 存在短路,即前一个条件可以决定表达式返回值是,就不再计算整个表达式了,直接返回。 !:其他类型转boolean: num转boolean:0,NaN为false,其他为true String 转boolean:空字符串为false,其余为true null,undefined转boolean:都是false 对象:所有对象都为true; |
三元运算符 | ?: | |
+,-可以帮助类型转换。如String转number,如果字面值不全部是数字,则转为NaN(不是数字的数字)如“123”可以转换为123,但“abc”只能转换为 NaN; boolean 转number: true转为1,false转为0; 示例 |
javascript特殊语法
javascript特殊语法 |
1.javascript语句以;结尾,,若一行只有一条语句,则;可以省略。 |
2.变量的定义使用var关键字,也可以不使用,用var定义的是局部变量,不用var定义的是全局变量; |
流程控制语句
javascript流程控制语句 | |
if...else | |
switch | 可以接受所有数据类型 |
while | |
do...while | |
for | |
实现99乘法表 | |
ECMAScript基本语法
javascript基本对象
类 | |
Function 函数对象 | //创建 //var fun=new Function(形参列表,方法体);基本不用 //function 方法名称 (形参列表) { 方法体} 形参列表里可以不写形参的类型 // // var 方法名=function(形参列表){方法体}; //可以不写var; |
//方法 | |
//属性 //length:形参的个数 | |
//特点 //形参类型,返回类型都可以不写; //当函数特征标完全相同时,javascript会出现覆盖,而不会报错; //函数前的var可以不写; //形参都有默认值,且形参本质是形参数组,即可变参数,因此即使不传参,少传参,多传参,也能调用方法; //在方法的声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数 //返回值类型可以不屑,因为只有一种,即var; | |
//调用 //方法名称(实际参数列表) | |
Array 数组 | //创建 |
//方法 //join(参数)将数组中的元素按分隔符拼接为字符串,参数即分隔符默认为"," //push()再数组末尾添加元素; | |
//属性 | |
//特点 //JS中,元素的类型是可变的;数组的长度也是可变的;访问越界时会自动扩容; | |
Boolean | |
Date | //创建 |
//方法 //toLocalString():返回date对象对应的本地时间的字符串; //getTime():获取从1970/01/01到当前的毫秒值; | |
//属性 | |
Math | |
Number | |
String | |
RegExp | 正则表达式 |
Global | 封装的方法可以直接调用,不需要对象 |
Function
// Function对象:函数()对象
//创建
//var fun=new Function(形参列表,方法体);基本不用
//function 方法名称 (形参列表) { 方法体} 形参列表里可以不写形参的类型
// // var 方法名=function(形参列表){方法体}; //可以不写var;
//方法
//属性
//length:形参的个数
//特点
//形参类型,返回类型都可以不写;
//当函数特征标完全相同时,javascript会出现覆盖,而不会报错;
//函数前的var可以不写;
//形参都有默认值,且形参本质是形参数组,即可变参数,因此即使不传参,少传参,多传参,也能调用方法;
//在方法的声明中有一个隐藏的内置对象(数组),arguments,封装所有的实际参数
//返回值类型可以不屑,因为只有一种,即var;
//调用
//方法名称(实际参数列表)var fun1=new Function("a","b","alert(a);"); //fun1(3,4) function fun2( a, b){ alert(a+b); } //fun2(2,3) fun3=function(a,b){alert(a+b);} // fun3(4,65) alert(fun3.length) function add(){ var sum=0; for(var i=0;i<arguments.length;i++){ sum+=arguments[i] } return sum } var sum= add(1,3,4,5,6,7);
Array数组
//创建
// var arr=new Array(元素列表)
// var arr=new Array(默认长度)
// var arr= [元素列表]//方法
//join(参数)将数组中的元素按分隔符拼接为字符串,参数即分隔符默认为","
//push()再数组末尾添加元素;
//属性 //特点
//JS中,元素的类型是可变的;数组的长度也是可变的;访问越界时会自动扩容;var arr=new Array(1,2,3,4) var arr1=new Array(5) var arr3=[4,5,6,7] var arr4=[1,"asd",true,null]; document.write(arr+"<br>") document.write(arr3+"<br>") document.write(arr4+"<br>") arr4.push(11); document.write(arr4.join("--")+"<br>")
Date
//创建
//var Date=new Date()//默认是美国时间
//方法
//toLocalString():返回date对象对应的本地时间的字符串;
//getTime():获取从1970/01/01到当前的毫秒值;
//属性var data=new Date(); document.write(data+"<br>"); document.write(data.toLocaleDateString());
Math
/**
* //方法:
* random():产生0~1之间的随机数。
* floop():向下取整
* cell():向上取整
* round():四舍五入
* //创建
* //不用创建,直接使用:Math.方法名();
* //属性
* //PI:圆周率
*/document.write(Math.PI+"<br>"); document.write(Math.round(3.14)+"<br>"); document.write(Math.random()+"<br>");
RegExp正则表达式对象
/**
* RegExp:
* 单个字符[]:[a-zA-Z0-9_]
* 特殊符号代表特殊含义的单个字符:
* \d单个数字字符;
* \w单个单词字符;
* 量词符号:
* *出现0次或多次
* ?出现0次或1次
* +出现1次或多次
* 表示数量:{m,n}:m<=数量<=n;{,m}最多m次;{m,}最少m次
* 6~12位单词:\w{6,12}
* \w*出现多次的单词字符;*正则对象:
* 创建:
* var reg=new RegExp("正则表达式");
* var reg=/正则表达式/
* 方法:
* test(参数);验证字符串是否正则符合规则
*
* 开始结束符号:
* ^:开始
* $结尾*/
var reg=new RegExp("^\\w{6,12}\\d{2,3}$"); var reg2=/\w{6,12}/; alert(reg) var flag=reg2.test("wadadwd") alert(flag );
Global
/**
* 特点:封装的方法可以直接调用,不需要对象
* 方法:
* encodeURI():url编码
* decodeURI():url解码
* 以下两种方法比上两种可编码的字符更多,可以编码网址
* encodeURIComponent url编码
* decodeURIComponent url解码
*
* parseInt():将字符串转换成数字;将逐一判断每一个字符是否是数字,直到不是数字为止,将前边数字部分转为数字;
* 如果一个数字也没有,就转换为NaN;
* isNaN():判断一个值是否是NaN;NaN六亲不认,NaN参与的==比较全部为false;
* eval():计算JavaScript字符串,把他转换为代码来执行(是代码写在字符串里,如“alert(a)”就可以被解析);
*/var str="你想干什么"; var url=encodeURI(str) document.write(url+"<br>") var url1=decodeURI(url) document.write(url1+"<br>") var url23=encodeURIComponent(str) document.write(url23+"<br>") var url2=decodeURIComponent(url23) document.write(url1) var jscode="alert(123)" eval(jscode);
事件
某些组件被执行(点击)了某些操作后去触发某些代码的执行
如何绑定时间:直接在html标签上,指定事件的属性,属性值就是js代码;
<img id="light" src="../image/image1/banner_1.jpg" onclick="func()">
<img id="light1" src="../image/image1/banner_1.jpg" onclick="func()">
<h1 id="ligh">悔创阿里</h1>
<script>
function fun(){
alert('我被点击了');
alert('我又被点击了');
alert('我又又被点击了');
alert('我又又又被点击了');
}
function fun2(){
alert('点击更新');
}
var light= document.getElementById("light");
alert("我要换图片了");
light.src="../image/image1/banner_2.jpg";
alert("我要换内容了")
var ligh=document.getElementById("ligh");
ligh.innerHTML="坦然处之"
document.getElementById("light1");
light1.onclick=fun2;
document.getElementById("light");
light.onclick=fun;
</script>
切换图片
<img src="../image/image1/banner_1.jpg" id="deng" >
<script>
var deng= document.getElementById("deng");
var flag=false;
deng.onclick=function(){
if(flag){
deng.src="../image/image1/banner_1.jpg";
flag=false;
}else{deng.src="../image/image1/banner_3.jpg";flag=true;}
}
</script>
BOM
Window
/**
* 方法:
* 1.与弹出框有关的方法:最常用的是confirm
* alert(),显示带有一段消息和一个确认按钮的警告框
* confirm,显示带有一段消息以及确认和取消按钮的对话框,点击确定,取消(方法返回true,false)之后可以根据返回值设置代码,该方法比较常用,
* prompt:显示可提示用户输入的对话框,返回值是用户输入的值
* 2.与打开关闭有关的方法:
* open打开一个新的窗口,返回新窗口对象
* close:关闭窗口
* 3.与定时器有关的方法:
* setTimeout:指定毫秒数后调用函数或计算表达式
* 参数1:要执行的语句(完整的)或者方法对象(不写括号)
* 参数2:毫秒值
* clearTimeout:取消由setTimeout设置的timeout,
*属性1.获取其他BOM对象
history 获取历史记录
location
Navigator:
Screen:
2.获取DOM对象
document:
*特点
* Window对象不用创建,使用window.方法名()调用方法;也可以直接使用方法名调用方法;
*/
//弹出框相关的方法:
var flag= confirm("您确定要退出吗");
alert(flag)
if(flag){
alert("欢迎下次光临")
}else{
alert("手别抖");
}
var res=prompt("请输入用户名");
alert(res)
//点击就打开窗口
// 与打开关闭窗口有关的方法:
var Btn= document.getElementById("openBtn");
var newwindow;//关闭新窗口;
Btn.onclick=function(){
newwindow=open("https://www.baidu.com");
}
var closeBtn= document.getElementById("closeBtn");
closeBtn.onclick=function(){
newwindow.close();
}
function fun3(){
alert('boom')
}
//一次定时器
var idd= setTimeout("fun3();",1000);//3s后执行代码
//循环定时器,如闹钟
clearTimeout(idd);
setInterval(fun3,1000);
Location:地址栏对象
/**
* Location包含当前窗口的url
* 方法:
* reload:重新加载当前网页;
* 属性
* href:设置或获取当前窗口的路径
*/
History:历史记录对象
当前用户在当前页面访问过的url;
/**
* History
* 属性
* length:返回当前窗口历史列表中的url数量
* 方法
* back:加载history列表总前一个url
* forward:加载history列表中洗一个url
* go:加载history列表中某个具体页面
* 参数:
* 正数 前进几个历史记录
* 负数:后退几个历史记录
*/
<body>
<input type="button" id="btn" value="获取历史记录个数">
<a href="02轮播图.html">轮播图页面</a>
<input type="button" id="forward" value="前进">
<script>
var btn=document.getElementById("btn");
btn.onclick=function(){
alert( history.length);
}
var btn1=document.getElementById("forward");
btn1.onclick=function(){
history.forward();
}
</script>
DOM
功能:控制Html文档的内容(CRUD)
代码:获取页面标签(元素)对象Element
document.getElementById("id值")通过元素ID获取元素对象;获取后可以操作Element对象:
修改属性值;修改标签体内容(标签内的值)注意,此时script代码要写到body的最后。
<img id="light" src="../image/image1/banner_1.jpg">
<h1 id="ligh">悔创阿里</h1>
<script>
var light= document.getElementById("light");
alert("我要换图片了");
light.src="../image/image1/banner_2.jpg";
alert("我要换内容了")
var ligh=document.getElementById("ligh");
ligh.innerHTML="坦然处之"
</script>
核心DOM
Document文档对象
<div id="div1">div1</div>
<div id="div2">div2</div>
<div id="div3">div3</div>
<div class="div5">div5</div>
<div class="div5">div4</div>
<input type="text" name="username">
<script>
var arr= document.getElementsByTagName("div");
alert(arr.length);
var arr1=document.getElementsByClassName("div5");
alert(arr1.length);
var username= document.getElementsByName("username");
alert(username.length);
</script>
Element对象
<a>点我试一试</a>
<input type="button" value="设置属性" id="btn_set" >
<input type="button" value="删除属性" id="btn_remove">
<script>
var bt_Set= document.getElementById("btn_set");
bt_Set.onclick=function (){
var element_e= document.getElementsByTagName("a")[0];//反射
element_e.setAttribute("href","https://www.baidu.com");
}
var btn_remove=document.getElementById("btn_remove");
btn_remove.onclick=function (){
var element_e= document.getElementsByTagName("a")[0];//反射
element_e.removeAttribute("href","https://www.baidu.com");
}
</script>
Node节点对象
<style>
.d1{
border:1px solid red;
width:100px;
height:100px;
}
.d2{
border:1px solid blue;
width:200px;
height:200px;
}
</style>
</head>
<body>
<div id="div1">div1</div>
<div id="div2">div2</div>
<script>
var div1=document.getElementById("div1");
div1.onclick=function (){
div1.style.border="1px solid red";
div1.style.width="200px ";
div1.style.fontSize="40px ";
}
var innerHTML= div1.innerHTML
div1.innerHTML+="<input type='text'>";
alert(innerHTML);
var div2=document.getElementById("div2");
div2.onclick=function(){
div2.className="d1";
}
</script>
Bootstrap开发框架
响应式布局
同一套页面可以兼容不同分辨率的设备
实现:依赖于栅格系统,将一行平均分成12个格子,可以指定元素占几个格子。
xml
xml第一行必须定义文档声明,xml文档中有且仅有一个根标签,标签的属性值必须用引号引起来,标签必须有结束。
外部约束单独一个文件,内部约束写xml文件里
maven中徐娅我们改的
<groupId>com.itheima</groupId>
<artifactId>project-java</artifactId>
<version>1,0</version>
<packaging>jar</packaging>
<properties>
<maven.compiler.source>11</maven.compiler.source>
<maven.compiler.target>11</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.12</version>
</dependency>
</dependencies>
idea
首先要设置jdk版本,即SDK选择为11
其次要配置mavende home path,setting fille,local repository
注意 archetype选择qucikstart,然后自己设置好gropuid,artcifactid,version
完成;