五、多对一
需求
- 对于学生而言,都有一位老师
- 对于老师而言,有多名学生
- 在学生角度看,学生和老师就是多对一的关系
- 要求输出学生的所有信息,包括他的老师
新实体类
学生
@Data @AllArgsConstructor @NoArgsConstructor public class Student { private String id; private String name; private Teacher teacher; }
老师
@Data @AllArgsConstructor @NoArgsConstructor public class Teacher { private String id; private String name; }
方法一
先查询学生信息,再根据老师ID,查询对应老师信息
mapper接口
public interface StudentMapper { /** * 查询学生所有信息,包括其对应的老师 方法1 * @return */ List<Student> findAllStudentMessages1(); }
XML具体实现
<?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="zwz.mapper.StudentMapper"> <!--需求: 查询学生所有信息,包括其对应的老师--> <!-- 1. 查询所有学生,设置resultMap --> <select id="findAllStudentMessages1" resultMap="teacherAndStudent1"> select * from student; </select> <!-- 2. 关联映射, association为对象标签 --> <resultMap id="teacherAndStudent1" type="student"> <result column="id" property="id"/> <result column="name" property="name"/> <!-- property:在Student类中的变量名 | column:数据库的字段 | javaType:Java对象 | select:数据来源 --> <association property="teacher" column="teacher" javaType="zwz.pojo.Teacher" select="findTeacherById"/> </resultMap> <!-- 3. 补充第二步的数据来源 --> <select id="findTeacherById" resultType="teacher"> select * from teacher where id = #{teacher}; </select> </mapper>
测试
@Test public void testFindAllStudentMessages1(){ SqlSession session = MybatisUtils.getSqlSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); List<Student> students = mapper.findAllStudentMessages1(); for (Student student : students) { System.out.println(student); } }
日志输出
可以看出,系统先执行 select * from student,然后根据查询到的老师ID,再执行 select * from teacher where id = ?
Created connection 1651162064. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@626abbd0] ==> Preparing: select * from student; ==> Parameters: <== Columns: id, name, teacher <== Row: 5992b89d9cfd4f0ba79a2991e108d017, ZWZ5, 5992b89d9cfd4f0ba79a2991e108d0b7 ====> Preparing: select * from teacher where id = ?; ====> Parameters: 5992b89d9cfd4f0ba79a2991e108d0b7(String) <==== Columns: id, name <==== Row: 5992b89d9cfd4f0ba79a2991e108d0b7, 郑老师 <==== Total: 1 <== Row: 5992b89d9cfd4f0ba79a2991e108d1b7, ZWZ1, 5992b89d9cfd4f0ba79a2991e108d0b7 <== Total: 2 Student(id=5992b89d9cfd4f0ba79a2991e108d017, name=ZWZ5, teacher=Teacher(id=5992b89d9cfd4f0ba79a2991e108d0b7, name=郑老师)) Student(id=5992b89d9cfd4f0ba79a2991e108d1b7, name=ZWZ1, teacher=Teacher(id=5992b89d9cfd4f0ba79a2991e108d0b7, name=郑老师)) Process finished with exit code 0
方法二
使用SQL语句做关联查询,再匹配到对应字段
mapper接口
public interface StudentMapper { /** * 查询学生所有信息,包括其对应的老师 方法2 * @return */ List<Student> findAllStudentMessages2(); }
XML具体实现
<?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="zwz.mapper.StudentMapper"> <!--需求: 查询学生所有信息,包括其对应的老师--> <!-- 1. 查询所有学生和老师的关联结果,设置resultMap --> <select id="findAllStudentMessages2" resultMap="teacherAndStudent2"> select t.id tid,t.name tname,s.id,s.name,s.teacher from teacher t,student s where s.teacher = t.id; </select> <!-- 2. 分别对应--> <resultMap id="teacherAndStudent2" type="student"> <result column="id" property="id"/> <result column="name" property="name"/> <association property="teacher" javaType="teacher"> <result column="tid" property="id"/> <result column="tname" property="name"/> </association> </resultMap> </mapper>
测试
/** * 方法二 */ @Test public void testFindAllStudentMessages2(){ SqlSession session = MybatisUtils.getSqlSession(); StudentMapper mapper = session.getMapper(StudentMapper.class); List<Student> students = mapper.findAllStudentMessages2(); for (Student student : students) { System.out.println(student); } }
日志输出
可以看出,系统直接执行 select t.id tid,t.name tname,s.id,s.name,s.teacher from teacher t,student s where s.teacher = t.id;
Created connection 1304589447. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@4dc27487] ==> Preparing: select t.id tid,t.name tname,s.id,s.name,s.teacher from teacher t,student s where s.teacher = t.id; ==> Parameters: <== Columns: tid, tname, id, name, teacher <== Row: 5992b89d9cfd4f0ba79a2991e108d0b7, 郑老师, 5992b89d9cfd4f0ba79a2991e108d017, ZWZ5, 5992b89d9cfd4f0ba79a2991e108d0b7 <== Row: 5992b89d9cfd4f0ba79a2991e108d0b7, 郑老师, 5992b89d9cfd4f0ba79a2991e108d1b7, ZWZ1, 5992b89d9cfd4f0ba79a2991e108d0b7 <== Total: 2 Student(id=5992b89d9cfd4f0ba79a2991e108d017, name=ZWZ5, teacher=Teacher(id=5992b89d9cfd4f0ba79a2991e108d0b7, name=郑老师)) Student(id=5992b89d9cfd4f0ba79a2991e108d1b7, name=ZWZ1, teacher=Teacher(id=5992b89d9cfd4f0ba79a2991e108d0b7, name=郑老师)) Process finished with exit code 0
六、一对多
需求
- 对于学生而言,都有一位老师
- 对于老师而言,有多名学生
- 在老师角度看,老师和学生就是一对多的关系
- 要求输出老师的所有信息,包括他的所有学生
实体类
学生
@Data @AllArgsConstructor @NoArgsConstructor public class Student { private String id; private String name; // 对应老师的ID即可 private String teacher; }
老师
@Data @AllArgsConstructor @NoArgsConstructor public class Teacher { private String id; private String name; // 老师拥有的学生列表 private List<Student> students; }
具体实现
mapper接口
public interface TeacherMapper { List<Teacher> findAllTeacherMessage(); }
XML具体实现
collection 是一个一个复杂类型的集合
<?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="zwz.mapper.TeacherMapper"> <select id="findAllTeacherMessage" resultMap="teacherAndStudent"> select t.id,t.name,s.id sid,s.name sname,s.teacher sTeacher from teacher t,student s where t.id = s.teacher; </select> <resultMap id="teacherAndStudent" type="teacher"> <result property="id" column="id"/> <result property="name" column="name"/> <collection property="students" ofType="student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <result property="teacher" column="sTeacher"/> </collection> </resultMap> </mapper>
测试
@Test public void testFindAllTeacherMessage(){ SqlSession session = MybatisUtils.getSqlSession(); TeacherMapper mapper = session.getMapper(TeacherMapper.class); List<Teacher> teachers = mapper.findAllTeacherMessage(); for (Teacher teacher : teachers) { System.out.println(teacher); } }
日志输出
可以看出系统直接执行 select t.id,t.name,s.id sid,s.name sname,s.teacher sTeacher from teacher t,student s where t.id = s.teacher; 查询到了结果
Created connection 2142565033. Setting autocommit to false on JDBC Connection [com.mysql.jdbc.JDBC4Connection@7fb4f2a9] ==> Preparing: select t.id,t.name,s.id sid,s.name sname,s.teacher sTeacher from teacher t,student s where t.id = s.teacher; ==> Parameters: <== Columns: id, name, sid, sname, sTeacher <== Row: 5992b89d9cfd4f0ba79a2991e108d0b7, 郑老师, 5992b89d9cfd4f0ba79a2991e108d017, ZWZ5, 5992b89d9cfd4f0ba79a2991e108d0b7 <== Row: 5992b89d9cfd4f0ba79a2991e108d0b7, 郑老师, 5992b89d9cfd4f0ba79a2991e108d1b7, ZWZ1, 5992b89d9cfd4f0ba79a2991e108d0b7 <== Total: 2 Teacher(id=5992b89d9cfd4f0ba79a2991e108d0b7, name=郑老师, students=[Student(id=5992b89d9cfd4f0ba79a2991e108d017, name=ZWZ5, teacher=5992b89d9cfd4f0ba79a2991e108d0b7), Student(id=5992b89d9cfd4f0ba79a2991e108d1b7, name=ZWZ1, teacher=5992b89d9cfd4f0ba79a2991e108d0b7)]) Process finished with exit code 0