11.一对多处理查询—集合—使用list集合—collection映射
1.Student.java和Teacher.java
import lombok.Data;
import java.util.List;
@Data
public class Teacher {
private int id;
private String name;
//老师这里是集合,所以在后面映射需要用collection
private List<Student> students;
}
import lombok.Data;
@Data
public class Student {
private int id;
private String name;
private int tid;
}
2.StudentMapper.java和TeacherMapper.java
public interface StudentMapper {
}
import com.kuang.pojo.Teacher;
import org.apache.ibatis.annotations.Param;
import java.util.List;
public interface TeacherMapper {
//获取所有老师,这里可以注解开发,也可以xml配置文件
public List<Teacher> getTeacher();
//获取给定老师id,获取老师下的所有学生信息以及老师信息,一对多
Teacher getTeachers(@Param("tid") int id);
//方式二,
Teacher getTeachers2(@Param("tid") int id);
}
3.MybatisUtils.java和mybatis-config.xml,db.properties同上
4.重点,一对多查询的实现
TeacherMapper.xml
<mapper namespace="com.kuang.dao.TeacherMapper">
<!--方式一,根据结果集查询,因为前面类中定义的是集合,所以,这里映射要用collection-->
<select id="getTeachers" resultMap="TeacherStudent">
select t.id tid,t.name tname,s.id sid,s.name sname from teacher t,student s
where t.id=s.tid and t.id=#{tid}
</select>
<!--复杂的属性,我们需要单独处理,
对象:association,
集合:collection
javaType是属性的类型,
集合中的泛型,我们用ofType来解决
-->
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"></result>
<result property="name" column="tname"></result>
<collection property="students" ofType="Student">
<result property="id" column="sid"></result>
<result property="name" column="sname"></result>
</collection>
</resultMap>
<!--方式二,子查询-->
<select id="getTeachers2" resultMap="TeacherStudent2">
select * from teacher where id=#{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<result property="id" column="id"></result>
<result property="name" column="name"></result>
<collection property="students" column="id" javaType="ArrayList"
ofType="Student" select="getStudentByTeacherID">
</collection>
</resultMap>
<select id="getStudentByTeacherID" resultType="Student">
select * from student where tid=#{tid}
</select>
</mapper>
总结:一对多,多对一查询,对比分析
1.在多对一中,类的定义是一个对象。多个学生对应一个老师
public class Student {
private int id;
private String name;
//使用组合,每一个学生关联一个老师
//这里是对象
private Teacher teacher;
}
//方式二,根据结果集查询
public List<Student> getStudent2();
所以在映射时,需要用到association,property是实体类的属性,column是数据库表的属性值。
javaType是实体类Teacher的别名,表示返回结果是Teacher对象。里面的name是Teacher实体类的属性,column是查出来的teacher表的name别名tname.
<!--********************方式二。根据结果集查询-->
<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>
<result property="name" column="sname"></result>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"></result>
</association>
</resultMap>
2.在一对多中,表示的是一个老师可以带多个学生。类的定义是List集合,范型是Student
@Data
public class Teacher {
private int id;
private String name;
//老师这里是集合,所以在后面映射需要用collection
private List<Student> students;
}
//接口
//获取给定老师id,获取老师下的所有学生信息以及老师信息,一对多
Teacher getTeachers(@Param("tid") int id);
所以,在这里对于集合,我们要用collection,这里需要注意的是collection中的property的值是实体类中的==students,==
(private List students;)
ofType是是泛型中的对象,Student。
result结果集就是一一对应了,Student中的id对于查出来的sid,name对于查出来的sname。
<!--方式二,根据结果集查询,因为前面类中定义的是集合,所以,这里映射要用collection-->
<select id="getTeachers" resultMap="TeacherStudent">
select t.id tid,t.name tname,s.id sid,s.name sname from teacher t,student s where t.id=s.tid and t.id=#{tid}
</select>
<!--复杂的属性,我们需要单独处理,
对象:association,
集合:collection
javaType是属性的类型,
集合中的泛型,我们用ofType来解决
-->
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"></result>
<result property="name" column="tname"></result>
<collection property="students" ofType="Student">
<result property="id" column="sid"></result>
<result property="name" column="sname"></result>
</collection>
</resultMap>
3.子查询比较
上面是对比,一对多,和多对一,根据子查询的方法,下面我们将对比,他们两个的子查询的方法(较难理解)
<!--*************************************一对多,一老师对于多个学生,方式一。子查询-->
<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 property="teacher" column="tid" javaType="Teacher" select="getTeacher">
</association>
</resultMap>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id=#{id}
</select>
<!--多对一,根据老师的id,查出老师的信息以及它对应的学生信息,方式一,子查询-->
<select id="getTeachers2" resultMap="TeacherStudent2">
select * from teacher where id=#{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<result property="id" column="id"></result>
<result property="name" column="name"></result>
<collection property="students" column="id" javaType="ArrayList"
ofType="Student" select="getStudentByTeacherID">
</collection>
</resultMap>
<select id="getStudentByTeacherID" resultType="Student">
select * from student where tid=#{tid}
</select>
根据对比,可以看出,其查询方式都相似,具体不同在于,
-
第一点
一对多中,定义的是类,所以用association来映射,
多对一,定义的是List集合,所以collection。
-
第二点
一对多中,association的property是对应的实体类的teacher。javaType是对应的Teacher对象(如下)
//使用组合,每一个学生关联一个老师 //这里是对象 private Teacher teacher;
多对一,collection的property也是对应的实体类的students。javaType参数是ArrayList也是对应的List集合(如下),
在集合中,会多一个ofType这里是范型的参数,和范型约束类型保存一致。
//老师这里是集合,所以在后面映射需要用collection private List<Student> students;