外键
一对多
- 一:主表
- 多:从表
- 在一对多关系中,在多的一方设置一个外键,用来体现一对多的关系。
- 外键的特点:
- 从表(多的一方)外键的值是对主表(一的一方)主键的引用;
- 从表外键类型必须与主表主键类型一致;
声明外键约束
添加外键
- 方式一:直接在创建表的时候添加。单独一行写
foreign key(从表外键字段名字) references 主表名字(主表主键名字) - 方式二:通过alter来添加。
alter table 从表名字 add [constraint] [外键名字] foreign key(从表外键字段名字) references 主表(主表主键名字)
删除外键
alter table 从表名字 drop foreign key 外键名字- 注意:这里的“外键名字”不是外键字段的名字,而是设置外键时写的外键名字。
设置外键的目的是为了保证数据的完整性
表与表之间的关系
一对多
上面已经讲过,此处不再赘述。
多对多
- 例子:学生选课。一个学生可以选很多门课。一门课可以被很多学生选。所以,学生与课程之间的关系就是多对多。
- 多对多的关系需要通过建立第三张表来体现。
- 学生表(主键为sid)
- 课程表(主键为cid)
- 第三张表(也叫从表or中间表,因为有外键,有外键的都叫从表)。
- 该从表至少有两个字段(一个是引用学生表的外键,另一个是引用课程表的外键),注意是至少两个字段,也可以有其他字段。
- sno:引用学生表主键的外键。
- cno:引用课程表主键的外键。
- 其实,此处的sno和cno都是外键,设置外键的方式与一对多那里的是一样的,只不过要分别设置引用的主键(因为这里的两个外键分别引用了不同表的主键)。
- 联合主键的设置
- 方式一:在建表时直接设置联合主键。
primary key(字段1,字段2) - 方式二:通过alter添加联合主键。
alter table table_name [constraint 别名] add primary key (字段1,字段2);。- 如果上述操作提示“不能设置多个主键”,则需要先删除原先的主键再设置联合主键。
alter table table_name drop primary key add primary key(字段1,字段2)。
- 如果上述操作提示“不能设置多个主键”,则需要先删除原先的主键再设置联合主键。
- 方式一:在建表时直接设置联合主键。
一对一
- 一对一的关系在实际开发中使用的比较少,因为一对一关系可以写在一张表里,不需要写两张表。
- 但是,如果非要写两张表,处理一对一的方法有两种:
- 外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,从表外键唯一unique。
- 外键是主键:主表的主键和从表的主键形成主外键关系。
查询
多表查询
交叉连接查询
- 语句:
select * from A,B;。其实就是没有where子句的隐式内连接。 - 结果:得到的结果是笛卡尔乘积,也就是两个表的乘积。
- 结论:交叉连接查询一般用的比较少。
自然连接查询
- 解释:自然连接是一种特殊的等值连接,它要求两张表中进行比较的必须是同名属性列,并且不需要添加连接条件,在查询结果中消除同名属性列(所有同名属性列只保留一个)。
- 语句:
select * from A natural join B
内连接查询
- 解释:内连接与自然连接差不多,只不过内连接不要求比较两张表的同名属性列,可以使用on来指定两张表比较的字段(比较的字段不要求同名);而且内连接的条件可以不写,如果不写就是查询的是笛卡尔积。
- 显式内连接:
- 语句:
select * from A [A表的别名] inner join B [B表的别名] [on 查询条件]; - 结果:得到的结果是根据条件查询得到的一一对应的结果集。
- 语句:
- 隐式内连接:
- 语句:
select * from A [A表的别名],B [B表的别名] where 查询条件; - 结果:得到的结果也是根据条件查询得到的一一对应的结果集。
- 结论:隐式内连接用的是比较多的。
- 语句:
外连接查询
- 解释
- 在内连接查询中,不符合条件的记录会被舍弃,不会出现在结果集中;那么如果想要把这些被舍弃的记录也保留在结果集中,就需要使用到外连接查询。
- 外连接必须使用on来指定查询条件。
- 外连接的分类:
- 左外连接:把左表中要舍弃的记录也保留在结果集中,右表中相对应的部分用null填充
- 右外连接:把右表中要舍弃的记录也保留在结果集中,左表中相对应的部分用null填充。
- 全外连接:把左表和右表中要舍弃的记录都保留在结果集中,右表和左表中中相对应的部分用null填充。
- 左外连接
- 语句:
select * from A [A表的别名] left [outer] join B [B表的别名] on 条件; - 结果:得到的结果是全部的左表结果以及对应的右表结果,如果没有相对应的右表,那么该行右表全部用null代替。
- 结论:左外连接查询是全部的左表信息,右表不匹配的部分用null代替。
- 语句:
- 右外连接
- 语句:
select * from A [A表的别名] right [outer] join B [B表的别名] on 条件; - 结果:得到的结果是全部的右表信息以及对应的左表信息,如果没有对应的左表,那么该行左表全部用null代替。
- 结论:右外连接查询是查询全部的右表信息,左表不匹配的部分用null代替。
- 语句:
- 全外连接:MySQL暂时不支持全外连接,可以使用其他方式代替。
子查询
- 解释:子查询就是一条查询语句的结果作为另一条查询语句的一部分(可以是查询条件、查询结果等)。
- 案例
- 需求:把商品表中商品名字带有“鼠标”二字的商品的分类设置为“鼠标大类”。
- 实现:
- 01、先在分类表中查询到分类名为“鼠标大类”的cid。
- 02、02比较商品表中的cid与上一步中查询到的cid来更新商品表中的cid字段。
- 具体命令
JDBC工具类的抽取
版本一
- 获取连接
- 释放资源
版本二
- 把数据库基本的信息放入配置文件中:
- 好处:当数据库信息有改动时,不需要去修改源代码,只需要修改配置文件里面的配置信息。
- 配置文件的书写格式:
key=value - 获取配置文件里的信息:
ResourceBundle rb=ResourceBundle.getBundle("XXX");- XXX是配置文件的名字,例如,有配置文件:db.properties,那么就应该写“db”。不需要写后缀。
String value=rb.getString("key");
- 其余部分的代码与版本一都一样。
版本三
- 也是把数据库基本的信息放入配置文件中,只是获取配置文件信息的方式不一样。
- 只不过,获取配置信息的方式不一样,这里是使用Properties对象来获取的,具体的细节请参考java基础中IO流那一节的笔记。