前几天有网友问到MyBatis多对多的问题,不过愧对网友厚爱的是,最近一直忙,直到现在才有时间处理此事。今天就先写一个多对多保存的示例,算是对这位网友的初步回应,以后会有更多相关的博文发表。
为演示多对多,我们可以模拟学生选课的情形。一个学生可以选修多门课程,一门课程可以被多个学生选修。显然,这是一种多对多的关系。先创建课程表如下(本文示例完整源码下载:http://down.51cto.com/data/907686):
1
2
3
4
5
6
7
8
9
10
11
12
|
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'
,
'数据结构'
);
|
接着创建学生选修表,用来保存学生的选课信息,如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
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表的主键。
创建对应的课程实体类。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
|
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;
}
}
|
为学生实体类添加所选课程属性如下:
1
2
3
4
5
6
7
8
9
10
|
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
1
2
3
4
5
|
package
com.abc.mapper;
import
com.abc.domain.Course;
public
interface
CourseMapper {
public
Course getById(
int
id);
}
|
CourseMapper.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
<?
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
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
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);
}
}
|
CourseMapper和CourseDao在spring中的配置如下:
1
2
3
4
5
6
7
|
<
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接口中添加一个方法,如下:
1
|
public
void
saveElecCourse(Student student, Course course);
|
映射文件StudentMapper.xml中添加相应的insert语句如下:
1
2
3
4
5
6
7
|
<!--这里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类中添加相关方法如下:
1
2
3
4
5
|
//保存学生选课信息
public
void
saveElecCourse(Student student, Course course)
{
this
.studentMapper.saveElecCourse(student, course);
}
|
接下来是运行类(ManyToManyDemo.java)。在这个类中,我们让id为8的学生(刘晓)选修id为1的课程(数据结构)。代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
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);
}
}
|
运行结束后,选修表中已插入了这名学生的选课信息,如下图所示。
本文转自 NashMaster2011 51CTO博客,原文链接:http://blog.51cto.com/legend2011/1270547,如需转载请自行联系原作者