1.手动:cmd->services.msc->启动MySql
开启,关闭服务下两种在管理员权限下运行:
2.net stop mysql(停止服务)
3.net start 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
本机 exit
远程 quit
1.sql语句可以单行或多行书写,以;结尾
2.语句不区分大小写,关键字可以大写
单行:-- 注释内容,# 注释内容(注意--后跟一个空格,#可以不跟)
多行:/* */(与JAVA一样);

1.操作数据库CRUD,增删改查
创建数据库: create database 数据库名字
create database if not exists 数据库名字;(如果存在就不创建了)
create database 数据库名字 character set gbk;
创建表:create 表名(列名1 数据类型1
列名2 数据类型2,
......
列名 n,数据类型n) //最后一列不加逗号;
复制表:create table 表名 like 表名
查询所有的数据库的名称:show databases
查询某个数据库中的所有表名称:show tables
查询表结构:desc 表名
修改数据库的字符集:alter database 数据库名称 character set 字符集名
修改表名 alter table 表名 rename to 新的表名
修改表 的字符集 alter table 表名 character set 字符集格式;
添加一列:alter table 表名 add 列名 数据类型
修改列的名称和类型:
修改名称和类型 alter table 表名 change 列名 新列名 数据类型
修改类型 alter table 表名 modify 列名 新数据类型
删除数据库: drop database 数据库名称
drop database if exists 数据库名称
删除表: drop table 表名
drop table if exists 表名
删除列:alter table 表名 drop 列名
查询当前正在使用的数据库:select database();
使用数据库: use 数据库名称;

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 条件];不加任何条件会修改所有记录;
查询语句:
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;
格式:
举例
-
- #查询姓马的人
- 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.消除传递依赖(任何非主属性不依赖于其他非主属性);
数据库的设计必须遵循以上三条,否则就要使用外键创立另外的表;工作中也使用以上三条来验证数据库的合理性。
备份语法:mysqldump -u用户名 -p密码 数据库的名称 > 保存的路径
还原语法:
1.登录数据库
2.创建数据库
3.使用数据库
4.执行文件
语法:
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);
子查询可以作为条件,使用运算符去判断如>,<>=,<= ,=;
- #查询员工工资小于平均工资的人
- SELECT * FROM emp1 WHERE emp1.`salary`<(SELECT AVG(salary) FROM emp1);
查询的结果是多行单列的,可以使用运算符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="市场部");
多行多列的子查询可以作为一张虚拟表进行表的查询
- #查询员工入职日期是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;
设置级别(set global transaction isolation level 级别字符串; 只有关闭后再开才会有效)
开启事务(start transaction, 两边同时开才有效)
进行操作(日常语句)
commit (提交,不同隔离级别的区别就在于commit是否提交,是否同时提交)
- #创建用户
- 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中忘记用户密码处理步骤 |
| 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不能对任何表进行任何操作
导入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();
- }
功能:注册驱动 注册与给定的驱动程序 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:密码
功能:
1.获取执行sql的对象
Statement createStatement();
PreparedStatement prepareStatement(String sql);
2.管理事务:封装相关对象来开启,回滚,关闭事务
开启事务:void setAutoCommit(boolean autoCommit):调用该方法设置参数为false,即开启事务;
关闭事务 commit();
回滚事务:rollback();
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语句)常用
封装查询语句的结果方法:
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); } } } } }
注册驱动
抽取一个方法获取连接对象
需求:不想传递参数(麻烦),还得保证工具类的通用性
释放资源
-
- 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);
- }
- }
- }
- }
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中使用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);
- }
- }
存放数据库连接的容器,当系统初始化好后,容器被创建,容器中会申请一些连接对象,当用户访问数据库时,从容其中获取连接对象,访问完后,将连接对象归还给容器;

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);
- }
- }
- }
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); }
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的简单封装。提供了一个JDBCTemplate对象简化JDBC的开发
步骤:
1.导入jar包:
2.创建JDBCTemplate对象。依赖于数据源DataSource
3.调用JDBCTemplate方法来完成CRUD的操作;常用方法如下:
update():执行DMl语句,增删改语句
queryForMap():查询结果将结果集封装为map集合
queryForList():查询结果将结果封装为list集合
query():查询结果,将结果封装为javabean对象
queryForObject:查询结果,将结果封装为对象

