Mybatis实现复杂查询
1.多对一处理
- 多个学生对应一个老师
- 从学生角度为多对一
数据库设计
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');
搭建测试环境
- 引入Lombok依赖
< dependency> < groupId>org.projectlombok< /groupId> < artifactId>lombok< /artifactId> < version>1.18.22< /version> < scope>compile< /scope> < /dependency>
- 在实体类中添加注解
- Student表实体类
/** * Student表实体类 * @author 刘淳 */ @Data @NoArgsConstructor @AllArgsConstructor public class Student { private int id; private String name; private Teacher teacher; }
- Teacher表实体类
/** * Teacher表实体类 * @author 刘淳 */ @Data @NoArgsConstructor @AllArgsConstructor public class Teacher { private int id; private String name; }
- 编写对应Mapper接口
- Student类Mapper接口
/** * Student类Mapper接口 * @author 刘淳 */ public interface StudentMapper { }
- Teacher类Mapper接口
/** * Teacher类Mapper接口 * @author 刘淳 */ public interface TeacherMapper { }
- 编写Mapper接口对应的Mapper.xml文件
- StudentMapper.xml
< ?xml version="1.0" encoding="UTF-8" ?> < !DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> < mapper namespace="ltd.lccyj.mapper.StudentMapper"> < /mapper>
- TeacherMapper.xml
< ?xml version="1.0" encoding="UTF-8" ?> < !DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> < mapper namespace="ltd.lccyj.mapper.TeacherMapper"> < /mapper>
需求:获取所有学生以及对应老师的信息
1.按结果嵌套处理
对应SQL处理方式: 联表查询
SELECT s.id sid, s.name sname,t.name tname FROM student s, teacher t WHERE s.tid = t.id
- Mapper接口方法
List< Student> getStudent();
- Mapper.xml
< resultMap id="Student" type="Student"> < id property="id" column="sid"/> < result property="name" column="sname"/> < association property="teacher" javaType="Teacher"> < id property="id" column="tid"/> < result property="name" column="tname"/> < /association> < /resultMap> < select id="getStudent" resultMap="Student"> select s.id sid,s.name sname,s.tid ,t.name tname from student s,teacher t where s.tid=t.id < /select>
- 测试方法
@Test public void getStudent(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List< Student> studentList = mapper.getStudent(); for (Student student : studentList) { System.out.println(student); } }
2.按查询嵌套处理
对应SQL处理方式:嵌套查询
- Mapper接口方法
List< Student> getStudent();
- Mapper.xml
< resultMap id="Student" type="Student"> < association property="teacher" column="tid" javaType="Teacher" select="getTeacherById"/> < /resultMap> < select id="getStudent" resultMap="Student"> select * from student < /select> < select id="getTeacherById" resultType="Teacher"> select * from teacher where id=#{id} < /select>
- 测试方法
@Test public void getStudent(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List< Student> studentList = mapper.getStudent(); for (Student student : studentList) { System.out.println(student); } }
2. 一对多处理
- 一个老师对应多个学生
- 从老师角度为一对多关系
搭建测试环境
- 除实体类外都与原先一致
- Student实体类
/** * Student表实体类 * @author 刘淳 */ @Data @NoArgsConstructor @AllArgsConstructor public class Student { private int id; private String name; private int tid; }
- Teacher实体类
/** * Teacher表实体类 * @author 刘淳 */ @Data @NoArgsConstructor @AllArgsConstructor public class Teacher { private int id; private String name; private List< Student> studentList; }
需求:获取指定的老师和老师下的所有学生
1.按结果嵌套处理
对应SQL处理方式: 联表查询
select t.id,t.name tname,s.id sid,s.name sname from student s,teacher t where s.tid=t.id
- Mapper接口方法
Teacher getTeacherById(int id);
- Mapper.xml
< resultMap id="Teacher" type="Teacher"> < id property="id" column="id"/> < result property="name" column="tname"/> < collection property="studentList" ofType="Student"> < id property="id" column="sid"/> < result property="name" column="sname"/> < result property="tid" column="id"/> < /collection> < /resultMap> < select id="getTeacherById" resultMap="Teacher"> select t.id ,t.name tname,s.id sid,s.name sname from student s,teacher t where s.tid=t.id and t.id=#{id} < /select>
- 测试方法
@Test public void getStudent(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); StudentMapper mapper = sqlSession.getMapper(StudentMapper.class); List< Student> studentList = mapper.getStudent(); for (Student student : studentList) { System.out.println(student); } }
2.按查询嵌套处理
对应SQL处理方式:嵌套查询
Mapper接口方法
Teacher getTeacherById(int id);
- Mapper.xml
< resultMap id="Teacher" type="Teacher"> < collection property="studentList" column="id" javaType="ArrayList" ofType="Student" select="getStudentByTid"/> < /resultMap> < select id="getTeacherById" resultMap="Teacher"> select * from teacher where id=#{id} < /select> < select id="getStudentByTid" resultType="Student"> select * from student where tid=#{id} < /select>
- 测试方法
@Test public void getTeacherById(){ SqlSession sqlSession = MybatisUtils.getSqlSession(); TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class); Teacher teacher = mapper.getTeacherById(1); System.out.println(teacher); }
3. 小结
association–关联: 用于一对一与多对一
**collection–集合:**用于一对多
**JavaType:**用于指定pojo中属性的类型
**ofType:**用于指定映射到list集合属性中pojo的类型