Version: Next
1. 多对一
- 多个学生对应一个老师
- 对于学生而言,关联多个学生,关联一个老师
- 对于老师而言,集合,一个老师又很多学生
之前使用resultMap
中的子标签result
将数据库字段映射为实体类属性
现在我们将使用resultMap
的其他字段来描述更复杂的查询情况
查看官方文档对ResultMap
子标签的描述:
结果映射ResultMap:
- association——一个复杂类型的关联,许多结果将包装成这种类型
- 嵌套结果映射——关联本身可以是一个
resultMap
元素,或者从别处引用一个
- 嵌套结果映射——关联本身可以是一个
- collection——一个复杂类型的集合
- 嵌套结果映射——集合本身可以是一个
resultMap
元素,或者从别处引用一个
- 嵌套结果映射——集合本身可以是一个
1.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) VALUE (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);
1.2 新建项目
新建模块mybatis06
,删除所有Mapper,Pojo, 删除mybatis-config.xml
中的mappers
标签
1.2.1 建POJO
Teacher
@Data@AllArgsConstructor@NoArgsConstructorpublic class Teacher {private int id;private String name;}Student
@Data@NoArgsConstructor@AllArgsConstructorpublic class Student {private int id;private String name;private Teacher teacher;}
1.2.2 建Mapper
TeacherMapper
public interface TeacherMapper {}StudentMapper
public interface StudentMapper {}
1.2.3 建mapper.xml
建立在resources
目录下,与src
中的Mapper接口同包 (确保包是多级路径,而不是一个单级路径名字带几个.)
内容复制mybatis-config.xml
,修改三个位置
把configuration
和config
都改为mapper
即可
TeacherMapper.xml
<mapper namespace="com.bsx.dao.TeacherMapper"></mapper>StudentMapper.xml
<mapper namespace="com.bsx.dao.StudentMapper"></mapper>
1.2.4 注册Mapper
在mybatis-config.xml
中注册mapper
<mappers>
<mapper resource="com/bsx/dao/TeacherMapper.xml"/>
<mapper resource="com/bsx/dao/StudentMapper.xml"/>
</mappers>
1.2.5 测试环境搭建
接口
public interface TeacherMapper {Teacher getTeacher(@Param("tid") int id);}mapper.xml
<mapper namespace="com.bsx.dao.TeacherMapper"><select id="getTeacher" resultType="com.bsx.pojo.Teacher" >select * from teacher where id = #{tid}</select></mapper>测试类
@Testpublic void testEnv() throws IOException {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();try {TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);Teacher teacher = mapper.getTeacher(1);System.out.println(teacher);} catch (Exception e) {e.printStackTrace();} finally {sqlSession.close();}}
2. 多对一需求
需求,查询所有的学生信息以及对应的老师的信息
sql (sid, sname, tname, tid为别名)
SELECTs.id sid, s.name sname, t.name tname, t.id tidFROMstudent s, teacher tWHEREs.tid = t.id;
Student类中有一个成员变量Teacher teacher,所以上述sql不能直接用Mybatis查询
2.1 思路一——按照查询嵌套处理
子查询
- 查询所有的学生信息
- 根据查询出来的学生的tid,寻找对应的老师
StudentMapper接口
//查询所有的学生信息以及对应的老师的信息List<Student> getStudent();StudentMapper.xml
主键一般用
id
标签,通用情况下用result
标签复杂的属性需要单独处理
- association——针对对象
- 用
javatype
指定映射对象的类型 - 用
select
指定嵌套查询
- 用
- association——针对对象
- collection——针对集合(一对多,之后再说)
- 测试
@Test
public void testGetStudent() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.getStudent();
for (Student student : students) {
System.out.println(student);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
结果
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.2 思路二——按照结果嵌套处理(常用)
- 查询所有的学生信息
- 根据查询出来的学生的tid,寻找对应的老师
接口
//方式二,按照结果嵌套List<Student> getStudent2();StudentMapper.xml
<!-- 方式二 按照结果嵌套处理--><select id="getStudent2" resultMap="StudentTeacher2">SELECTs.id sid, s.name sname, t.name tname, t.id tidFROMstudent s, teacher tWHEREs.tid = t.id;</select><resultMap id="StudentTeacher2" type="com.bsx.pojo.Student"><result column="sid" property="id"/><result column="sname" property="name"/><association property="teacher" javaType="Teacher"><result column="tname" property="name"/><result column="tid" property="id"/></association></resultMap>测试
@Testpublic void testGetStudent2() throws IOException {InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);SqlSession sqlSession = sqlSessionFactory.openSession();try {StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);List<Student> students = mapper.getStudent2();for (Student student : students) {System.out.println(student);}} catch (Exception e) {e.printStackTrace();} finally {sqlSession.close();}}结果
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=秦老师))