不会还有人不知道mybatis的关联查询吧?
Posted 客官不爱喝酒
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了不会还有人不知道mybatis的关联查询吧?相关的知识,希望对你有一定的参考价值。
前言:我也是花了好久的时间进行思考,该如何把这个发展的关联查询给描述出来,来今天我们就来看看这个mybatis关联查询到的是怎么样进行关联的,码字不易,如果你觉得该文章对你有用请一键三连。
1.数据库表和实体类关系分析:
数据库表之间的关系无非就是三种:一对一,一对多,多对多
1.首先需要搞懂一对一,一对多,对多之间的关系,然后数据库表是怎么表示的?利用java的面向对象思维是怎么表示的?然后就是sql查询该怎么写?然后通过mybatis关系映射标签表示他们之间的对应关系,怎么把查询出来结果集封装到相应的对象中,然后就是你自己能不能举个一对一,一对多,多对多的业务逻辑关系,自己建立数据库表,自己建立实体类对应关系,自己使用myabtis查询出对应的结果,能举出例子你才是真的学会了。记住 收藏不一定等于学会,看了学了也不一定等于学会。那么什么才交学会呢?就是自己能根据这个知识点能够想一个具体的例子并且实现,还能把这个例子给别人描述清楚,别人能懂。那么我相信,你肯定也就明白了。
一对一:
- 外键唯一:主表的主键和从表的外键(唯一),形成主外键关系,外键唯一unique。
- 外键是主键:主表的主键和从表的主键,形成主外键关系。
看个例子:比如一个学生对一张学生卡,也就是说一个学生只能有一张学生卡,而这张学生卡也只能属于这个学生。
我们来看下数据库表之间怎么表示一对一的关系
我们在来看下java里面利用面向对象的思维是怎么实现一对一的关系的。
一对多:
在多的一方创建一个字段,字段作为外键指向一的一方的主键。
举个例子:一个学生对应一个班级,一个学生只能属于某个班级,一个班级下可以有多个学生,这就是一对多的关系。
数据库表之间对应关系的表示:
利用java面向对象的方式表示一对多;
多对多:
需要创建第三张表,中间表中至少两个字段,这两个字段分别作为外键指向各自一方的主键。
例子:比如学生和老师之间的关系,一个学生可以有多个任课1老师,一个任课老师也可以有多名学生。
数据库表关系描述:
利用java的面向对象思维描述:
我这里已经把数据库表给大家准备好了,大家只需要复制粘贴进行运行就好了,注意不同版本的数据库,可能会出现异常,我这里使用的是5.7的版本,也可以根据我这里的字段类型自己去创建,利用可视化工具去创建也是非常快的。
2.数据库表准备:
t_class表
DROP TABLE IF EXISTS `t_class`;
CREATE TABLE `t_class` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`class_name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 3 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_class
-- ----------------------------
INSERT INTO `t_class` VALUES (101, '软件工程');
INSERT INTO `t_class` VALUES (102, '云计算');
SET FOREIGN_KEY_CHECKS = 1;
t_student表:
DROP TABLE IF EXISTS `t_student`;
CREATE TABLE `t_student` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`name` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`age` int(11) NULL DEFAULT NULL,
`class_id` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `class_id`(`class_id`) USING BTREE,
CONSTRAINT `t_student_ibfk_1` FOREIGN KEY (`class_id`) REFERENCES `t_class` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_student
-- ----------------------------
INSERT INTO `t_student` VALUES (1, '张三', 18, 101);
INSERT INTO `t_student` VALUES (2, '李四', 19, 101);
INSERT INTO `t_student` VALUES (3, '小明', 20, 102);
INSERT INTO `t_student` VALUES (4, '王五', 16, 102);
SET FOREIGN_KEY_CHECKS = 1;
t_student_card表:
DROP TABLE IF EXISTS `t_student_card`;
CREATE TABLE `t_student_card` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) NULL DEFAULT NULL,
`student_card` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NULL DEFAULT NULL,
`balance` int(255) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `student_id`(`student_id`) USING BTREE,
CONSTRAINT `t_student_card_ibfk_1` FOREIGN KEY (`student_id`) REFERENCES `t_student` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_student_card
-- ----------------------------
INSERT INTO `t_student_card` VALUES (1, 1, '1001', 200);
INSERT INTO `t_student_card` VALUES (2, 2, '1002', 220);
INSERT INTO `t_student_card` VALUES (3, 3, '1003', 100);
INSERT INTO `t_student_card` VALUES (4, 4, '1004', 500);
SET FOREIGN_KEY_CHECKS = 1;
t_student_teacher表:
DROP TABLE IF EXISTS `t_student_teacher`;
CREATE TABLE `t_student_teacher` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`m_student_id` int(11) NULL DEFAULT NULL,
`m_teacher_id` int(11) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE,
INDEX `m_student_id`(`m_student_id`) USING BTREE,
INDEX `m_teacher_id`(`m_teacher_id`) USING BTREE,
CONSTRAINT `t_student_teacher_ibfk_1` FOREIGN KEY (`m_student_id`) REFERENCES `t_student` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT,
CONSTRAINT `t_student_teacher_ibfk_2` FOREIGN KEY (`m_teacher_id`) REFERENCES `t_teacher` (`id`) ON DELETE RESTRICT ON UPDATE RESTRICT
) ENGINE = InnoDB AUTO_INCREMENT = 9 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_student_teacher
-- ----------------------------
INSERT INTO `t_student_teacher` VALUES (1, 1, 1);
INSERT INTO `t_student_teacher` VALUES (2, 1, 2);
INSERT INTO `t_student_teacher` VALUES (3, 1, 3);
INSERT INTO `t_student_teacher` VALUES (4, 1, 4);
INSERT INTO `t_student_teacher` VALUES (6, 2, 2);
INSERT INTO `t_student_teacher` VALUES (7, 3, 2);
INSERT INTO `t_student_teacher` VALUES (8, 4, 2);
SET FOREIGN_KEY_CHECKS = 1;
t_teacher表:
DROP TABLE IF EXISTS `t_teacher`;
CREATE TABLE `t_teacher` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`teacher` varchar(255) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci NOT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_general_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of t_teacher
-- ----------------------------
INSERT INTO `t_teacher` VALUES (1, 'admin');
INSERT INTO `t_teacher` VALUES (2, 'root');
INSERT INTO `t_teacher` VALUES (3, 'Tom');
INSERT INTO `t_teacher` VALUES (4, 'jack');
SET FOREIGN_KEY_CHECKS = 1;
表已经建立好了,大家可以通过以下sql进行感受下他们直接的对应关系:
一对多:
查询某个学生是属于那个班级的:
select s.*,c.id as cid ,c.class_name from t_student s left join t_class c on s.class_id =c.id where s.id=1;
查询某个班级下有哪些学生?
select * from t_class c join t_student s on c.id=s.class_id where c.id=101; 需要注意的是联合查询两个表中的主键字段名都为id会有问题,需要取别名
一对一:
查询某个学生的余额信息:
select * from t_student s left join t_student_card c on s.id =c.student_id where s.id=1;
根据学生卡号查询这个余额对应的是那个学生?
select * from t_student s right join t_student_card c on s.id =c.student_id where c.student_card='1003';
多对多
查询某个学生的任教老师有哪些?
select s.id as sid,s.name,s.age,s.class_id,t.id as tid, t.teacher from t_student s left join t_student_teacher m on s.id= m.m_student_id left join t_teacher t on m.m_teacher_id=t.id where s.id=1;
查询某个老师底下后哪些学生?
select s.id as sid,s.name,s.age,s.class_id, t.id as tid , t.teacher from t_teacher t left join t_student_teacher m on t.id=m.m_teacher_id left join t_student s on m.m_student_id=s.id where t.id=2;
因为写的比较匆忙,可能sql写的不是很好,但是能用,如果你有更好的写法,可以进行优化。
3.mybatis关系映射标签说明:
resultMap:封装返回的结果集
id:数据库表中对应的id字段
result: 数据库表中的普通字段
collections:一对多关系属性映射标签
association:一对一关系属性映射标签
property:java中实体类属性
column:数据库字段
type:java实体类的类名配合association进行使用
ofType:java实体类类名配合collections进行使用
4.具体代码实现过程:
1.实体类
Class:班级实体类
/ 班级类 对应数据库中的 班级表
public class Class {
// 自增主键id
private int classId;
// 班级名称
private String className;
// 建立学生表和班级表一对多的关系
private List<Student> studentList;
public int getClassId() {
return classId;
}
public void setClassId(int classId) {
this.classId = classId;
}
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public List<Student> getStudentList() {
return studentList;
}
public void setStudentList(List<Student> studentList) {
this.studentList = studentList;
}
@Override
public String toString() {
return "Class{" +
"classId=" + classId +
", className='" + className + '\\'' +
'}';
}
}
Student:学生实体类:
// 学生类 对应数据库中学生表
public class Student {
// 自增主键id
private int studentId;
// 学生姓名
private String name;
// 学生年龄
private int age;
// 学生的班级编号
private int classId;
// 建立学生表和学生卡表的一对一关系
private StudentCard studentCard;
//建立学生表和班级表一对多的关系
private Class studentClass;
// 建立学生表和教师表多对多关系
private List<Teacher> teacherList;
public List<Teacher> getTeacherList() {
return teacherList;
}
public void setTeacherList(List<Teacher> teacherList) {
this.teacherList = teacherList;
}
public int getStudentId() {
return studentId;
}
public void setStudentId(int studentId) {
this.studentId = studentId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public int getClassId() {
return classId;
}
public void setClassId(int classId) {
this.classId = classId;
}
public StudentCard getStudentCard() {
return studentCard;
}
public void setStudentCard(StudentCard studentCard) {
this.studentCard = studentCard;
}
public Class getStudentClass() {
return studentClass;
}
public void setStudentClass(Class studentClass) {
this.studentClass = studentClass;
}
@Override
public String toString() {
return "Student{" +
"studentId=" + studentId +
", name='" + name + '\\'' +
", age=" + age +
", classId=" + classId +
'}';
}
}
StudentCard:学生卡类
// 学生卡类 对应数据库中的学生卡表
public class StudentCard {
// 自增主键id
private int cardId;
// 学生的id
private int studentId;
// 学生的卡号
private String studentCard;
// 学生卡的余额
private int balance;
// 建立学生卡和学生之间的一对一关系
private Student student;
public int getCardId() {
return cardId;
}
public void setCardId(int cardId) {
this.cardId = cardId;
以上是关于不会还有人不知道mybatis的关联查询吧?的主要内容,如果未能解决你的问题,请参考以下文章
不会吧,不会吧,还有人不知道用selenium的等待方式吗?
不会吧,不会吧,不会还有人不知道❤️Python给图片加水印❤️超级简单哦