MyBatis对象关联关系----多对多的保存与查询
模拟情景:
对象:学生,课程
关系:一个学生可选多个课程,一门课程可被多个学生选择
一、保存
1.创建数据库表,student,course,student_course,其中student_course用来关联学生表与课程表注意在设计表的字段时,字段名不要相同,尤其是主键的字段名不要相同,不然在查询的时候使用collection集合只出现一条结果。student_course表中的s_id,c_id作为外键关联到student,course表的主键
DROP TABLE IF EXISTS `course`; CREATE TABLE `course` ( `cid` int(8) NOT NULL AUTO_INCREMENT, `cnumber` varchar(20) COLLATE utf8_bin DEFAULT NULL, `cname` varchar(20) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`cid`) ) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `sid` int(8) NOT NULL AUTO_INCREMENT, `name` varchar(20) COLLATE utf8_bin DEFAULT NULL, PRIMARY KEY (`sid`) ) ENGINE=InnoDB AUTO_INCREMENT=4 DEFAULT CHARSET=utf8 COLLATE=utf8_bin; DROP TABLE IF EXISTS `student_course`; CREATE TABLE `student_course` ( `sc_id` int(8) NOT NULL AUTO_INCREMENT, `s_id` int(8) NOT NULL, `c_id` int(8) NOT NULL, PRIMARY KEY (`sc_id`), KEY `10001` (`s_id`), KEY `10002` (`c_id`), CONSTRAINT `10002` FOREIGN KEY (`c_id`) REFERENCES `course` (`cid`) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT `10001` FOREIGN KEY (`s_id`) REFERENCES `student` (`sid`) ON DELETE CASCADE ON UPDATE CASCADE ) ENGINE=InnoDB AUTO_INCREMENT=15 DEFAULT CHARSET=utf8 COLLATE=utf8_bin;
2.创建实体对象
public class Student { private int id; private String name; private List<Course> course ;//所选课程 //...省略get、set方法 } public class Course { private int cid; private String cnumber; private String cname; private List<Student> student ;//选择该课程的学生 //...省略get、set方法 }
3.编写接口方法
public interface IStudentDao { public Student getById(int id); public void saveSelectCourse(@Param("student") Student s,@Param("course") Course c); public Student getStudentCourse(int id); }
4.编写sql映射文件student.xml
<mapper namespace="com.mybaits.dao.IStudentDao"> <select id="getById" parameterType="int" resultType="Student">
select * from student where id=#{id}
</select> <insert id="saveSelectCourse" > insert into student_course(sid,cid) values(#{student.id} ,#{course.id}) </insert> </mapper>
5.在主配置文件中添加mapper,编写测试类
public class StudentTest { private SqlSessionTemplate sqlSessionTemplate; @Before public void init(){ ApplicationContext ctx=new ClassPathXmlApplicationContext("spring.xml"); sqlSessionTemplate=(SqlSessionTemplate) ctx.getBean("sqlSessionTemplate"); } @Test public void test(){ IStudentDao student=sqlSessionTemplate.getMapper(IStudentDao.class); Student s=student.getById(1); ICourseDao course=sqlSessionTemplate.getMapper(ICourseDao.class); Course c=course.getById(1); student.saveSelectCourse(s, c); System.out.println("save succeed!"); } }
。。。。。。。。。。。。。运行结束。。。。。。。。。。。
二、查询
1.根据学生id查询学生信息,以及其选课信息,(通过id查询课程信息以及选择该课程的学生信息,两者的方法基本相同)接口方法已在上文保存中给出public Student getStudentCourse(int id);
2.sql映射文件语句
<resultMap type="com.mybaits.bean.Course" id="courseResult"> <id property="cid" column="cid"/> <result property="cnumber" column="cnumber"/> <result property="cname" column="cname"/> </resultMap> <resultMap type="com.mybaits.bean.Student" id="studentResult" > <id property="id" column="sid"/> <result property="name" column="name"/>
//使用collection元素来映射course集合,在collection中再嵌套resultMap,将集合中的元素映射成course对象 <collection property="course" ofType="com.mybaits.bean.Course" resultMap="courseResult"> </collection> </resultMap> <select id="getStudentCourse" parameterType="int" resultMap="studentResult"> select s.*,c.* from student s left join student_course sc on s.sid=sc.s_id left join course c on c.cid=sc.c_id where s.sid=#{id} </select>
3.编写测试类
@Test public void test2(){ IStudentDao student=sqlSessionTemplate.getMapper(IStudentDao.class); Student s=student.getStudentCourse(1); System.out.println("学生姓名:"+s.getName()+"\n选择课程:"); for(Course c:s.getCourse()){ System.out.println("课程编号:"+c.getCnumber()+"\t课程名称:"+c.getCname()); } }
运行结果:
学生姓名:mike
选择课程:
课程编号:s001 课程名称:JAVA
课程编号:s002 课程名称:C Language