C/S架构 Client/Server 客户端/服务器端
用户本地有一个客户端程序,远程有一个服务器端程序
优点:用户体验好
缺点:开发,安装,部署,维护麻烦
B/S架构:Browser/Server 浏览器/服务器端
只需要一个浏览器,用户通过不同的网址(URL),访问不同的服务器端程序
优点:开发,安装,部署,维护简单
缺点:应用过大时用户的体验会受到影响;对硬件要求过高。
注意:JavaWeb是B/S架构
使用静态网页开发技术发布的资源。
特点:所有用户访问,得到的结果是一样的。如:文本,图片,音频,视频;如果用户请求的是静态资源,那么服务器会直接将静态资源发送给浏览器,浏览器内置了静态资源的解析引擎,可以展示静态资源。
使用动态网页及时发布的资源
特点:所有用户访问,得到的结果可能不一样。如jsp/servlet,php,asp.....如果用户请求的是动态资源,服务器将会执行动态资源,转换为静态资源,再发送给浏览器(因为浏览器只能解析静态资源)。
HTML:搭建基础网页,展示页面的内容,
CSS:用于美化页面,完成页面的美化和布局
JavaScript:控制页面的元素,让页面有一些动态的效果
Hyper Text Markup Language 超文本标记语言
超文本:用超链接的方法,将各种不同空间的文字信息组织在一起的网状文
标记语言:有标签构成的语言。<标签名称>如html,xml;标记语言不是编程语言。
HTML语法:文件名.html或.htm
1.标签分类:1.围堵标签,如开始标签和结束标签:,围堵标签是可以嵌套的标签
title
Hello World
2.自闭和标签:开始标签和结束标签在一起,如
3.在开始标签中可以定义属性,属性有键值对构成,值可以用引号(单,双均可)引起来。
4.html标签不区分大小写,但是建议使用小写。
to
标题标签,格式为:
xx
~
h1~h6的字号不同,其余相同,
段落标签,格式为
xx
(
) 换行
显示一条水平线,格式:
或者
可以设置线的颜色和宽度,粗细,对齐方式分别为红,200,10,左对齐水平线的属性有:
color 颜色
width 宽度,赋值方式:
1.数值,单位是像素(px),width='20',20像素
2.百分比,相比于屏幕的大小,
size 粗细
align :center,left,right
字体加粗 格式:百日衣衫尽
字体斜体 白日依山尽
字体标签(修改字体的字号,大小,风格等)语法:xxxxx
属性包括:
color色彩,赋值方式:
1.red,green,blue; 白日依山尽
2.RGB(值1 ,值2,值3)白日依山尽
3.#值1值2值3(00~FF之间,采用16进制)
白日依山尽
size大小()赋值方式
face:字体(楷体等)
白日依山尽 作用:可以让文本居中
| 标签名称 | 作用 | 示例 |
to | 标题标签 | xx |
| 段落标签 | xx |
| 换行 | 单独一个 | |
| 显示一条水平线 | ||
| 字体加粗 | 百日衣衫尽 | |
| 字体斜体 | 白日依山尽 | |
| 字体标签(修改字体的字号,大小,风格等) | 白日依山尽 | |
| 可以让文本居中 |

自闭和标签:
示例:
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>
href代表要访问的资源,不仅指网络资源,也可以指内存中的资源
- 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>
- <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>
提高程序的可读性
header:
footer:




- <form action ="#" method="get">
- 用户名:<input nmae="username"><br>
- 密码: <input name="password"><br>
- <input type="submit" value="登录">
- form>
语法: 定义变量: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特殊语法 |
| 1.javascript语句以;结尾,,若一行只有一条语句,则;可以省略。 |
| 2.变量的定义使用var关键字,也可以不使用,用var定义的是局部变量,不用var定义的是全局变量; |
| javascript流程控制语句 | |||||||||||||||||||||||||||||||||||
| if...else | |||||||||||||||||||||||||||||||||||
| switch | 可以接受所有数据类型 | ||||||||||||||||||||||||||||||||||
| while | |||||||||||||||||||||||||||||||||||
| do...while | |||||||||||||||||||||||||||||||||||
| for | |||||||||||||||||||||||||||||||||||
| 实现99乘法表 | |