collection与association标签的功能就是为了解决查询条件映射到一个类或一个集合上,适用于对于多对一,一对多的映射结果,现在我们就探究其具体使用吧。
环境搭建:
- 数据库搭建
CREATE TABLEteacher ( id INT(10) NOT NULL, name VARCHAR(30) DEFAULT NULL, PRIMARY KEY(id) ) ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO teacher(id, name) VALUES (1, '秦老师'); CREATE TABLEstudent ( id INT(10) NOT NULL, name VARCHAR(30) DEFAULT NULL, tid INT(10) DEFAULT NULL, PRIMARY KEY(id), KEYfktid (tid), CONSTRAINT fktid FOREIGN KEY (tid) REFERENCESteacher (id) ) ENGINE=INNODB DEFAULT CHARSET=utf8 INSERT INTO student (id, name, tid) VALUES ('1', '小明', '1'); INSERT INTO student (id, name, tid) VALUES ('2', '小红', '1'); INSERT INTO student (id, name, tid) VALUES ('3', '小张', '1'); INSERT INTO student (id, name, tid) VALUES ('4', '小李', '1'); INSERT INTO student (id, name, tid) VALUES ('5', '小王', '1');
- pojo
//GET,SET,ToString,有参,无参构造 public classTeacher { private intid; privateString name; }
//Get,Set,ToString, 有参,无参构造 public classStudent { private intid; privateString name; //多个学生可以是同一个老师,即多对一 privateTeacher teacher; }
多对一的理解:
- 多个学生对应一个老师
- 如果对于学生这边,就是一个多对一的现象,即从学生这边关联一个老师!
接口编写方法:
//获取所有学生及对应老师的信息 public List<Student> getStudents();
配置文件:
方式一:按查询嵌套查询
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.ttt.mapper.StudentMapper"> <select id="getStudents"resultMap="StudentTeacher">select * from student </select> <resultMap id="StudentTeacher"type="Student"> <!--association关联属性 property属性名 javaType属性类型 column在多的一方的表中的列名--> <association property="teacher"column="tid"javaType="Teacher"select="getTeacher"/> </resultMap> <!--这里传递过来的id,只有一个属性的时候,下面可以写任何值 association中column多参数配置: column="{key=value,key=value}" 其实就是键值对的形式,key是传给下个sql的取值名称,value是片段一中sql查询的字段名。 --> <select id="getTeacher"resultType="teacher">select * from teacher where id = #{id} </select> </mapper>
方式二:按结果嵌套查询
<select id="getStudents2"resultMap="StudentTeacher2" >select s.id sid, s.name sname , t.name tname from student s,teacher t where s.tid = t.id </select> <resultMap id="StudentTeacher2"type="Student"> <id property="id"column="sid"/> <result property="name"column="sname"/> <!--关联对象property 关联对象在Student实体类中的属性--> <association property="teacher"javaType="Teacher"> <result property="name"column="tname"/> </association> </resultMap>
在核心配置文件注册。
测试:
1 @Test 2 public voidtestGetStudents(){ 3 SqlSession session =MybatisUtils.getSession(); 4 StudentMapper mapper = session.getMapper(StudentMapper.class); 5 6 List<Student> students =mapper.getStudents(); 7 8 for(Student student : students){ 9 System.out.println( 10 "学生名:"+student.getName() 11 +" 老师:"+student.getTeacher().getName()); 12 } 13 }
一对多的理解:
- 一个老师拥有多个学生
- 如果对于老师这边,就是一个一对多的现象。
接口编写方法:
//获取指定老师,及老师下的所有学生 public Teacher getTeacher(int id);
mapper配置文件:
方式一:按查询嵌套查询
<select id="getTeacher2"resultMap="TeacherStudent2">select * from teacher where id = #{id} </select> <resultMap id="TeacherStudent2"type="Teacher"> <!--column是一对多的外键 , 写的是一的主键的列名--> <collection property="students"javaType="ArrayList"ofType="Student"column="id"select="getStudentByTeacherId"/> </resultMap> <select id="getStudentByTeacherId"resultType="Student">select * from student where tid = #{id} </select>
方式二:按结果嵌套查询
<mapper namespace="com.ttt.mapper.TeacherMapper"> <select id="getTeacher"resultMap="TeacherStudent">select s.id sid, s.name sname , t.name tname, t.id tid from student s,teacher t where s.tid = t.id and t.id=#{id} </select> <resultMap id="TeacherStudent"type="Teacher"> <result property="name"column="tname"/> <collection property="students"ofType="Student"> <result property="id"column="sid" /> <result property="name"column="sname" /> <result property="tid"column="tid" /> </collection> </resultMap> </mapper>
在核心配置文件注册。
测试:
1 @Test 2 public voidtestGetTeacher2(){ 3 SqlSession session =MybatisUtils.getSession(); 4 TeacherMapper mapper = session.getMapper(TeacherMapper.class); 5 Teacher teacher = mapper.getTeacher2(1); 6 System.out.println(teacher.getName()); 7 System.out.println(teacher.getStudents()); 8 }
小结:
1、关联-association 集合-collection
2、所以association是用于一对一和多对一,而collection是用于一对多的关系
3、JavaType和ofType都是用来指定对象类型的
- JavaType是用来指定pojo中属性的类型
- ofType指定的是映射到list集合属性中pojo的类型。