Mybatis如何关联查询

创建Teacher和Student表:

Teacher



Student



创建Teacher和Student类:

Teacher

public class Teacher {
	private Integer id;
	private String name;
	private List<Student> students;

	public Teacher() {
		super();
	}

	public Teacher(Integer id, String name, List<Student> students) {
		super();
		this.id = id;
		this.name = name;
		this.students = students;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public List<Student> getStudents() {
		return students;
	}

	public void setStudents(List<Student> students) {
		this.students = students;
	}
}
Student

public class Student {
	private Integer id;
	private String name;
	private Integer teacherId;
	private Teacher teacher;

	public Student() {
		super();
	}

	public Student(Integer id, String name, Integer teacherId, Teacher teacher) {
		super();
		this.id = id;
		this.name = name;
		this.teacherId = teacherId;
		this.teacher = teacher;
	}

	public Integer getId() {
		return id;
	}

	public void setId(Integer id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Integer getTeacherId() {
		return teacherId;
	}

	public void setTeacherId(Integer teacherId) {
		this.teacherId = teacherId;
	}

	public Teacher getTeacher() {
		return teacher;
	}

	public void setTeacher(Teacher teacher) {
		this.teacher = teacher;
	}
}

我们在Teacher中定义了List<Student>,在Student中定义了Teacher,在关系映射时我们会用到这两个属性

首先是以Map类型返回数据:

	<select id="findTeacherMap" resultType="java.util.Map">
		SELECT
			t.id,
			t. NAME,
			s.id AS sid,
			s. NAME AS sname
		FROM
			teacher t
		LEFT JOIN student s ON t.id = s.teacher_id
	</select>

测试方法:

	@Test
	public void findTeacherMap() {
		try {
			SqlSession session = sessionFactory.openSession();
			List<Map<String, Object>> teachers = session.selectList("mybatis.model.TeacherMapper.findTeacherMap");
			for (Map<String, Object> map : teachers) {
				for (Entry<String, Object> teacher : map.entrySet()) {
					System.out.print(teacher.getKey() + ":" + teacher.getValue() + ",");
				}
				System.out.println();
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
这种方法没什么好说的就是两表联查把结果集放到Map中,下面是运行结果

sname:小名,id:1,NAME:keke,sid:1,
sname:大明,id:1,NAME:keke,sid:2,
sname:微微,id:1,NAME:keke,sid:3,
sname:小华,id:2,NAME:array,sid:4,
sname:张三,id:2,NAME:array,sid:5,
sname:李四,id:2,NAME:array,sid:6,


当一对多的关系映射时我们有两种方法来应对:

第一种:我们在mapper.xml中定义resultMap

	<resultMap type="Teacher" id="teacherMap1">
		<id column="id" property="id" />
		<result column="name" property="name" />
		<collection property="students" ofType="Student" fetchType="lazy">
			<id column="sid" property="id" />
			<result column="sname" property="name" />
		</collection>
	</resultMap>

	<select id="findTeacherResultMap1" resultMap="teacherMap1">
		SELECT
			t.id,
			t. NAME,
			s.id AS sid,
			s. NAME AS sname
		FROM
			teacher t
		LEFT JOIN student s ON t.id = s.teacher_id
	</select>

resultMap跟bean的属性结构差不多.type是实际的java类型这里我用到了别名所以直接写的Teacher,id是标识引用这个resultMap时会用到,column是select标签中的列名不可重复(重复用别名),property是bean中属性名称,bean中的students是集合我们用collection,这里的ofType是集合的类型,延迟加载tetchType="lazy",虽然这里启用了延迟加载但实际开发中不建议用这种方法,因为如果数据量大的话会非常耗性能.

测试方法:

	@Test
	public void findTeacherResultMap1() {
		try {
			SqlSession session = sessionFactory.openSession();
			List<Teacher> teachers = session.selectList("mybatis.model.TeacherMapper.findTeacherResultMap1");
			for (Teacher teacher : teachers) {
				System.out.println("id:" + teacher.getId() + ",name:" + teacher.getName());
				for (Student stuent : teacher.getStudents()) {
					System.out.println("sid:" + stuent.getId() + ",sname:" + stuent.getName());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}

运行结果:

id:1,name:keke
sid:1,sname:小名
sid:2,sname:大明
sid:3,sname:微微
id:2,name:array
sid:4,sname:小华
sid:5,sname:张三
sid:6,sname:李四

第二种:我们还是mapper.xml中定义resultMap

	<resultMap type="Teacher" id="teacherMap2">
		<id column="id" property="id" />
		<result column="name" property="name" />
		<collection column="id" property="students" select="findStudentsResultMap2"/>
	</resultMap>
<span style="white-space:pre">	</span><select id="findTeacherResultMap2" resultMap="teacherMap2">
		SELECT
			id,
			NAME
		FROM
			teacher
	</select>
	<select id="findStudentsResultMap2" resultType="Student">
		SELECT
			id,
			NAME
		FROM
			student
		WHERE
			teacher_id = #{id}
		LIMIT 0,2
	</select>

这种方式我们把students集合的部分单独查询并限制条数,collection中的column是查询是要传入的参数,select是要执行那个select语句,这种方式比第一种方式性能方面会好很多也灵活很多.

测试方法:

	@Test
	public void findTeacherResultMap2() {
		try {
			SqlSession session = sessionFactory.openSession();
			List<Teacher> teachers = session.selectList("mybatis.model.TeacherMapper.findTeacherResultMap2");
			for (Teacher teacher : teachers) {
				System.out.println("id:" + teacher.getId() + ",name:" + teacher.getName());
				for (Student stuent : teacher.getStudents()) {
					System.out.println("sid:" + stuent.getId() + ",sname:" + stuent.getName());
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
运行结果:

id:1,name:keke
sid:1,sname:小名
sid:2,sname:大明
id:2,name:array
sid:4,sname:小华
sid:5,sname:张三
多对一的关系映射:

首先是resultMap

	<resultMap type="Student" id="StudentMap">
		<id column="id" property="id" />
		<result column="name" property="name" />
		<association property="teacher" javaType="Teacher">
			<id column="tid" property="id" />
			<result column="tname" property="name" />
		</association>
	</resultMap>
	<select id="findStudents" resultMap="StudentMap">
		SELECT
			s.id,
			s. NAME,
			t.id AS tid,
			t. NAME AS tname
		FROM
			student s
		RIGHT JOIN teacher t ON s.teacher_id = t.id;
	</select>
测试方法:

	@Test
	public void findStudents() {
		try {
			SqlSession session = sessionFactory.openSession();
			List<Student> students = session.selectList("mybatis.model.TeacherMapper.findStudents");
			for (Student student : students) {
				System.out.println("id:" + student.getId() + ",name:" + student.getName());
				System.out.println("老师:"+student.getTeacher().getName());
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
运行结果:

id:1,name:小名
老师:keke
id:2,name:大明
老师:keke
id:3,name:微微
老师:keke
id:4,name:小华
老师:array
id:5,name:张三
老师:array
id:6,name:李四
老师:array






  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值