Version: Next

1. 多对一

  • 多个学生对应一个老师
  • 对于学生而言,关联多个学生,关联一个老师
  • 对于老师而言,集合,一个老师又很多学生

之前使用resultMap中的子标签result将数据库字段映射为实体类属性

现在我们将使用resultMap的其他字段来描述更复杂的查询情况

查看官方文档对ResultMap子标签的描述:

结果映射ResultMap:

  • association——一个复杂类型的关联,许多结果将包装成这种类型
    • 嵌套结果映射——关联本身可以是一个resultMap元素,或者从别处引用一个
  • collection——一个复杂类型的集合
    • 嵌套结果映射——集合本身可以是一个resultMap元素,或者从别处引用一个

1.1 环境搭建

数据库表

CREATE TABLE teacher(
id INT(10) NOT NULL ,
NAME VARCHAR(30) DEFAULT NULL,
PRIMARY KEY (`id`)
)ENGINE = INNODB DEFAULT CHARSET =utf8;
INSERT INTO teacher(id,NAME) VALUE (1, "秦老师");
CREATE TABLE student(
id INT(10) NOT NULL ,
NAME VARCHAR(30) DEFAULT NULL,
tid INT(10) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `fktid` (`tid`),
CONSTRAINT `fktid` FOREIGN KEY (`tid`) REFERENCES teacher (`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);

1.2 新建项目

新建模块mybatis06,删除所有Mapper,Pojo, 删除mybatis-config.xml中的mappers标签

1.2.1 建POJO

  • Teacher

    @Data
    @AllArgsConstructor
    @NoArgsConstructor
    public class Teacher {
    private int id;
    private String name;
    }
  • Student

    @Data
    @NoArgsConstructor
    @AllArgsConstructor
    public class Student {
    private int id;
    private String name;
    private Teacher teacher;
    }

1.2.2 建Mapper

  • TeacherMapper

    public interface TeacherMapper {
    }
  • StudentMapper

    public interface StudentMapper {
    }

1.2.3 建mapper.xml

建立在resources目录下,与src中的Mapper接口同包 (确保包是多级路径,而不是一个单级路径名字带几个.)


内容复制mybatis-config.xml修改三个位置


configurationconfig都改为mapper即可

  • TeacherMapper.xml

    <mapper namespace="com.bsx.dao.TeacherMapper">
    </mapper>
  • StudentMapper.xml

    <mapper namespace="com.bsx.dao.StudentMapper">
    </mapper>

1.2.4 注册Mapper

mybatis-config.xml中注册mapper

<mappers>
<mapper resource="com/bsx/dao/TeacherMapper.xml"/>
<mapper resource="com/bsx/dao/StudentMapper.xml"/>
</mappers>

1.2.5 测试环境搭建

  • 接口

    public interface TeacherMapper {
    Teacher getTeacher(@Param("tid") int id);
    }
  • mapper.xml

    <mapper namespace="com.bsx.dao.TeacherMapper">
    <select id="getTeacher" resultType="com.bsx.pojo.Teacher" >
    select * from teacher where id = #{tid}
    </select>
    </mapper>
  • 测试类

    @Test
    public void testEnv() throws IOException {
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try {
    TeacherMapper mapper = sqlSession.getMapper(TeacherMapper.class);
    Teacher teacher = mapper.getTeacher(1);
    System.out.println(teacher);
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    sqlSession.close();
    }
    }

2. 多对一需求

需求,查询所有的学生信息以及对应的老师的信息

  • sql (sid, sname, tname, tid为别名)

    SELECT
    s.id sid, s.name sname, t.name tname, t.id tid
    FROM
    student s, teacher t
    WHERE
    s.tid = t.id;

Student类中有一个成员变量Teacher teacher,所以上述sql不能直接用Mybatis查询

2.1 思路一——按照查询嵌套处理

子查询

  1. 查询所有的学生信息
  2. 根据查询出来的学生的tid,寻找对应的老师
  • StudentMapper接口

    //查询所有的学生信息以及对应的老师的信息
    List<Student> getStudent();
  • StudentMapper.xml

    主键一般用id标签,通用情况下用result标签

    复杂的属性需要单独处理

    • association——针对对象
      • javatype指定映射对象的类型
      • select指定嵌套查询

  • collection——针对集合(一对多,之后再说)
  • 测试
@Test
public void testGetStudent() throws IOException {
InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
SqlSession sqlSession = sqlSessionFactory.openSession();
try {
StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
List<Student> students = mapper.getStudent();
for (Student student : students) {
System.out.println(student);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
sqlSession.close();
}
}
  • 结果

    Student(id=1, name=小明, teacher=Teacher(id=1, name=秦老师))
    Student(id=2, name=小红, teacher=Teacher(id=1, name=秦老师))
    Student(id=3, name=小张, teacher=Teacher(id=1, name=秦老师))
    Student(id=4, name=小李, teacher=Teacher(id=1, name=秦老师))
    Student(id=5, name=小王, teacher=Teacher(id=1, name=秦老师))

2.2 思路二——按照结果嵌套处理(常用)

  1. 查询所有的学生信息
  2. 根据查询出来的学生的tid,寻找对应的老师
  • 接口

    //方式二,按照结果嵌套
    List<Student> getStudent2();
  • StudentMapper.xml

    <!-- 方式二 按照结果嵌套处理-->
    <select id="getStudent2" resultMap="StudentTeacher2">
    SELECT
    s.id sid, s.name sname, t.name tname, t.id tid
    FROM
    student s, teacher t
    WHERE
    s.tid = t.id;
    </select>
    <resultMap id="StudentTeacher2" type="com.bsx.pojo.Student">
    <result column="sid" property="id"/>
    <result column="sname" property="name"/>
    <association property="teacher" javaType="Teacher">
    <result column="tname" property="name"/>
    <result column="tid" property="id"/>
    </association>
    </resultMap>
  • 测试

    @Test
    public void testGetStudent2() throws IOException {
    InputStream inputStream = Resources.getResourceAsStream("mybatis-config.xml");
    SqlSessionFactory sqlSessionFactory = new SqlSessionFactoryBuilder().build(inputStream);
    SqlSession sqlSession = sqlSessionFactory.openSession();
    try {
    StudentMapper mapper = sqlSession.getMapper(StudentMapper.class);
    List<Student> students = mapper.getStudent2();
    for (Student student : students) {
    System.out.println(student);
    }
    } catch (Exception e) {
    e.printStackTrace();
    } finally {
    sqlSession.close();
    }
    }
  • 结果

    Student(id=1, name=小明, teacher=Teacher(id=1, name=秦老师))
    Student(id=2, name=小红, teacher=Teacher(id=1, name=秦老师))
    Student(id=3, name=小张, teacher=Teacher(id=1, name=秦老师))
    Student(id=4, name=小李, teacher=Teacher(id=1, name=秦老师))
    Student(id=5, name=小王, teacher=Teacher(id=1, name=秦老师))