使用表级约束语法建立唯一约束
unique (test_name),
使用表级约束语法建立唯一约束, 而且指定约束名
constraint test2_uk unique(test_pass)
);
上面的建表语句为 test_name、 test_pass 分别建立了唯一约束, 这意味着这两列都不能出现重复值。
除此之外, 还可以为这两列组合建立唯一约束, SQL 语句如下:
建表时创建唯一约束, 使用表级约束语法建立约束
create table unique_test3
(
建立了非空约束, 这意味着 test_id 不可以为 null
test_id int not null,
test name varchar(255),
test_pass varchar(255),
使用表级约束语法建立唯一约束, 指定两列组合不允许重复
constraint test3_uk unique(test_name,test_pass)
);
对于上面的 unique_test2 和 unique_test3 两个表, 都是对 test_name、test_pass 建立唯一约束, 其中unique_test2 要求 test_name、 test_pass 都不能出现重复值, 而 unique_test3 只 要 求 test_name、test_pass两列值的组合不能重复。
也可以在修改表结构时使用 add 关键字来增加唯一约束, SQL 语句如下:
增加唯一约束
alter table unique_test3
add unique(test_name, test_pass);
还可以在修改表时使用 modify 关键字, 为单列采用列级约束语法来增加唯一约束, 代码如下:
列增加唯一约束
alter table unique_test3
modify test_name varchar(255) unique;
对于大部分数据库而言, 删除约束都是在 alter table 语句后使用“ drop constraint 约束名” 语法来完成的, 但 MySQL 并不使用这种方式, 而是使用 “drop index 约束名” 的方式来删除约束。 例如如下 SQL语句:
删除 unique_test3 表上的 test3_uk 唯一约束
alter table unique_test3
drop index test3_uk;
主键约束相当于非空约束和唯一约束, 即主键约束的列既不允许出现重复值, 也不允许出现 null值;如果对多列组合建立主键约束,则多列里包含的每一列都不能为空, 但只要求这些列组合不能重复。
主键列的值可用于唯一地标识表中的一条记录。
每一个表中最多允许有一个主键, 但这个主键约束可由多个数据列组合而成, 主键是表中能唯一确定一行记录的字段或字段组合。
建立主键约束时既可使用列级约束语法, 也可使用表级约束语法。 如果需要对多个字段建立组合主键约束, 则只能使用表级约束语法。 使用表级约束语法来建立约束时, 可以为该约束指定约束名。 但不管用户是否为该主键约束指定约束名, MySQL 总是将所有的主键约束命名为 PRIMARY。
当创建主键约束时, MySQL 在主键约束所在列或列组合上建立对应的唯一索引。
创建主键约束的语法和创建唯一约束的语法非常像, 一样允许使用列级约束语法为单独的数据列创建主键, 如果需要为多列组合建立主键约束或者需要为主键约束命名, 则应该使用表级约束语法来建立主键约束。 与建立唯一约束不同的是, 建立主键约束使用 primary key。
- 建表时创建主键约束, 使用列级约束语法:
create table primary_test
(
建立了主键约束
test_id int primary key,
test_name varchar(255)
);
建表时创建主键约束, 使用表级约束语法:
create table primary_test2
(
test_id int not null,
test_name varchar(255),
test_pass varchar(255),
指定主键约束名为 test2_pk, 对大部分数据库有效, 但对 MySQL 无效
MySQL 数据库中该主键约秦名依然是 PRIMARY
constraint test2_pk primary key(test_id)
);
建表时创建主键约束, 以多列建立组合主键, 只能使用表级约束语法:
create table primary_test3
(
test name varchar(255),
test_pass varchar(255),
建立多列组合的主键约束
primary key(test_name, test_jpass)
);
如果需要删除指定表的主键约束, 则在 alter table 语句后使用 drop primary key 子句即可。 SQL 语句如下:
删除主键约束
alter table primary_test3
drop primary key;
如果需要为指定表增加主键约束, 既可通过 modify 修改列定义来增加主键约束, 这将采用列级约束语法来增加主键约束; 也可通过 add 来增加主键约束, 这将采用表级约束语法来增加主键约束。 SQL语句如下:
使用表级约束语法增加主键约束
alter table primary_test3
add primary key(test_name,test_pass);
如果只是为单独的数据列增加主键约束, 则可使用 modify 修改列定义来实现, 如下 SQL 语句所示:
使用列级约束语法增加主键约束
alter table primary_test3
modify test_name varchar(255) primary key;
很多数据库对主键列都支持一种自增长的特性一一如果某个数据列的类型是整型 主键约束 , 则可指定该列具有自增长功能 ,MySQL 指定自增长功能通常用于设置逻辑主键列一一该列的值没有任何物理意义, 仅仅用于标识每行记录。 SQL 语句 如下:
create table primary_test4
(
increment primary key,
test_name varchar(255),
test_pass varchar(255)
);
外键约束主要用于保证一个或两个数据表之间的参照完整性, 外键是构建于一个表的两个字段或者两个表的两个字段之间的参照关系。 外键确保了相关的两个字段的参照关系: 子( 从) 表外键列的值必须在主表被参照列的值范围之内, 或者为空( 也可以通过非空约束来约束外键列不允许为空)。
当主表的记录被从表记录参照时, 主表记录不允许被删除, 必须先把从表里参照该记录的所有记录全部删除后, 才可以删除主表的该记录。 还有一种方式, 删除主表记录时级联删除从表中所有参照该记录的从表记录。
从表外键参照的只能是主表主键列或者唯一键列, 这样才可保证从表记录可以准确定位到被参照的主表记录。 同一个表内可以拥有多个外键。
建立外键约束时, MySQL 也会为该列建立索引。
外键约束通常用于定义两个实体之间的一对多、 一对一的关联关系。 对于一对多的关联关系, 通常在多的一端增加外键列, 例如老师一学生( 假设一个老师对应多个学生, 但每个学生只有一个老师, 这是典型的一对多的关联关系)。 为了建立他们之间的关联关系, 可以在学生表中增加一个外键列, 该列中保存此条学生记录对应老师的主键。 对于一对一的关联关系, 则可选择任意一方来增加外键列, 增加外键列的表被称为从表, 只要为外键列增加唯一约束就可表示一对一的关联关系了。 对于多对多的关联关系, 则需要额外增加一个连接表来记录它们的关联关系。
建立外键约束同样可以采用列级约束语法和表级约束语法。 如果仅对单独的数据列建立外键约束,则使用列级约束语法即可; 如果需要对多列组合创建外键约束, 或者需要为外键约束指定名字, 则必须使用表级约束语法。
采用列级约束语法建立外键约束直接使用 references 关键字, references 指定该列参照哪个主表, 以及参照主表的哪一列。
如下 SQL 语句所示:
为了保证从表参照的主表存在, 通常应该先建主表
create table teacher_table
(
auto increment: 代表数据库的自动编号策略, 通常用作数据表的逻辑主键
teacher_id int auto_increment,
teacher_name varchar(255),
primary key(teacher_id)
);
create table student table3
(
为本表建立主键约束
student_id int auto_increment primary key,
student_name varchar(255),
java_teacher_name varchar(255),
java_teacher_pass varchar(255),
使用表级约束语法建立外键约束, 指定两列的联合外键
foreign key(java_teacher_name , java_teacher_pass)
references teacher_table3(teacher_name , teacher_pass)
);
删除外键约束的语法很简单, 在 alter table 后增加 “ drop foreign key 约束名 ” 子句即可。 如下代码所示:
删除 student_table3 表上名为 student_table3_ibfk_l 的外键约束
alter table student_table3
drop foreign key student_table3_ibfk_l;
增加外键约束通常使用 add foreign key 命令。 如下 SQL 语句所示:
修改 student_table3 数据表, 增加外键约束
alter table student_table3
add foreign key(java_teacher_name,java_teacher_pass)
references teacher_table3(teacher_name,teachter_pass);
值得指出的是, 外键约束不仅可以参照其他表, 而且可以参照自身, 这种参照自身的情况通常被称为自关联。
例如, 使用一个表保存某个公司的所有员工记录, 员工之间有部门经理和普通员工之分, 部门经理和普通员工之间存在一对多的关联关系, 但他们都是保存在同一个数据表里的记录, 这就是典型的自关联。 下面的 SQL 语句用于建立自关联的外键约束。
使用表级约束语法建立外约束键, 且直接参照自身
create table foreign_test
(
foreign_id int auto_increment primary key,
foreign_name varchar(255),
使用该袠的 refer_id 参照到本表的 foreign_id 列
refer_id int,
foreign key(refer_id) references foreign_test(foreign_id)
);
如果想定义当删除主表记录时, 从表记录也会随之删除, 则需要在建立外键约束后添加 on delete cascade 或添加 on delete set null, 第一种是删除主表记录时, 把参照该主表记录的从表记录全部级联删除; 第二种是指定当删除主表记录时, 把参照该主表记录的从表记录的外键设为 null。 如下 SQL 语句所示:
#为了保证从表参照的主表存在, 通常应该先建主表
create table teacher table4
(
auto_increment: 代表数据厍的自动编号策略, 通常用作数据表的逻辑主键
teacher_id int auto_increment,
teacher_name varchar(255) ,
primary key(teacher_id)
);
create table student table4
(
为本表建立主键约束
student_id int auto_increment primary key,
student name varchar(255),
java_teacher int,
使用表级约束语法建立外键约束, 定义级联删除
foreign key(java_teacher) references teacher_table4(teacher_id)
on delete cascade # 也可用 on delete set null
);
当前版本的 MySQL支持建表时指定CHECK约束, 但这个 CHECK约束不会有任何作用。 建立CHECK约束的语法很简单, 只要在建表的列定义后增加 check (逻辑表达式) 即可。 如下 SQL 语句所示:
create table check test
(
emp_id int auto_increment,
emp_name varchar(255) ,
emp_salary decimal,
primary key(emp_id),
建立 CHECK 约束
check(emp_salary>0)
);
======================================================================
索引是存放在模式( schema) 中的一个数据库对象, 虽然索引总是从属于数据表, 但它也和数据表一样属于数据库对象。 创建索引的唯一作用就是加速对表的查询, 索引通过使用快速路径访问方法来快速定位数据, 从而减少了磁盘的 I/O。
索引作为数据库对象, 在数据字典中独立存放, 但不能独立存在, 必须属于某个表。
创建索引有两种方式:
-
自动: 当在表上定义主键约束、 唯一约束和外键约束时, 系统会为该数据列自动创建对应的索引。
-
手动: 用户可以通过 create index…语句来创建索引。
删除索引也有两种方式:
-
自动: 数据表被删除时, 该表上的索引自动被删除。
-
手动: 用户可以通过 drop index…语句来删除指定数据表 h的指定索引。
索引的作用类似于书的目录, 几乎没有一本书没有目录, 因此几乎没有一个表没有索引。 一个表中可以有多个索引列, 每个索引都可用于加速该列的查询速度。正如书的目录总是根据书的知识点来建立一样——因为读者经常要根据知识点来查阅一本书。 类似的,通常为经常需要查询的数据列建立索引, 可以在一列或者多列上创建索引。 创建索引的语法格式如下:
create index index_name
on table name (column[, column ] …);
下面的索引将会提高对 employees 表基于 last name 字段的查询速度。
create index emp_last_name_idx
on employees(last_name);
也可同时对多列建立索引, 如下 SQL 语句所示:
下面语句为 employees 的 first_name 和 last_name 两列同时建立索引
create index emp_last_name_idx2
on employees(first_name, last_name);
MySQL 中删除索引需要指定表, 采用如下语法格式:
drop index 索引名
on 表名;
如下 SQL 语句删除了 employees 表上的 emp_last_name idx2索引:
drop index enqp_last_name_idx2
on employees;
索引的好处是可以加速查询。 但索引也有如下两个坏处。
-
与书的目录类似, 当数据表中的记录被添加、 删除、 修改时, 数据库系统需要维护索引, 因此有一定的系统开销。
-
存储索引信息需要一定的磁盘空间。
======================================================================
视图看上去非常像一个数据表, 但它不是数据表, 因为它并不能存储数据。 视图只是一个或多个数据表中数据的逻辑显示。
使用视图有如下几个好处:
-
可以限制对数据的访问。
-
可以使复杂的查询变得简单。
-
提供了数据的独立性。
-
提供了对相同数据的不同显示。
因为视图只是数据表中数据的逻辑显示一一也就是一个查询结果, 所以创建视图就是建立视图名和查询语句的关联。
创建视图的语法如下:
create or replace view 视图名
as
subquery
从上面的语法可以看出, 创建、 修改视图都可使用上面语法。 上面语法的含义是, 如果该视图不存在, 则创建视图; 如果指定视图名的视图己经存在, 则使用新视图替换原有视图。 后面的 subquery 就是一个查询语句, 这个查询可以非常复杂。
通过建立视图的语法规则不难看出, 所谓视图的本质, 其实就是一条被命名的 SQL 查询语句。
一旦建立了视图以后, 使用该视图与使用数据表就没有什么区别了, 但通常只是查询视图数据, 不会修改视图里的数据, 因为视图本身没有存储数据。
如下 SQL 语句就创建了一个简单的视图:
create or replace view view_test
as
select teacher_name ,teacher_pass from teacher_table;
为了强制不允许改变视图的数据, MySQL 允许在创建视图时使用 with check option 子句, 使用该子句创建的视图不允许修改, 如下所示:
create or replace view view_test
as
select teacher name from teacher table
指定不允许修改该视图的数据
with check option;
删除视图使用如下语句:
drop view 视图名
============================================================================
与 DDL 操作数据库对象不同,DML 主要操作数据表里的数据, 使用 DML 可以完成如下三个任务。
-
插入新数据。
-
修改己有数据。
-
删除不需要的数据。
DML 语句由 insert 、 update 和 delete 三个命令组成。
insert 用于向指定数据表中插入记录。 对于标准的 SQL 语句而言, 每次只能插入一条记录。 insert语句的语法格式如下:
insert into table_name [(column [, column…])]
values(value [, value…]);
执行插入操作时, 表名后可以用括号列出所有需要插入值的列名, 而 values 后用括号列出对应需要插入的值。
如果省略了表名后面的括号及括号里的列名列表, 默认将为所有列都插入值, 则需要为每一列都指定一个值。 如果既不想在表名后列出列名, 又不想为所有列都指定值, 则可以为那些无法确定值的列分配 null。
下面的 SQL 语句示范了如何向数据表中插入记录。
在表名后使用括号列出所有需要插入值的列:
insert into teacher_table2(teacher_name)
values(‘xyz’);
如果不想在表后用括号列出所有列, 则需要为所有列指定值; 如果某列的值不能确定, 则为该列分配一个 null 值。
insert into teacher table2
使用 null 代替主键列的值
values(null , ‘abc’);
在一些特别的情况下, 可以使用带子查询的插入语句, 带子查询的插入语句可以一次插入多条记录,如下 SQL 语句所示:
insert into student_table2(student name)
使用子查询的值来插入
select teacher name from teacher_table2;
正如上面的 SQL 语句所示, 带子查询的插入语句甚至不要求查询数据的源表和插入数据的目的表是同一个表, 它只要求选择出来的数据列和插入目的表的数据列个数相等、 数据类型匹配即可。
MySQL 甚至提供了一种扩展的语法, 通过这种扩展的语法也可以一次插入多条记录。 MySQL 允许在 values 后使用多个括号包含多条记录, 表示多条记录的多个括号之间以英文逗号(,) 隔开。 如下SQL 语句所示:
insert into teacher table2
同时插入多个值
values(null , “Yeeku”),
(null , “Sharfly”);
update 语句用于修改数据表的记录, 每次可以修改多条记录, 通过使用 where 子句限定修改哪些记录。 where 子句是一个条件表达式, 该条件表达式类似于 Java 语言的 if, 只有符合该条件的记录才会被修改。 没有 where 子句则意味着 where 表达式的值总是 true, 即该表的所有记录都会被修改。 update 语句的语法格式如下:
update table_name
set columnl= valuel[, column2 = value2] …
[WHERE condition];
使用 update 语句不仅可以一次修改多条记录, 也可以一次修改多列。 修改多列都是通过在 set 关键字后使用 columnl=valuel,column2=value2…来实现的, 修改多列的值之间以英文逗号( ,) 隔幵。
下面的 SQL 语句将会把 teacher_table2 表中所有记录的 teacher name 列的值都改为’孙悟空’。
update teacher_table2
set teacher_name = 孙悟空 ’;
也可以通过添加 where 条件来指定只修改特定记录, 如下 SQL 语句所示:
只修改 teacher_id 大于 1 的记录
update teacher_table2
set teacher_name =
where teacher id > 1;
delete from 语句用于删除指定数据表的记录。 使用 delete from 语句删除时不需要指定列名, 因为总是整行地删除。
使用 delete from 语句可以一次删除多行, 删除哪些行采用 where 子句限定, 只删除满足 where 条件的记录。 没有 where 子句限定将会把表里的全部记录删除。
delete from 语句的语法格式如下:
delete from table_name
[WHERE condition];
如下 SQL 语句将会把 student_table2 表中的记录全部删除:
delete from student table2;
也可以使用 where 条件来限定只删除指定记录, 如下 SQL 语句所示:
delete from teacher_table2
where teacher id > 2;
当主表记录被从表记录参照时 : 主表记录不能被删除, 只有先将从表中参照主表记录的所有记录全部删除后, 才可删除主表记录。 还有一种情况, 定义外键约束时定义了主表记录和从表记录之间的级联删除 on delete cascade, 或者使用 on delete set null 用于指定当主表记录被删除时, 从表中参照该记录的从表记录把外键列的值设为 null。
========================================================================
select 语句的功能就是查询数据。 select 语句也是SQL 语句中功能最丰富的语句, select 语句不仅可以执行单表查询, 而且可以执行多表连接查询, 还可以
进行子查询, select 语句用于从一个或多个数据表中选出特定行、 特定列的交集。
单表查询的 select 语句的语法格式如下:
select columnl, column2 ……
from 数据源
[where condition]
下面的 SQL 语句将会选择出 teacherjable 表中的所有行、 所有列的数据:
select *
from teacher table;
如果增加 where 条件, 则只选择出符合 where 条件的记录。 如下 SQL 语句将选择出 student_table表中 java teacher 值大于 3 的记录的 student name 列的值。
select student_name
from student_table
where java_teacher > 3;
当使用 select 语句进行查询时, 还可以在 select 语句中使用算术运算符(+、 一、 *、 /), 从而形成算术表达式。 使用算术表达式的规则如下:
-
对数值型数据列、 变量、 常量可以使用算术运算符(+、 -、 *、 /) 创建表达式;
-
对日期型数据列、 变量、 常量可以使用部分算术运算符(+、 -) 创建表达式, 两个日期之间可以进行减法运算, 日期和数值之间可以进行加、 减运算;
-
运算符不仅可以在列和常量、 变量之间进行运算, 也可以在两列之间进行运算。
不论从哪个角度来看, 数据列都很像一个变量, 只是这个变量的值具有指定的范围一一逐行计算表中的每条记录时, 数据列的值依次变化。 因此能使用变量的地方, 基本上都可以使用数据列。
下面的 select 语句中使用了算术运算符。
数据列实际上可当成一个变量
select teacher_id + 5
from teacher_table;
查询出 teacher_table 表中 teacher_id * 3 大于 4 的记录
select *
from teacher_table
where teacher id * 3 > 4;
select 后的不仅可以是数据列, 也可以是表达式, 还可以是变量、 常量等。 例如,如下语句也是正确的:
数据列实际上可当成一个变量
select 3*5, 20
from teacher table;
SQL 语句中算术运算符的优先级与 Java 语言中的运算符优先级完全相同, 乘法和除法的优先级高于加法和减法, 同级运算的顺序是从左到右, 表达式中使用括号可强行改变优先级的运算顺序。
MySQL 中没有提供字符串连接运算符, 即无法使用加号(+) 将字符串常量、 字符串变量或字符串列连接起来。 MySQL 使用 concat 函数来进行字符串连接运算。
如下 SQL 语句所示:
选择出teacher_name 和 'XX '字符串连接后的结果
select concat(teacher_name ,‘xx’)
from teacher_table;
对于 MySQL 而言, 如果在算术表达式中使用 null , 将会导致整个算术表达式的返回值为 null; 如果在字符串连接运算中出现 null, 将会导致连接后的结果也是 null。 如下 SQL 语句将会返回 null:
select concat(teacher_name, null)
from teacher_table;
如果不希望直接使用列名作为列标题, 则可以为数据列或表达式起一个别名, 为数据列或表达式起别名时, 别名紧跟数据列, 中间以空格隔开, 或者使用 as 关键字隔开。 如下 SQL 语句所示:
select teacher_id + 5 as MY_ID
from teacher table;
如果列别名中使用特殊字符( 例如空格), 或者需要强制大小写敏感, 都可以通过为别名添加双引号来实现。 如下 SQL 语句所示:
可以为选出的列起别名, 别名中包括单引号字符, 所以把别名用双引号引起来
select teacher_id + 5 “MY’id”
from teacher table;
如果需要选择多列, 并为多列起别名, 则列与列之间以逗号隔开, 但列和列别名之间以空格隔开。如下 SQL 语句所示:
select teacher_id + 5 MY_ID , teacher name 老师名
from teacher table;
不仅可以为列或表达式起别名, 也可以为表起别名, 为表起别名的语法和为列或表达式起别名的语法完全一样, 如下 SQL 语句所示:
select teacher_id + 5 MY_ID , teacher_name 老师名
为 teacher_table 起另lj名 t
from teacher_table t
前面己经提到, 列名可以当成变量处理, 所以运算符也可以在多列之间进行运算, 如下 SQL 语句所示:
select teacher_id + 5 MY_ID, concat(teacher_name , teacher_id) teacher_name
from teacher_table
where teacher id * 2 > 3;
甚至可以在 select、 where 子句中都不出现列名, 如下 SQL 语句所示·:
select 5 + 4
from teacher_table
where 2 < 9;
对于选择常量的情形, 指定数据表可能没有太大的意义, 所以 MySQL 提供了一种扩展语法, 允许 select 语句后没有 from 子句, 即可写成如下形式:
select 5 + 4;
select 默认会把所有符合条件的记录全部选出来, 即使两行记录完全一样。 如果想去除重复行, 则可以使用 distinct 关键字从查询结果中清除重复行。 比较下面两条 SQL 语句的执行结果:
选出所有记录, 包括重复行
select student_name,java_teacher
from student table;
去除重复行
select distinct student_name,java_teacher
from student table;
前面己经看到了 where 子句的作用一一可以控制只选择指定的行。 因为 where 子句里包含的是一个条件表达式, 所以可以使用>、 =和<>等基本的比较运算符。
SQL 中的比较运算符不仅可以比较数值之间的大小, 也可以比较字符串、 日期之间的大小。
SQL 中判断两个值是否相等的比较运算符是单等号, 判断不相等的运算符是◊; SQL中的赋值运算符不是等号, 而是冒号等号( := )。
除此之外, SQL 还支持如表 2所示的特殊的比较运算符。
表2
下面的 SQL 语句选出 student_id 大于等于 2, 且小于等于 4 的所有记录。
select * from student_table
where student id between 2 and 4;
使用 between val1 and val2 必须保证 val1 小于 val2,否则将选不出任何记录。 除此之外, between val1 and val2 中的两个值不仅可以是常量, 也可以是变量, 或者是列名也行。 如下 SQL 语句选出 java_teacher小于等于 2, student id 大于等于 2 的所有记录。
select from student_table
where 2 between java_teacher and student_id;
使用 in 比较运算符时, 必须在 in 后的括号里列出一个或多个值, 它要求指定列必须与 in 括号里任意一个值相等。 如下 SQL 语句所示:
选出 student_id 为 2 或 4 的所有记录
select * from student_table
where student id in(2, 4);
与之类似的是, in 括号里的值既可以是常量, 也可以是变量或者列名, 如下 SQL 语句所示:
选出 student_id、 java_teacher 列的值为 2 的所有记录
select * from student_table
where 2 in(student_id, java_teacher);
like 运算符主要用于进行模糊查询, 例如, 若要查询名字以“ 孙” 开头的所有记录, 这就需要用到模糊查询, 在模糊查询中需要使用 like 关键字。 SQL 语句中可以使用两个通配符: 下画线(_) 和百分号(% ), 其中下画线可以代表一个任意的字符, 百分号可以代表任意多个字符。 如下 SQL 语句将查询出所有学生中名字以“ ?小” 开头的学生。
select * from student table
where student name like ‘孙%’;
下面的 SQL 语句将查询出名字为两个字符的所有学生。
select * from student table
下面使用两个下画线代表两个字符
where student name like ‘__’;
在某些特殊的情况下, 查询的条件里需要使用下画线或百分号, 不希望 SQL 把下画线和百分号当成通配符使用, 这就需要使用转义字符, MySQL 使用反斜线(\ ) 作为转义字符, 如下 SQL 语句所示:
选出所有名字以下画线开头的学生
select * from student_table
where student name like ‘_%’;
标准 SQL 语句并没有提供反斜线(\ ) 的转义字符, 而是使用 escape 关键字显式进行转义。 例如,为了实现上面功能需要使用如下 SQL 语句:
#在标准的 SQL 中选出所有名字以下画线开头的学生
select from student_table
where student name like ‘_%’ escape ‘’;
is null 用于判断某些值是否为空, 判断是否为空不要用=111111 来判断, 因为 SQL 中 null=null 返回 null。
如下 SQL 语句将选择出 student_table 表中 student_name 为 null 的所有记录:
select from student_table
where student_name is null;
如果 where 子句后有多个条件需要组合, SQL 提供了 and 和 or 逻辑运算符来组合两个条件, 并提供了 not 来对逻辑表达式求否。 如下 SQL 语句将选出学生名字为 2 个字符, 且 student_id 大于 3 的所有记录。
select * from student_table
使 用 and 来 组 合 多 个 条 件
where student name like ‘__’ and student_id > 3;
下面的 SQL 语句将选出 student_table 表中姓名不以下画线开头的所有记录。
select * from student_table
使用not对where条件取否
where not student name like ‘_%’;
当使用比较运算符、 逻辑运算符来连接表达式时, 必须注意这些运算符的优先级。 SQL 中比较运算符、 逻辑运算符的优先级如表 3 所示:
表2:MySQL逻辑运算符优先级
如果 SQL 代码需要改变优先级的默认顺序, 则可以使用括号, 括号的优先级比所有的运算符高。
如下 SQL 语句使用括号来改变逻辑运算符的优先级:
select * from student table
使用括号强制先计算 or 运算
where (student_id > 3 or student_name > '张 ')
and java_teacher > 1;
执行查询后的查询结果默认按插入顺序排列; 如果需要查询结果按某列值的大小进行排序, 则可以使用 order by 子句。 order by 子句的语法格式如下:
order by column_name1 [desc] , column_name2 …
进行排序时默认按升序排列, 如果强制按降序排列, 则需要在列后使用 desc 关键字( 与之对应的是 asc 关键字, 用不用该关键字的效果完全一样, 因为默认是按升序排列)。
上面语法中设定排序列时可采用列名、 列序号和列别名。 如下 SQL 语句选出 student_table 表中的所有记录, 选出后按 java_teacher 列的升序排列。
select * from student_table
order by java_teacher;
如果需要按多列排序, 则每列的asc > desc 必须单独设定。 如果指定了多个排序列, 则第一个排序列是首要排序列, 只有当第一列中存在多个相同的值时,第二个排序列才会起作用。 如下 SQL 语句先按 java_teacher 列的降序排列, 当 java teacher 列的值相同时按 student name 列的升序排列。
select * from student_table
order by java_teacher desc , student_name;
==========================================================================
正如前面看到的连接字符串使用的 concat 函数, 每个数据库都会在标准的 SQL 基础上扩展一些函数, 这些函数用于进行数据处理或复杂计算, 它们通过对一组数据进行计算,得到最终需要的输出结果。
函数一般都会有一个或者多个输入, 这些输入被称为函数的参数, 函数内部会对这些参数进行判断和计算, 最终只有一个值作为返回值。 函数可以出现在 SQL 语句的各个位置, 比较常用的位置是 select 之后和 where 子句中。
根据函数对多行数据的处理方式, 函数被分为单行函数和多行函数, 单行函数对每行输入值单独计算, 每行得到一个计算结果返回给用户; 多行函数对多行输入值整体计算, 最后只会得到一个结果。
执行函数的语法如下:
function_name(argl, arg2 …)
多行函数也称为聚集函数、 分组函数, 主要用于完成一些统计功能, 在大部分数据库中基本相同。 但不同数据库中的单行函数差别非常大, MySQL 中的单行函数具有如下特征。
-
单行函数的参数可以是变量、 常量或数据列。单行函数可以接收多个参数, 但只返回一个值。
-
单行函数会对每行单独起作用, 每行( 可能包含多个参数) 返回一个结果。
-
使用单行函数可以改变参数的数据类型。 单行函数支持嵌套使用, 即内层函数的返回值是外层函数的参数。
MySQL 的单行函数分类如图所示:
MySQL 数据库的数据类型大致分为数值型、 字符型和日期时间型, 所以 MySQL 分别提供了对应的函数。转换函数主要负责完成类型转换,其他函数又大致分为如下几类。
-
位函数
-
流程控制函数
-
加密解密函数
-
信息函数
每个数据库都包含了大量的单行函数, 这些函数的用法也存在一些差异, 但有一点是相同的一一每个数据库都会为一些常用的计算功能提供相应的函数, 这些函数的函数名可能不同, 用法可能有差异,但所有数据库提供的函数库所能完成的功能大致相似, 读者可以参考各数据库系统的参考文档来学习这些函数的用法。
下面通过一些例子来介绍 MySQL 单行函数的用法:
选出 teacher_table 表中 teacher_name 列的字符长度
select char_length(teacher_name) from teacher_table;
计算 teacher_name 列的字符长度的 sin 值
select sin(char_length(teacher_name)) from teacher_table;
计算 1.57 的lin 值, 约等于 1
select sin(1.57);
为指定日期添加一定的时间
在这种用法下 interval 是关键字, 需要一个数值, 还需要一个单位
SELECT DATE_ADD(‘1998-01-02’ ,interval 2 MONTH);
这种用法更简单
select ADDDATE(‘1998-01-02’,3);
获取当前日期
select CURDATE();
获取当前时间
select curtime();
下面的 MD5 是 MD5 加密函数
select MD5(‘testing’);
MySQL 提供了如下几个处理 null 的函数。
-
ifnull(expr1,expr2): 如果 exprl 为 null, 则返回 expr2, 否则返回 exprl。
-
nullif(expr1,expr2): 如果 erprl 和 expr2 相等, 则返回 null, 否 则 返 回 exprl。
-
if(exprl,expr2,expr3): 有点类似于?:三目运算符, 如果 exprl 为 true, 不等于 0, 且不等于 null,则返回 expr2, 否 则 返 回 expr3。
-
isnull(expr1): 判断 exprl 是否为 null, 如 果 为 null 则 返 回 true, 否 则 返 回 false。
如果 student_name 列为 null, 则返回 '没有名字
select ifnull(student_name,'没有名字 ')from student_ table;
student 列等于 '张三 ’ , 则返回 null
select nullif(student_name, 1 张三 ')from student_table;
如果student_name 列为null, 则返回 ‘没有名字’, 否则返回 '有名字
select if(isnull(student_name),‘没有名字’, ‘有名字’ from student table;
MySQL 还提供了一个 case 函数, 该函数是一个流程控制函数:
一个用法的语法格式如下:
case value
when compare_valuel then resultl
when compare_value2 then result2
……
else result
end
case函数用 value 和后面的 compare_valuel 、 compare_value2、 …依次进行比较, 如果 value 和指定的 compare valuel 相等, 则返回对应的 resultl , 否 则 返 回 else 后的 result。 例如如下 SQL 语句:
如果 java_teacher 为 1, 则返回’Java 老师、 为 2 返回’Ruby 老师、 否则返回 '其他老师 ’
select student_name , case java_teacher
when 1 then ‘Java 老师’,
when 2 then 'Ruby 老师 ',
else '其他老师 ’
end
from student table;
case 函数第二个用法的语法格式如下:
case
when conditionl then resultl
when condition2 then result2
……
else result
end
在第二个用法中, condition1、 condition2 都是一个返回 boolean 值的条件表达式, 因此这种用法更加灵活。 例如如下 SQL 语句:
id 小于 3 的为初级班, 3 6 的为中级班, 其他的为高级班
select student
when student_id<=3 then ‘初级班’
when student_id<=6 then ‘中级班’
else ‘高级班’,
……
end
from student table;
虽然此处介绍了一些 MySQL 常用函数的简单用法, 但通常不推荐在 Java 程序中使用特定数据库的函数, 因为这将导致程序代码与特定数据库耦合; 如果需要把该程序移植到其他数据库系统上时, 可能需要打开源程序, 重新修改 SQL 语句。
MySQL中提供了三种循环:
- while
WHILE expression DO
statements
END WHILE
- loop
loop_name:loop
if 条件 THEN – 满足条件时离开循环
leave loop_name; – 和 break 差不多都是结束训话
end if;
end loop;
- repeat
REPEAT
statements;
UNTIL expression
END REPEAT
===========================================================================
组函数也就是前面提到的多行函数, 组函数将一组记录作为整体计算, 每组记录返回一个结果, 而不是每条记录返回一个结果。 常用的组函数有如下 5 个。
-
avg([distinct |all]expr): 计算多行expr 的平均值, 其中, expr 可以是变量、 常量或数据列, 但其数据类型必须是数值型。 还可以在变量、 列前使用 distinct 或 all 关键字, 如果使用 distinct, 则表明不计算重复值; all 用和不用的效果完全一样, 表明需要计算重复值。
-
count({ *|[distinct |all]expr}): 计算多行 expr 的总条数, 其中, expr 可以是变量、 常量或数据列,其数据类型可以是任意类型; 用星号( *)表示统计该表内的记录行数; distinct 表示不计算重复值。
-
max(expr): 计算多行 expr 的最大值, 其中 expr 可以是变量、 常量或数据列, 其数据类型可以是任意类型。
-
min(expr): 计算多行 expr 的最小值, 其中 expr 可以是变量、 常量或数据列, 其数据类型可以是任意类型。
-
sum([distinct|all]expr): 计算多行 expr 的总和, 其中, expr 可以是变量、 常量或数据列, 但其数据类型必须是数值型; distinct 表示不计算重复值。
计算 student_table 表中的记录条数
select count(*) from student_table;
计算 java_teacher 列总共有多少个值
select count(distinct java_teacher) from student_table;
统计所有 student_id 的总和
select sum(student_id) from student_table;
计 算 的 结 果 是 * 记 录 的 行 数
select sum(20) from student_table;
选出 student_table 表中 student_id 最大的值
select max(student_id) from student_table;
选出 teacher_table 表中 teacher_id 最小的值
select min(teacher_id) from teacher table;
因为 sum 里的 expr 是常量 34, 所以每行的值都相同
使用 distinct 强制不计算重复值, 所以下面计算结果为 34
select sum(distinct 34) from student_table;
使用 count 續计记录行数时, null 不会被计算在
select count(student_name) from student table;
在默认情况下, 组函数会把所有记录当成一组, 为了对记录进行显式分组, 可以在 select 语句后使用 group by 子句, group by 子句后通常跟一个或多个列名, 表明查询结果根据一列或多列进行分组当一列或多列组合的值完全相同时, 系统会把这些记录当成一组。 如下 SQL 语句所示:
count(*)将会对每组得到一个结果
select count(*)
from student_table
将 java_teacher 列值相同的记录当成一组
group by java_teacher;
如果对多列进行分组, 则要求多列的值完全相同才会被当成一组。 如下 SQL 语句所示:
select count(*)
from student_table
当 java_teacher、 student_name 两列的值完全相同时才会被当成一组
group by java_teacher , student_name;
对于很多数据库而言, 分组计算时有严格的规则一一如果查询列表中使用了组函数, 或者 select 语句中使用了 group by 分组子句, 则要求出现在 select 列表中的字段, 要么使用组函数包起来, 要么必须出现在 group by 子句中。 这条规则很容易理解, 因为一旦使用了组函数或使用了 group by 子句, 都将导致多条记录只有一条输出, 系统无法确定输出多条记录中的哪一条记录。
对于 MySQL 来说, 并没有上面的规则要求,如果某个数据列既没有出现在 group by 之后, 也没有使用组函数包起来, 则 MySQL 会输出该列的第一条记录的值。
如果需要对分组进行过滤, 则应该使用 having子句, having 子句后面也是一个条件表达式, 只有满足该条件表达式的分组才会被选出来。 having子句和 where 子句非常容易混淆, 它们都有过滤功能, 但它们有如下区别:
-
不 能 在 where 子句中过滤组, where 子句仅用于过滤行。 过滤组必须使用 having 子句。
-
不能在where 子句中使用组函数, having 子句才可使用组函数。
如下 SQL 语句所示:
select * from student_table
group by java_teacher
对组进行过滤 ^
having count(*) > 2;
===========================================================================
很多时候, 需要选择的数据并不是来自一个表, 而是来自多个数据表, 这就需要使用多表连接查询。
例如, 对于上面的 student_table 和 teacher_table 两个数据表, 如果希望查询出所有学生以及他的老师名字, 这就需要从两个表中取数据。
多表连接查询有两种规范, 较早的 SQL 92 规范支持如下几种多表连接查询。
-
等值连接。
-
非等值连接。
-
外连接。
-
广义笛卡儿积。
SQL 99 规范提供了可读性更好的多表连接语法, 并提供了更多类型的连接查询。 SQL 99 支持如下几种多表连接查询。
-
交叉连 接。
-
自然连接。
-
使用using子句的连接。
-
使用on子句的连接。
-
全外连接或者左、 右外连接
SQL 92 的多表连接语法比较简洁, 这种语法把多个数据表都放在 from 之后, 多个表之间以逗号隔开; 连接条件放在 where 之后, 与查询条件之间用 and 逻辑运算符连接。 如果连接条件要求两列值相等,则称为等值连接, 否则称为非等值连接; 如果没有任何连接条件, 则称为广义笛卡儿积。 SQL 92 中 多表连接查询的语法格式如下:
select columnl , column2 …
from tablel, table2 …
[where join_condition]
多表连接查询中可能出现两个或多个数据列具有相同的列名, 则需要在这些同名列之间使用表名前缀或表别名前缀作为限制, 避免系统混淆。
所有的列都可以增加表名前缀或表别名前缀。 只是进行单表查询时, 绝不可能出现同名列,所以系统不可能混淆, 因此通常省略表名前缀。
如下 SQL 语句查询出所有学生的资料以及对应的老师姓名。
select s.* , teacher_name
指定多个数据表, 并指定表别名
from student_table s , teacher_table t
使用 where 指定连接条件
where s.java_teacher = t.teacher_id;
只要把 where 后的连接条件去掉, 就可以得到广义笛卡儿积, 如下 SQL 语句所示:
不使用连接条件, 得到广义笛卡儿积
select s.* , teacher_name
指定多个数据表, 并指定表别名
from student_table s , teacher_table t;
与此类似的是, 非等值连接的执行结果可以使用上面的嵌套循环来计算, 如下 SQL 语句所示 :
select s.* , teacher name
指定多个数据表, 并指定表别名
from student_table s , teacher_table t
使用 where 指定连接条件, 非等值连接
where s.java_teacher > t.teacher_id;
如果还需要对记录进行过滤, 则将过滤条件和连接条存使用 and 连 接 起 如 下 SQL 语句所示:
select s.* , teacher name
指定多个数据表, 并指定表别名
from student_table s , teacher_table t
使用 where 定连接条件, 并指定 student_name 列不能为 null
where s.java_teacher = t.teacher_id and student_name is not null;
有一种自连接, 和自关联类似, 如果同一个表中的不同记录之间存在主、 外键约束关联, 例如把员工、 经理保存在同一个表里, 则需要使用自连接查询。
自连接只是连接的一种用法, 并不是一种连接类型 , 不管是 SQL 92 还是 SQL 99 都可以使用自连接查询。 自连接的本质就是把一个表当成两个表来用。
下面的 SQL 语句建立了一个自关联的数据表, 并向表中插入了 4 条数据。
create table emp_table(
emp_id int auto_increment primary key,
emp_name varchar(255),
manager_id int,
foreign key(manager_id) references emp_table(emp_id)
);
insert into emp_table
values(null , ’ 唐僧 ’ , null),
(null , , 孙悟空 , , 1),
(null , , 猪八戒 ’ , 1),
(null , ’ 沙僧’ , 1);
如果需要查询该数据表中的所有员工名, 以及每个员工对应的经理名, 则必须使用自连接查询。 所谓自连接就是把一个表当成两个表来用, 这就需要为一个表起两个别名, 而且查询中用的所有数据列都要加表别名前缀, 因为两个表的数据列完全一样。 下面的自连接查询可以查询出所有的员工名, 以及对应的经理名。
select emp.emp_id,emp.emp 员工名, mgr.emp 经理名
from emp_table emp,emp_table mgr
where emp.manager_id = mgr.emp_id;
SQL 99 的连接查询与 SQL 92 的连接查询原理基本相似, 不同的是 SQL 99 连接查询的可读性更强,查询用的多个数据表显式使用 xxx join 连接, 而不是直接依次排列在 from 之后, from 后只需要放一个数据表; 连接条件不再放在where 之后, 而是提供了专门的连接条件子句。
- 交叉连接( cross join ): 交叉连接效果就是 SQL 92 中的广义笛卡儿积, 所以交叉连接无须任何连接条件, 如下 SQL 语句所示:
select s.* , teacher_name
SQL 99 多表连接查询&from 后只有一个表名
from student_table s
cross join交叉连接, 相当于广义笛卡儿积
cross join teacher_table t;
- 自然连接( naturaljoin ): 自然连接表面上看起来也无须指定连接条件, 但自然连接是有连接条件的, 自然连接会以两个表中的同名列作为连接条件; 如果两个表中没有同名列, 则自然连接与交叉连接效果完全一样一一因为没有连接条件。 如下 SQL 语句所示:
select s.* , teacher_name
SQL 99 多表连接查询&
from 后只有一个表名
from student_table s
natural join 自然连接使用两个表中的同名列作为连接条件
natural join teacher_table t;
- using 子句连接: using 子句可以指定一列或多列, 用于显式指定两个表中的同名列作为连接条件。 假设两个表中有超过一列的同名列, 如果使用 natural join, 则会把所有的同名列当成连接条件; 使用 using 子句, 就可显式指定使用哪些同名列作为连接条件。 如下 SQL 语句所示:
select s.* , teacher_name
SQL 99 多表连接查询&
from 后只有一个表名
from student_table s
join 连接另一个表
join teacher_table t
using(teacher_id);
运行上面语句将出现一个错误, 因为 student_table 表中并不存在名为 teacher _id 的列。 也就是说,如果使用 using 子句来指定连接条件, 则两个表中必须有同名列, 否则就会出现错误。
- on 子句连接: 这是最常用的连接方式, SQL 99 语法的连接条件放在 on 子句中指定, 而且每个on子句只指定一个连接条件。 这意味着: 如果需要进行N表连接, 则需要有 N-1个 join…on 对。
如下 SQL 语句所示:
select s.* , teacher_name
SQL 99 多表连接查询的
“”
from 后只有一个表名
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/d944d9fc62d61fd6ee3cd66c4d126d45.jpeg)
最后
ActiveMQ消息中间件面试专题
- 什么是ActiveMQ?
- ActiveMQ服务器宕机怎么办?
- 丢消息怎么办?
- 持久化消息非常慢怎么办?
- 消息的不均匀消费怎么办?
- 死信队列怎么办?
- ActiveMQ中的消息重发时间间隔和重发次数吗?
ActiveMQ消息中间件面试专题解析拓展:
redis面试专题及答案
- 支持一致性哈希的客户端有哪些?
- Redis与其他key-value存储有什么不同?
- Redis的内存占用情况怎么样?
- 都有哪些办法可以降低Redis的内存使用情况呢?
- 查看Redis使用情况及状态信息用什么命令?
- Redis的内存用完了会发生什么?
- Redis是单线程的,如何提高多核CPU的利用率?
Spring面试专题及答案
- 谈谈你对 Spring 的理解
- Spring 有哪些优点?
- Spring 中的设计模式
- 怎样开启注解装配以及常用注解
- 简单介绍下 Spring bean 的生命周期
Spring面试答案解析拓展
高并发多线程面试专题
- 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
- Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
- Java 中 wait 和 sleep 方法有什么区别?
- 如何在 Java 中实现一个阻塞队列?
- 如何在 Java 中编写代码解决生产者消费者问题?
- 写一段死锁代码。你在 Java 中如何解决死锁?
高并发多线程面试解析与拓展
jvm面试专题与解析
- JVM 由哪些部分组成?
- JVM 内存划分?
- Java 的内存模型?
- 引用的分类?
- GC什么时候开始?
JVM面试专题解析与拓展!
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!
SQL 语句所示:
select s.* , teacher_name
SQL 99 多表连接查询&
from 后只有一个表名
from student_table s
join 连接另一个表
join teacher_table t
using(teacher_id);
运行上面语句将出现一个错误, 因为 student_table 表中并不存在名为 teacher _id 的列。 也就是说,如果使用 using 子句来指定连接条件, 则两个表中必须有同名列, 否则就会出现错误。
- on 子句连接: 这是最常用的连接方式, SQL 99 语法的连接条件放在 on 子句中指定, 而且每个on子句只指定一个连接条件。 这意味着: 如果需要进行N表连接, 则需要有 N-1个 join…on 对。
如下 SQL 语句所示:
select s.* , teacher_name
SQL 99 多表连接查询的
“”
from 后只有一个表名
自我介绍一下,小编13年上海交大毕业,曾经在小公司待过,也去过华为、OPPO等大厂,18年进入阿里一直到现在。
深知大多数Java工程师,想要提升技能,往往是自己摸索成长或者是报班学习,但对于培训机构动则几千的学费,着实压力不小。自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前!
因此收集整理了一份《2024年Java开发全套学习资料》,初衷也很简单,就是希望能够帮助到想自学提升又不知道该从何学起的朋友,同时减轻大家的负担。[外链图片转存中…(img-FqKgm2gq-1712522401370)]
[外链图片转存中…(img-Qvg69th2-1712522401371)]
[外链图片转存中…(img-X8R6js27-1712522401371)]
既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,基本涵盖了95%以上Java开发知识点,真正体系化!
由于文件比较大,这里只是将部分目录截图出来,每个节点里面都包含大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并且会持续更新!
如果你觉得这些内容对你有帮助,可以扫码获取!!(备注Java获取)
![img](https://i-blog.csdnimg.cn/blog_migrate/d944d9fc62d61fd6ee3cd66c4d126d45.jpeg)
最后
ActiveMQ消息中间件面试专题
- 什么是ActiveMQ?
- ActiveMQ服务器宕机怎么办?
- 丢消息怎么办?
- 持久化消息非常慢怎么办?
- 消息的不均匀消费怎么办?
- 死信队列怎么办?
- ActiveMQ中的消息重发时间间隔和重发次数吗?
ActiveMQ消息中间件面试专题解析拓展:
[外链图片转存中…(img-ncK6waa3-1712522401371)]
redis面试专题及答案
- 支持一致性哈希的客户端有哪些?
- Redis与其他key-value存储有什么不同?
- Redis的内存占用情况怎么样?
- 都有哪些办法可以降低Redis的内存使用情况呢?
- 查看Redis使用情况及状态信息用什么命令?
- Redis的内存用完了会发生什么?
- Redis是单线程的,如何提高多核CPU的利用率?
[外链图片转存中…(img-kGc0iuHu-1712522401371)]
Spring面试专题及答案
- 谈谈你对 Spring 的理解
- Spring 有哪些优点?
- Spring 中的设计模式
- 怎样开启注解装配以及常用注解
- 简单介绍下 Spring bean 的生命周期
Spring面试答案解析拓展
[外链图片转存中…(img-Iyw7ubPY-1712522401372)]
高并发多线程面试专题
- 现在有线程 T1、T2 和 T3。你如何确保 T2 线程在 T1 之后执行,并且 T3 线程在 T2 之后执行?
- Java 中新的 Lock 接口相对于同步代码块(synchronized block)有什么优势?如果让你实现一个高性能缓存,支持并发读取和单一写入,你如何保证数据完整性。
- Java 中 wait 和 sleep 方法有什么区别?
- 如何在 Java 中实现一个阻塞队列?
- 如何在 Java 中编写代码解决生产者消费者问题?
- 写一段死锁代码。你在 Java 中如何解决死锁?
高并发多线程面试解析与拓展
[外链图片转存中…(img-gRvwnnci-1712522401372)]
jvm面试专题与解析
- JVM 由哪些部分组成?
- JVM 内存划分?
- Java 的内存模型?
- 引用的分类?
- GC什么时候开始?
JVM面试专题解析与拓展!
[外链图片转存中…(img-tygo1ymw-1712522401372)]
《一线大厂Java面试题解析+核心总结学习笔记+最新讲解视频+实战项目源码》,点击传送门即可获取!