多对多查询
1.数据库层面
在一对多的关联关系中,我们需要在数据库中新建立一个中间表,然后将两个表的主键作为外键放在该表中,例如,学生表和课程表就是多对多的情况,所以我们需要建立一个中间表:选课表;在无论是一对多,还是多对一,外键的属性总是放在多方的表中,在多对多关系中,外键是存放在中间表中,所以中间表对于另外两个表都是多对一;
2.实体类层面
对于实体类而言,中间表是体现在两个实体类中各自都将另外一个实体类的集合作为属性;需要注意的是,toString()方法的中的属性其实是通过调用getXxx()得到的,所以如果两个类将对方的集合属性添加到toString()方法中,就会互相调用,导致集合深度异常;所以我们让Student的toString()添加Course的集合属性,而Course的toString()中不添加Student的集合属性;
<!--Student.class-->
public class Student {
private Integer sid;
private String sname;
private Set<Course> courses;
//此处省略setter、getter方法
@Override
public String toString() {
return "Student [sid=" + sid + ", sname=" + sname + ", courses=" + courses + "]";
}
}
<!--Course.class-->
public class Course {
private Integer cid;
private String cname;
private Set<Student> students;
@Override
public String toString() {
return "Course [cid=" + cid + ", cname=" + cname + "]";
}
}
<!--多表连接查询-->
<resultMap type="Student" id="studentMapper">
<id column="sid" property="sid"/>
<result column="sname" property="sname"/>
<collection property="courses" ofType="Course">
<id column="cid" property="cid"/>
<result column="cname" property="cname"/>
</collection>
</resultMap>
<select id="selectStudentById" resultMap="studentMapper">
select sid,sname,cid,cname
from student,course,middle
where sid = studentId and cid = courseId and sid = #{id}
</select>