前几天有网友问到MyBatis多对多的问题,不过愧对网友厚爱的是,最近一直忙,直到现在才有时间处理此事。今天就先写一个多对多保存的示例,算是对这位网友的初步回应,以后会有更多相关的博文发表。

为演示多对多,我们可以模拟学生选课的情形。一个学生可以选修多门课程,一门课程可以被多个学生选修。显然,这是一种多对多的关系。先创建课程表如下(本文示例完整源码下载:http://down.51cto.com/data/907686):

SET FOREIGN_KEY_CHECKS=0;
DROP TABLE IF EXISTS `course`;
CREATE TABLE `course` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`course_code` varchar(20) NOT NULL COMMENT '课程编号',
`course_name` varchar(50) NOT NULL COMMENT '课程名称',
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8;
-- ----------------------------
-- Records of course
-- ----------------------------
INSERT INTO `course` VALUES ('1', 'zj01', '数据结构');

接着创建学生选修表,用来保存学生的选课信息,如下:

SET FOREIGN_KEY_CHECKS=0;
-- ----------------------------
-- Table structure for `student_course`
-- ----------------------------
DROP TABLE IF EXISTS `student_course`;
CREATE TABLE `student_course` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`student_id` int(11) NOT NULL COMMENT '选课学生id',
`course_id` int(11) NOT NULL COMMENT '所选课程的id',
PRIMARY KEY (`id`),
KEY `student_id` (`student_id`),
KEY `course_id` (`course_id`),
CONSTRAINT `student_course_ibfk_1` FOREIGN KEY (`student_id`) REFERENCES `student` (`id`),
CONSTRAINT `student_course_ibfk_2` FOREIGN KEY (`course_id`) REFERENCES `course` (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

由以上可看出,表中的student_id字段和course_id字段分别作为外键关联到了sutdent表和course表的主键。

创建对应的课程实体类。

package com.abc.domain;
import java.util.List;
public class Course{
private int id;
private String courseCode;  //课程编号
private String courseName;//课程名称
private List<Student> students;//选课学生
public int getId()
{
return this.id;
}
public void setId(int id)
{
this.id = id;
}
public String getCourseCode()
{
return this.courseCode;
}
public void setCourseCode(String courseCode)
{
this.courseCode = courseCode;
}
public String getCourseName()
{
return this.courseName;
}
public void setCourseName(String courseName)
{
this.courseName = courseName;
}
}

为学生实体类添加所选课程属性如下:

private List<Course> courses;//所选的课程
//getter和setter
public List<Course> getCourses()
{
return this.courses;
}
public void setCourses(List courses)
{
this.courses = courses;
}

接下来为Course实体编写映射器接口和文件、DAO类,这与以前一样。详见以下代码,不再赘述。

CourseMapper.java

package com.abc.mapper;
import com.abc.domain.Course;
public interface CourseMapper {
public Course getById(int id);
}

CourseMapper.xml

<?xml version="1.0" encoding="utf8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.abc.mapper.CourseMapper">
<!--根据id查询课程-->
<select id="getById" parameterType="int"
resultMap="courseResultMap">
select id,course_code,course_name
from course where id=#{id}
</select>
<!--课程实体映射-->
<resultMap id="courseResultMap" type="Course">
<id property="id" column="id"/>
<result property="courseCode" column="course_code"/>
<result property="courseName" column="course_name"/>
</resultMap>
</mapper>

CourseDao.java

package com.abc.dao;
import com.abc.mapper.CourseMapper;
import com.abc.domain.Course;
public class CourseDao {
private CourseMapper courseMapper;
//studentMapper的setter和getter方法
public void setCourseMapper(CourseMapper courseMapper)
{
this.courseMapper = courseMapper;
}
public CourseMapper getCourseMapper()
{
return this.courseMapper;
}
public Course getById(int id)
{
return this.courseMapper.getById(id);
}
}

CourseMapperCourseDaospring中的配置如下:

<bean id="courseMapper" parent="parentMapper">
<property name="mapperInterface" value="com.abc.mapper.CourseMapper" />
</bean>
<!--为courseDao注入courseMapper-->
<bean id="courseDao" class="com.abc.dao.CourseDao">
<property name="courseMapper" ref="courseMapper" />
</bean>

要保存学生选课信息,先在StudentMapper接口中添加一个方法,如下:

public void saveElecCourse(Student student, Course course);

映射文件StudentMapper.xml中添加相应的insert语句如下:

<!--这里param1,param2用到了MyBatis多参数传递的默认命名方式,
详见作者博客:http://legend2011.blog.51cto.com/3018495/1024869-->
<insert id="saveElecCourse"
useGeneratedKeys="true" keyColumn="GENERATED_KEY">
insert into student_course(student_id,course_id)
values(#{param1.id},#{param2.id})
</insert>

在StudentDao类中添加相关方法如下:

//保存学生选课信息
public void saveElecCourse(Student student, Course course)
{
this.studentMapper.saveElecCourse(student, course);
}

接下来是运行类(ManyToManyDemo.java)。在这个类中,我们让id8的学生(刘晓)选修id1的课程(数据结构)。代码如下:

package com.demo;
import org.springframework.context.ApplicationContext;
import com.abc.domain.Student;
import com.abc.domain.Teacher;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.abc.dao.StudentDao;
import com.abc.dao.CourseDao;
import com.abc.domain.Course;
public class ManyToManyDemo
{
private static ApplicationContext ctx;
static
{
//在类路径下寻找resources/beans.xml文件
ctx = new ClassPathXmlApplicationContext("resources/beans.xml");
}
public static void main(String[] args)
{
//从Spring容器中请求Dao对象
StudentDao studentDao =
(StudentDao)ctx.getBean("studentDao");
CourseDao courseDao =
(CourseDao)ctx.getBean("courseDao");
Student student = studentDao.getById(8);
Course course = courseDao.getById(1);
studentDao.saveElecCourse(student, course);
}
}

运行结束后,选修表中已插入了这名学生的选课信息,如下图所示。

222243875.png

       猛戳这里全面系统地学习MyBatis 3

       MyBatis技术交流群:188972810,或扫描二维码:

wKioL1SaztmBchKiAADsv4YAWBY259.jpg


【MyBatis学习笔记】系列之预备篇一:ant的下载与安装

【MyBatis学习笔记】系列之预备篇二:ant入门示例

【MyBatis学习笔记】系列之一:MyBatis入门示例

【MyBatis学习笔记】系列之二:MyBatis增删改示例

【MyBatis学习笔记】系列之三:MyBatis的association示例

【MyBatis学习笔记】系列之四:MyBatis association的两种形式

【MyBatis学习笔记】系列之五:MyBatis与Spring集成示例

【MyBatis学习笔记】系列之六:MyBatis与Spring集成示例续

【MyBatis学习笔记】系列之七:MyBatis一对多双向关联

【MyBatis学习笔记】系列之八:MyBatis MapperScannerConfigurer配置

【MyBatis学习笔记】系列之九:MyBatis collection的两种形式

【MyBatis学习笔记】系列之十:MyBatis日志之Log4j示例

【MyBatis学习笔记】系列之十一:MyBatis多参数传递之注解方式示例

【MyBatis学习笔记】系列之十二:MyBatis多参数传递之默认命名方式示例

【MyBatis学习笔记】系列之十三:MyBatis多参数传递之Map方式示例

【MyBatis学习笔记】系列之十四:MyBatis中的N+1问题

【MyBatis学习笔记】系列之十五:MyBatis多参数传递之混合方式

【MyBatis学习笔记】系列之十六:Spring声明式事务管理示例

【MyBatis学习笔记】系列之十七:MyBatis多对多保存示例

【MyBatis学习笔记】系列之十八:MyBatis多对多关联查询示例

【MyBatis学习笔记】系列之十九:如何在MyBatis-3.2.7中使用Log4j2 rc2

MyBatis中如何通过继承SqlSessionDaoSupport来编写DAO(一)

MyBatis中如何通过继承SqlSessionDaoSupport来编写DAO(二)