多个学生对应一个老师
对于学生这边而言,关联..多个学生,关联一个老师【多对一】
对于老师而言,集合,一个老师有很多个学生【一对多】
注意:一对多相当与“对象”用(assocation)去处理
多对一相当于”集合“用(collection)去处理
一,环境搭建
SQL
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');
<!--到resources包和java包有重名包时默认合成一个包,特别是引全路径是注意-->
pojo
student
package com.king.pojo; import lombok.Data; @Data public class Student { private int id; private String name; //学生需要关联一个老师 private Teacher teacher; }
teacher
package com.king.pojo; import lombok.Data; @Data public class Teacher { private int id; private String name; }
mappper测试
package com.king.dao; import com.king.pojo.Teacher; import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Select; public interface TeacherMapper { @Select("select * from teacher where id = #{tid}") public Teacher getTeacher(@Param("tid") int id); }
<mappers> <mapper resource="com/king/dao/TeacherMapper.xml"/> </mappers>
public class MyTest { @Test public void teacherTest(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class); Teacher teacher = mapper.getTeacher(1); System.out.println(teacher); sqlSession.close(); } }
二,多对一查询方式:
子查询
联表查询
练习,题目《查询所有学生信息以及对应老师的信息》
方式一,按照查询嵌套处理(子查询)
<mapper namespace="com.king.dao.StudentMapper"> <!-- 思路:1.查询所有的学生信息 2.根据查询出来的学生tid,寻找对应的老师 --> <select id="getStudent" resultMap="StudentTeacher"> select * from student </select> <resultMap id="StudentTeacher" type="Student"> <result property="id" column="id"/> <result property="name" column="name"/> <!--复杂语句--> <association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/> </resultMap> <select id="getTeacher" resultType="Teacher"> select * from teacher where id = #{id} </select> </mapper>
拓展:为什么联表查询的过程是没有顺序的(不是先执行完表一再表二)?
答:数据库是并发执行的
方式二,按照结果进行嵌套处理(联表查询)
<!--按照结果嵌套处理--> <select id="getStudent2" resultMap="StudentTeacher2"> select s.id sid, s.`name` sname,t.`name` tname from student s ,teacher t where s.tid=t.id </select> <resultMap id="StudentTeacher2" type="Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <association property="teacher" javaType="Teacher"> <result property="name" column="tname"/> </association> </resultMap>
三,一对多查询
3.1环境搭建
实体类
package com.king.pojo; import lombok.Data; import java.util.List; @Data //一对多 public class Teacher { private int id; private String name; //一个老师有很多学生 private List<Student> students; }
package com.king.pojo; import lombok.Data; @Data public class Student { private int id; private String name; private int tid; }
3.2 mappper.xml实现
方式一:根据结果查询(调试代码,改sql就可,推荐这种)
<!--按结果嵌套查询--> <select id="getTeacher" resultMap="TeacherStudent"> select s.id sid,s.name sname,t.id tid,t.name tname from student s,teacher t where s.tid=t.id and t.id=#{tid} </select> <resultMap id="TeacherStudent" type="Teacher"> <result property="id" column="tid"/> <result property="name" column="tname"/> <!--复杂的属性,我们需要单独处理, 多对一(对象,association),javaType 指定属性的类型 一对多(集合,collection),ofType 获取泛型信息 --> <collection property="students" ofType="Student"> <result property="id" column="sid"/> <result property="name" column="sname"/> <result property="tid" column="tid"/> </collection> </resultMap>
测试
@Test
public void teachersTest() {
SqlSession sqlSession = MybatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher);
sqlSession.close();
}
方式二:select子嵌套
<select id="getTeacher2" resultMap="TeacherStudent2"> select * from teacher where id = #{tid} </select> <resultMap id="TeacherStudent2" type="teacher"> <collection property="students" javaType="ArrayList" ofType="student" select="getStudentByTeacherId" column="id"/> </resultMap> <select id="getStudentByTeacherId" resultType="student"> select * from student where tid=#{tid} </select>
总结:
1.关联----association【多对一】
2.集合----collection 【一对多】
3.javaType & ofType
3.1 javaType 用来指定实体类中属性的类型
3.2 ofType 用来指定映射到List或者集合中的pojo类型,(泛型中约束的类型)