11、☆☆☆ mybatis中的一对多多对一详解
测试环境搭建
1.导入lombok
2.新建实体类Teacher, Student
3.建立Mapper接口
4.建立Mapper.XML文件
5.在核心配置文件中绑定注册我们的Mapper接口或者文件! [方式很多, 随心选]
6.测试查询是否能够成功!
mysql表:
CREATE TABLE `teacher` ( `id` INT(10) NOT NULL, `name` VARCHAR(30) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO teacher(`id`,`name`) VALUES (1, '秦老师'); CREATE TABLE `student` ( `id` INT(10) NOT NULL, `name` VARCHAR(30) DEFAULT NULL, `tid` INT(10) DEFAULT NULL, PRIMARY KEY (`id`), KEY `fktid` (`tid`), CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES `teacher` (`id`) ) ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('1', '小明', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('2', '小红', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('3', '小张', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('4', '小李', '1'); INSERT INTO `student` (`id`, `name`, `tid`) VALUES ('5', '小王', '1');
· 多对一:(多个学生有一个老师):
@Data @AllArgsConstructor @NoArgsConstructor public class Student { private int id; private String name;
//多个学生对应一个老师 private Teacher teacher; }
查询出来学生,以及学生对应的老师名字
通过普通方式进行查找:
<方式1.>按照查询嵌套处理(子查询):
解决思路:
1.查询所有的学生信息
2.根据查询出来的学生的tid,寻找对应的老师!
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zhixi.dao.StudentMapper"> <!-- 思路: 1. 查询所有的学生信息 2. 根据查询出来的学生的tid,寻找对应的老师! --> <resultMap id="student_teacher" type="student"> <!--property:实体类属性 column:sql字段--> <result property="id" column="id"/> <result property="name" column="name"/> <!--复杂的属性,我们需要单独处理对象: association 集合: collection -->
<!--javaType:指定pojo实体类中的属性类型 ofType:指定集合属性的类型-->
<association property="teacher"javaType="teacher" select="getTeacher"/> </resultMap> <select id="getStudent" resultMap="student_teacher"> select * from student ; </select> <!--resultType="teacher"这个是用包机制器的别名,表示返回老师这个对象--> <select id="getTeacher" resultType="teacher"> select * from teacher t; </select> </mapper>
结果:
Student(id=1, name=小明, teacher=Teacher(id=1, name=秦老师))
Student(id=2, name=小红, teacher=Teacher(id=1, name=秦老师))
Student(id=3, name=小张, teacher=Teacher(id=1, name=秦老师))
Student(id=4, name=小李, teacher=Teacher(id=1, name=秦老师))
Student(id=5, name=小王, teacher=Teacher(id=1, name=秦老师))
<方式2、>按照结果嵌套处理:
1.查询所有的学生信息
2.根据查询出来的学生的tid,寻找对应的老师!
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zhixi.dao.StudentMapper"> <!--做字段的映射--> <resultMap id="student_teacher2" type="student"> <result property="id" column="sid"/> <result property="name" column="sname"/>
<!--javaType:指定pojo实体类中的属性类型 ofType:指定集合属性的类型-->
<association property="teacher" column="tid" javaType="teacher"> <!--在老师表中嵌套查询--> <result property="name" column="tname"/> <!--老师实体类中的id对应SQL表中的id(as了一个新的名字)--> <result property="id" column="tid"/> </association> </resultMap> <select id="getStudent2" resultMap="student_teacher2"> select s.id as sid ,s.name as sname ,t.id as tid ,t.name as tname from student s,teacher t where s.tid = t.id; </select> </mapper>
Student(id=1, name=小明, teacher=Teacher(id=1, name=秦老师))
Student(id=2, name=小红, teacher=Teacher(id=1, name=秦老师))
Student(id=3, name=小张, teacher=Teacher(id=1, name=秦老师))
Student(id=4, name=小李, teacher=Teacher(id=1, name=秦老师))
Student(id=5, name=小王, teacher=Teacher(id=1, name=秦老师))
· 一对多:(一个老师有多个学生):
@Data @AllArgsConstructor @NoArgsConstructor public class Teacher { private int id; private String name; //一个老师拥有多个学生 private List<Student> students; }
普通方式查找:可以看到查询到的学生信息为null
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Config 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.zhixi.dao.TeacherMapper"> <select id="getTeacher" resultType="teacher"> select * from teacher; </select> </mapper>
Teacher(id=1, name=秦老师, students=null)
按照结果嵌套处理:
方法接口:
public interface TeacherMapper { //获取指定老师id下所有的学生 Teacher getStudents(@Param("tid") int id); }
TeacherMapper.xml:
<resultMap id="getStudentMap" type="teacher"> <result property="id" column="tid"/> <result property="name" column="tname"/> <!--association:表示对象 collection:表示集合--> <!--javaType:指定pojo实体类中的属性类型 ofType:指定集合属性的类型--> <collection property="students" ofType="student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <result property="tid" column="tid"/> </collection> </resultMap> <select id="getStudents" resultMap="getStudentMap"> select s.id as sid,s.name as sname,t.id as tid,t.name as tname from student s,teacher t where s.tid = t.id and t.id = #{tid}; </select>
结果:
Teacher(
id=1,
name=秦老师,
students=[
Student(id=1, name=小明, tid=1),
Student(id=2, name=小红, tid=1),
Student(id=3, name=小张, tid=1),
Student(id=4, name=小李, tid=1),
Student(id=5, name=小王, tid=1)
]
)
总结:
javatype和ofType 都是用来指明对象类型, 区别在于使用的场合不一样,
javatype是在pojo属性类型,
ofType指定是当对象需要Collection进行list集合映射对象的时候使用 ofType,也就是一对多映射的时候使用
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话