MyBatis实现关联表查询
一、一对一关联
1.1、提出需求
根据班级id查询班级信息(带老师的信息)
1.2、创建表和数据
创建一张教师表和班级表,这里我们假设一个老师只负责教一个班,那么老师和班级之间的关系就是一种一对一的关系。
复制代码
1CREATETABLEteacher(
2t_idINTPRIMARYKEYAUTO_INCREMENT,
3t_nameVARCHAR(20)
4);
5CREATETABLEclass(
6c_idINTPRIMARYKEYAUTO_INCREMENT,
7c_nameVARCHAR(20),
8teacher_idINT
9);
10ALTERTABLEclassADDCONSTRAINTfk_teacher_idFOREIGNKEY(teacher_id)REFERENCESteacher(t_id);
11
12INSERTINTOteacher(t_name)VALUES(''teacher1'');
13INSERTINTOteacher(t_name)VALUES(''teacher2'');
14
15INSERTINTOclass(c_name,teacher_id)VALUES(''class_a'',1);
16INSERTINTOclass(c_name,teacher_id)VALUES(''class_b'',2);
复制代码
表之间的关系如下:
1.3、定义实体类
1、Teacher类,Teacher类是teacher表对应的实体类。
复制代码
1packageme.gacl.domain;
2
3/
4@authorgacl
5定义teacher表对应的实体类
6/
7publicclassTeacher{
8
9//定义实体类的属性,与teacher表中的字段对应
10privateintid;//id===>t_id
11privateStringname;//name===>t_name
12
13publicintgetId(){
14returnid;
15}
16
17publicvoidsetId(intid){
18this.id=id;
19}
20
21publicStringgetName(){
22returnname;
23}
24
25publicvoidsetName(Stringname){
26this.name=name;
27}
28
29@Override
30publicStringtoString(){
31return"Teacher[id="+id+",name="+name+"]";
32}
33}
复制代码
2、Classes类,Classes类是class表对应的实体类
复制代码
1packageme.gacl.domain;
2
3/
4@authorgacl
5定义class表对应的实体类
6/
7publicclassClasses{
8
9//定义实体类的属性,与class表中的字段对应
10privateintid;//id===>c_id
11privateStringname;//name===>c_name
12
13/
14class表中有一个teacher_id字段,所以在Classes类中定义一个teacher属性,
15用于维护teacher和class之间的一对一关系,通过这个teacher属性就可以知道这个班级是由哪个老师负责的
16/
17privateTeacherteacher;
18
19publicintgetId(){
20returnid;
21}
22
23publicvoidsetId(intid){
24this.id=id;
25}
26
27publicStringgetName(){
28returnname;
29}
30
31publicvoidsetName(Stringname){
32this.name=name;
33}
34
35publicTeachergetTeacher(){
36returnteacher;
37}
38
39publicvoidsetTeacher(Teacherteacher){
40this.teacher=teacher;
41}
42
43@Override
44publicStringtoString(){
45return"Classes[id="+id+",name="+name+",teacher="+teacher+"]";
46}
47}
复制代码
1.4、定义sql映射文件classMapper.xml
复制代码
1
2
3
6
7
8
17
18
23
24selectfromclassc,teachertwherec.teacher_id=t.t_idandc.c_id=#{id}
25
26
27
28
29
30
31
32
33
34
35
36
41
42selectfromclasswherec_id=#{id}
43
44
45
46
47
48
49
50
51
52SELECTt_idid,t_namenameFROMteacherWHEREt_id=#{id}
53
54
55
复制代码
在conf.xml文件中注册classMapper.xml
1.5、编写单元测试代码
复制代码
1packageme.gacl.test;
2
3importme.gacl.domain.Classes;
4importme.gacl.util.MyBatisUtil;
5importorg.apache.ibatis.session.SqlSession;
6importorg.junit.Test;
7
8publicclassTest3{
9
10@Test
11publicvoidtestGetClass(){
12SqlSessionsqlSession=MyBatisUtil.getSqlSession();
13/
14映射sql的标识字符串,
15me.gacl.mapping.classMapper是classMapper.xml文件中mapper标签的namespace属性的值,
16getClass是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
17/
18Stringstatement="me.gacl.mapping.classMapper.getClass";//映射sql的标识字符串
19//执行查询操作,将查询结果自动封装成Classes对象返回
20Classesclazz=sqlSession.selectOne(statement,1);//查询class表中id为1的记录
21//使用SqlSession执行完SQL之后需要关闭SqlSession
22sqlSession.close();
23System.out.println(clazz);//打印结果:Classes[id=1,name=class_a,teacher=Teacher[id=1,name=teacher1]]
24}
25
26@Test
27publicvoidtestGetClass2(){
28SqlSessionsqlSession=MyBatisUtil.getSqlSession();
29/
30映射sql的标识字符串,
31me.gacl.mapping.classMapper是classMapper.xml文件中mapper标签的namespace属性的值,
32getClass2是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
33/
34Stringstatement="me.gacl.mapping.classMapper.getClass2";//映射sql的标识字符串
35//执行查询操作,将查询结果自动封装成Classes对象返回
36Classesclazz=sqlSession.selectOne(statement,1);//查询class表中id为1的记录
37//使用SqlSession执行完SQL之后需要关闭SqlSession
38sqlSession.close();
39System.out.println(clazz);//打印结果:Classes[id=1,name=class_a,teacher=Teacher[id=1,name=teacher1]]
40}
41}
复制代码
1.6、MyBatis一对一关联查询总结
MyBatis中使用association标签来解决一对一的关联查询,association标签可用的属性如下:
property:对象属性的名称
javaType:对象属性的类型
column:所对应的外键字段名称
select:使用另一个查询封装的结果
二、一对多关联
2.1、提出需求
根据classId查询对应的班级信息,包括学生,老师
2.2、创建表和数据
在上面的一对一关联查询演示中,我们已经创建了班级表和教师表,因此这里再创建一张学生表
复制代码
CREATETABLEstudent(
s_idINTPRIMARYKEYAUTO_INCREMENT,
s_nameVARCHAR(20),
class_idINT
);
INSERTINTOstudent(s_name,class_id)VALUES(''student_A'',1);
INSERTINTOstudent(s_name,class_id)VALUES(''student_B'',1);
INSERTINTOstudent(s_name,class_id)VALUES(''student_C'',1);
INSERTINTOstudent(s_name,class_id)VALUES(''student_D'',2);
INSERTINTOstudent(s_name,class_id)VALUES(''student_E'',2);
INSERTINTOstudent(s_name,class_id)VALUES(''student_F'',2);
复制代码
2.3、定义实体类
1、Student类
复制代码
1packageme.gacl.domain;
2
3/
4@authorgacl
5定义student表所对应的实体类
6/
7publicclassStudent{
8
9//定义属性,和student表中的字段对应
10privateintid;//id===>s_id
11privateStringname;//name===>s_name
12
13publicintgetId(){
14returnid;
15}
16
17publicvoidsetId(intid){
18this.id=id;
19}
20
21publicStringgetName(){
22returnname;
23}
24
25publicvoidsetName(Stringname){
26this.name=name;
27}
28
29@Override
30publicStringtoString(){
31return"Student[id="+id+",name="+name+"]";
32}
33}
复制代码
2、修改Classes类,添加一个Liststudents属性,使用一个List集合属性表示班级拥有的学生,如下:
复制代码
1packageme.gacl.domain;
2
3importjava.util.List;
4
5/
6@authorgacl
7定义class表对应的实体类
8/
9publicclassClasses{
10
11//定义实体类的属性,与class表中的字段对应
12privateintid;//id===>c_id
13privateStringname;//name===>c_name
14
15/
16class表中有一个teacher_id字段,所以在Classes类中定义一个teacher属性,
17用于维护teacher和class之间的一对一关系,通过这个teacher属性就可以知道这个班级是由哪个老师负责的
18/
19privateTeacherteacher;
20//使用一个List集合属性表示班级拥有的学生
21privateListstudents;
22
23publicintgetId(){
24returnid;
25}
26
27publicvoidsetId(intid){
28this.id=id;
29}
30
31publicStringgetName(){
32returnname;
33}
34
35publicvoidsetName(Stringname){
36this.name=name;
37}
38
39publicTeachergetTeacher(){
40returnteacher;
41}
42
43publicvoidsetTeacher(Teacherteacher){
44this.teacher=teacher;
45}
46
47publicListgetStudents(){
48returnstudents;
49}
50
51publicvoidsetStudents(Liststudents){
52this.students=students;
53}
54
55@Override
56publicStringtoString(){
57return"Classes[id="+id+",name="+name+",teacher="+teacher
58+",students="+students+"]";
59}
60}
复制代码
2.4、修改sql映射文件classMapper.xml
添加如下的SQL映射信息
复制代码
1
4
8
9selectfromclassc,teachert,studentswherec.teacher_id=t.t_idandc.C_id=s.class_idandc.c_id=#{id}
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
31
32selectfromclasswherec_id=#{id}
33
34
35
36
37
38
39
40
41
42SELECTt_idid,t_namenameFROMteacherWHEREt_id=#{id}
43
44
45
46SELECTs_idid,s_namenameFROMstudentWHEREclass_id=#{id}
47
复制代码
2.5、编写单元测试代码
复制代码
1packageme.gacl.test;
2
3importme.gacl.domain.Classes;
4importme.gacl.util.MyBatisUtil;
5importorg.apache.ibatis.session.SqlSession;
6importorg.junit.Test;
7
8publicclassTest4{
9
10@Test
11publicvoidtestGetClass3(){
12SqlSessionsqlSession=MyBatisUtil.getSqlSession();
13/
14映射sql的标识字符串,
15me.gacl.mapping.classMapper是classMapper.xml文件中mapper标签的namespace属性的值,
16getClass3是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
17/
18Stringstatement="me.gacl.mapping.classMapper.getClass3";//映射sql的标识字符串
19//执行查询操作,将查询结果自动封装成Classes对象返回
20Classesclazz=sqlSession.selectOne(statement,1);//查询class表中id为1的记录
21//使用SqlSession执行完SQL之后需要关闭SqlSession
22sqlSession.close();
23//打印结果:Classes[id=1,name=class_a,teacher=Teacher[id=1,name=teacher1],students=[Student[id=1,name=student_A],Student[id=2,name=student_B],Student[id=3,name=student_C]]]
24System.out.println(clazz);
25}
26
27@Test
28publicvoidtestGetClass4(){
29SqlSessionsqlSession=MyBatisUtil.getSqlSession();
30/
31映射sql的标识字符串,
32me.gacl.mapping.classMapper是classMapper.xml文件中mapper标签的namespace属性的值,
33getClass4是select标签的id属性值,通过select标签的id属性值就可以找到要执行的SQL
34/
35Stringstatement="me.gacl.mapping.classMapper.getClass4";//映射sql的标识字符串
36//执行查询操作,将查询结果自动封装成Classes对象返回
37Classesclazz=sqlSession.selectOne(statement,1);//查询class表中id为1的记录
38//使用SqlSession执行完SQL之后需要关闭SqlSession
39sqlSession.close();
40//打印结果:Classes[id=1,name=class_a,teacher=Teacher[id=1,name=teacher1],students=[Student[id=1,name=student_A],Student[id=2,name=student_B],Student[id=3,name=student_C]]]
41System.out.println(clazz);
42}
43}
|
|