分享

Mybatis关联查询之一对多和多对一XML配置详解

 甘甘灰 2018-08-03

平时在开发过程中dao、bean和XML文件都是自动生成的,很少写XML的配置关系,今天记录一下mybatis的关联查询中的多对一和一对多的情况。

  • 首先是有两张表(学生表Student和老师Teacher表),为了更易懂,这里只设置了最简单的几个必要字段。表结构如下图

Student表:


Teacher表:

  • 创建实体bean
Teacher.java:
  1. import java.util.List;
  2. /**
  3. * TODO
  4. * @version 创建时间:2017年12月21日 上午9:02:45
  5. */
  6. public class Teacher {
  7. private Integer id;
  8. private String name;
  9. private String className;
  10. private List<Student> students;
  11. public List<Student> getStudents() {
  12. return students;
  13. }
  14. public void setStudents(List<Student> students) {
  15. this.students = students;
  16. }
  17. public Integer getId() {
  18. return id;
  19. }
  20. public void setId(Integer id) {
  21. this.id = id;
  22. }
  23. public String getName() {
  24. return name;
  25. }
  26. public void setName(String name) {
  27. this.name = name;
  28. }
  29. public String getClassName() {
  30. return className;
  31. }
  32. public void setClassName(String className) {
  33. this.className = className;
  34. }
  35. }

Sfudent.java

  1. /**
  2. * TODO
  3. *
  4. * @author 作者 E-mail:2332999366@qq.com
  5. * @version 创建时间:2017年12月21日 上午9:01:17
  6. */
  7. public class Student {
  8. private Integer id;
  9. private String name;
  10. private Integer teacherId;
  11. private String className;
  12. private Teacher teacher;
  13. public Teacher getTeacher() {
  14. return teacher;
  15. }
  16. public void setTeacher(Teacher teacher) {
  17. this.teacher = teacher;
  18. }
  19. public Integer getId() {
  20. return id;
  21. }
  22. public void setId(Integer id) {
  23. this.id = id;
  24. }
  25. public String getName() {
  26. return name;
  27. }
  28. public void setName(String name) {
  29. this.name = name;
  30. }
  31. public Integer getTeacherId() {
  32. return teacherId;
  33. }
  34. public void setTeacherId(Integer teacherId) {
  35. this.teacherId = teacherId;
  36. }
  37. public String getClassName() {
  38. return className;
  39. }
  40. public void setClassName(String className) {
  41. this.className = className;
  42. }
  43. @Override
  44. public String toString() {
  45. return "{id:"+this.id+",name:"+this.name+",className:"+this.className+",teacherId:"+this.teacherId+"}";
  46. }
  47. }
  • 下面重点来了:配置Mapper.xml文件:
  1. <?xml version="1.0" encoding="UTF-8" ?>
  2. <!DOCTYPE mapper PUBLIC "-////DTD Mapper 3.0//EN" "http:///dtd/mybatis-3-mapper.dtd">
  3. <mapper namespace="com.tz.mybatis.dao.studentDao">
  4. <!-- /////////////////////////////////一对多的第一种写法,一般考虑到性能问题,不会这么实现//////////////////////// -->
  5. <resultMap type="Teacher" id="teacherMap">
  6. <id column="id" property="id"/>
  7. <result column="name" property="name"/>
  8. <collection property="students" ofType="Student" column="id">
  9. <id column="sid" property="id"/><!-- 这里的column对应的是下面查询的别名,而不是表字段名 -->
  10. <result column="sname" property="name"/><!-- property对应JavaBean中的属性名 -->
  11. <result column="className" property="className"/>
  12. </collection>
  13. </resultMap>
  14. <!-- 查询所有的老师级各自的所有学生 -->
  15. <select id="getTeachers" parameterType="Teacher" resultMap="teacherMap">
  16. SELECT
  17. t.id,
  18. t.NAME,
  19. t.class_Name,
  20. s.id AS sid,
  21. s. NAME AS sname,
  22. s.class_name as className
  23. FROM
  24. teacher t
  25. LEFT JOIN student s ON t.id = s.teacher_id
  26. </select>
  27. </mapper>

  • 测试类:

  1. package com.tz.test;
  2. import java.io.IOException;
  3. import java.io.InputStream;
  4. import java.util.List;
  5. import org.apache.ibatis.io.Resources;
  6. import org.apache.ibatis.session.SqlSession;
  7. import org.apache.ibatis.session.SqlSessionFactory;
  8. import org.apache.ibatis.session.SqlSessionFactoryBuilder;
  9. import org.junit.Before;
  10. import org.junit.Test;
  11. import com.tz.mybatis.bean.Student;
  12. import com.tz.mybatis.bean.Teacher;
  13. public class TeacherTest {
  14. private SqlSessionFactory sqlSessionFactory;
  15. @Before
  16. public void init() throws IOException {
  17. String resource = "mybatis-config.xml";
  18. InputStream inputStream = Resources.getResourceAsStream(resource);
  19. sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
  20. }
  21. @Test
  22. public void getTeachers() {
  23. SqlSession session = sqlSessionFactory.openSession();
  24. List<Teacher> list = session.selectList("com.tz.mybatis.dao.studentDao.getTeachers");
  25. System.out.println(list);
  26. }
  27. }

