6Mybatis一对多喝多对一处理
一对多和多对一处理
1多对一处理
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`) 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
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private int id;
private String name;
//学生需要关联一个老师
private Teacher teacher;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
private int id;
private String name;
}
public interface StudentMapper {
//查询所有的学生信息,以及对应的老师信息
List<Student> getStudent();
List<Student> getStudent2();
}
public interface TeacherMapper {
Teacher getTeacher(int id);
}
1.2回顾Mysql多对一查询方式
- 子查询
- 联表查询
1.3方式一:按嵌套处理
- 查询所有学生信息
- 根据查询出来的学生tid寻找对应的老师
- 这样学生的结果集中应该包含老师,该如何处理呢?
- 做一个结果集映射:StudentTeacher
- StudentTeacher结果集的类型为 Student
- 学生中老师的属性为teacher,对应数据库中为tid
- association – 一个复杂类型的关联;使用它来处理关联查询
<!-- StudentMapper.xml中 -->
<select id="getStudent" resultMap="StudentTeacher">
select * from student;
</select>
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"></result>
<result property="name" column="name"></result>
<!--复杂的属性我们需要单独处理 对象:association 集合:collection-->
<!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"></association>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id=#{tid}
</select>
@Test
public void test2(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getStudent();
for (Student student:studentList){
System.out.println(student);
}
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=秦老师))
1.4方式二:按照结果嵌套处理(个人更喜欢)
<!-- StudentMapper.xml中 -->
<select id="getStudent2" resultMap="StudentTeacher2">
select s.id sid, s.name sname,t.id tid,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="id" column="tid"/>
<result property="name" column="tname"/>
</association>
</resultMap>
@Test
public void test3(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> studentList = mapper.getStudent2();
for (Student student:studentList){
System.out.println(student);
}
sqlSession.close();
}
//结果和上面一样
2一对多处理
2.1理解
- 一个老师拥有多个学生
- 如果对于老师这边,就是一个一对多的现象,即从一个老师下面拥有一群学生(集合)!
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Student {
private int id;
private String name;
private int tid;
}
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Teacher {
private int id;
private String name;
//一个老师拥有多个学生
private List<Student> students;
}
public interface TeacherMapper {
//获取老师
List<Teacher> getTeacher();
//获取指定老师下的所有学生及老师的信息
Teacher getTeacher(int id);
}
2.2按结果嵌套查询
<!-- TeacherMapper.xml中 -->
<select id="getTeacher" resultMap="TeacherStudent">
select s.id sid, s.name sname, t.name tname, t.id tid
from student s,teacher t
where s.tid=t.id and t.id=#{id}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!-- 复杂的属性 我们需要单独处理 对象association 集合collection
javatype 指定属性的类型
集合中的泛型信息 我们使用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 test(){
SqlSession sqlSession = MyBatisUtils.getSqlSession();
TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
Teacher teacher = mapper.getTeacher(1);
System.out.println(teacher);
sqlSession.close();
}
//结果
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)])
3小结
- 关联:association(多对一)
- 集合:collection(一对多)
- javaType:用来指定实体类中属性的类型
- ofType:用来指定映射到List或集合中的pojo类型,即泛型中的约束类型
4注意点
- 保证SQL的可读性,尽量通俗易懂
- 根据实际要求,尽量编写性能更高的SQL语句
- 注意属性名和字段不一致的问题
- 注意一对多和多对一 中:字段和属性对应的问题
- 尽量使用Log4j,通过日志来查看自己的错误

浙公网安备 33010602011771号