下面给出第二种写法:

  1. <!-- //////////////////////////////////////////////一对多的第二种写法///////////////////////////////////////////////////// -->
  2. <resultMap type="Teacher" id="teacherMaps">
  3. <id column="id" property="id"/>
  4. <result column="name" property="name"/>
  5. <result column="class_name" property="className"/>
  6. <collection property="students" ofType="Student" select="getStudents" column="id">
  7. </collection>
  8. </resultMap>
  9. <!-- 查询所有的老师级各自的所有学生 -->
  10. <select id="getAllTeacher" parameterType="Teacher" resultMap="teacherMaps">
  11. SELECT
  12. t.id,
  13. t.NAME,
  14. t.class_name
  15. FROM
  16. teacher t
  17. </select>
  18. <select id="getStudents" parameterType="int" resultType="Student">
  19. select
  20. s.id,
  21. s. NAME,
  22. s.class_name as className
  23. from student s
  24. where teacher_id = #{id}
  25. </select>

测试类:

  1. @Test
  2. public void getTeachers2() {
  3. SqlSession session = sqlSessionFactory.openSession();
  4. List<Teacher> list = session.selectList("com.tz.mybatis.dao.studentDao.getAllTeacher");
  5. System.out.println(list);
  6. }

查询学生信息(多对一):

首先还是配置文件:

  1. <resultMap type="Student" id="studentMap">
  2. <id column="id" property="id"/>
  3. <result column="name" property="name"/>
  4. <result column="class_name" property="className"/>
  5. <result column="teacher_id" property="teacherId"/>
  6. <association property="teacher" select="getTeacher" column="teacher_id" javaType="Teacher">
  7. <!-- 这里要注意的是column对应的是student中的外键,而且需是表字段名 -->
  8. </association>
  9. </resultMap>
  10. <select id="getStudent" resultMap="studentMap">
  11. SELECT
  12. s.id,
  13. s.name,
  14. s.class_name,
  15. s.teacher_id
  16. FROM
  17. student s
  18. </select>
  19. <select id="getTeacher" resultType="Teacher" parameterType="int">
  20. SELECT
  21. t.id,
  22. t.name,
  23. t.class_name as className
  24. FROM teacher t
  25. where id = #{teacher_id}
  26. </select>

测试类:

  1. @Test
  2. public void getStudents() {
  3. SqlSession session = sqlSessionFactory.openSession();
  4. List<Student> list = session.selectList("com.tz.mybatis.dao.studentDao.getStudent");
  5. System.out.println(list);
  6. }

最后:当然如果不想配置这么麻烦的信息,可以直接写一个关联查询的SQL语句,返回结果直接由Map接受即可。不过这样就不太符合面向对象的理念了。

    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多