您的位置:

Mybatis一对多映射详解

一、Mybatis一对多映射原理

在Mybatis中,一对多映射指的是一个实体类A中包含一个实体类B的集合,即A与B是一对多的关系。Mybatis通过使用嵌套查询或嵌套结果来实现一对多映射。

嵌套查询指的是使用多条SQL语句来查询实体类A和实体类B,然后在Java代码中通过循环来实现将实体类B的结果集加入到实体类A中。而嵌套结果则是通过一条SQL语句查询出实体类A和实体类B的集合,并将实体类B的集合放入实体类A中。

举例来说,有一个学生表和成绩表,学生表和成绩表是一对多的关系,一个学生可能对应多个成绩。这时候我们就可以使用Mybatis的一对多映射来查询出每个学生对应的成绩,将结果集保存到一个List中,然后将List放入Student对象中。


public class Student {
    private int id;
    private String name;
    private List<Score> scores; // 一对多映射中的集合属性,表示学生对应的成绩列表
    // getter/setter方法省略
}

public class Score {
    private int id;
    private int stuId; //成绩所对应的学生id
    private String subject;
    private int score;
    // getter/setter方法省略
}

二、Mybatis一对多映射配置

在Mybatis中,配置一对多映射需要在映射文件中进行配置。具体步骤如下:

1、在映射文件中定义实体类A的resultMap,以及定义实体类A和实体类B的resultMap,注意要给实体类B设置一个association标签,指定实体类B对应的Java属性



   
     
    
     
    
     
    
          
     
          
     
          
     
     
    

   

2、编写SQL语句查询出实体类A和实体类B的数据,并在SQL语句中使用嵌套查询或嵌套结果。例如:



3、在接口中定义方法,如下所示:


public interface StudentMapper {
     public Student getStudentWithScores(int id);
}

4、调用方法来查询结果:


SqlSession session = MybatisUtils.getSession();
try {
     StudentMapper mapper = session.getMapper(StudentMapper.class);
     Student student = mapper.getStudentWithScores(1);
} finally {
     session.close();
}

三、Mybatis映射

Mybatis使用映射文件来定义Java对象与对应数据库表之间的映射关系。在一对多映射中,需要为实体类A和实体类B分别定义对应的resultMap。

在实体类A的resultMap中,通过使用collection标签来定义与实体类B的集合属性对应的resultMap,然后在实体类B的resultMap中,使用association标签来定义实体类A的属性与数据库表的字段之间的映射关系。具体实现可以参考第二部分中的代码示例。

四、Mybatis一对多映射分步查询

Mybatis一对多映射分步查询指的是在不使用嵌套查询或嵌套结果的情况下分步查询出实体类A和实体类B的数据,并将实体类B的数据作为集合属性设置到实体类A中。

具体步骤如下:

1、在接口中定义方法,如下所示:


public interface StudentMapper {
     public Student getStudent(int id);
     public List<Score> getScoresByStuId(int stuId);
}

2、在映射文件中配置以上两个方法,分别查询出实体类A和实体类B的数据。例如:





3、调用以上两个方法,并将其中一个方法的结果集设置到另一个方法所返回的实体类中,具体代码示例可参考以下实现:


public Student getStudent(int id) {
    SqlSession session = MybatisUtils.getSession();
    try {
        StudentMapper mapper = session.getMapper(StudentMapper.class);
        Student student = mapper.getStudent(id);
        if (student != null) {
            List<Score> scores = mapper.getScoresByStuId(student.getId());
            student.setScores(scores);
        }
        return student;
    } finally {
        session.close();
    }
}

五、Mybatis一对多映射注解

Mybatis也支持使用注解来完成一对多映射的配置。需要使用@Results和@ResultMap注解来完成实体类与数据库表之间的映射关系的定义。同时,使用@One和@Many注解来表示一对多映射关系的定义。


public interface StudentMapper {
     @Results(id="studentMap", value={
          @Result(property="id", column="id"),
          @Result(property="name", column="name"),
          @Result(property="scores", column="id", 
               many=@Many(select="com.example.ScoreMapper.getScoresByStuId"))
     })
     public Student getStudentWithScores(int id);
}

public interface ScoreMapper {
     @Select("SELECT id, stu_id, subject, score FROM score WHERE stu_id=#{stuId}")
     public List<Score> getScoresByStuId(int stuId);
}

六、Mybatis多对多映射

多对多映射指的是两个实体类之间互相包含集合的关系。Mybatis中可以使用嵌套查询或嵌套结果来实现多对多映射。具体实现思路与一对多映射类似,只是需要分别为两个实体类定义对应的resultMap。

七、Mybatis一对多映射为空

如果实体类A中的集合属性对应的实体类B在数据库表中没有对应数据,使用Mybatis进行一对多映射时,实体类A的集合属性值将为空。

八、Mybatis一对多查询

在Mybatis中,一对多查询指的是单独查询出实体类A对应的数据以及实体类B对应的数据,而不是通过嵌套查询或嵌套结果来实现。这种方式不涉及到一对多映射关系的定义,在查找的时候也需要进行多次查询。具体步骤如下:

1、在映射文件中分别定义实体类A和实体类B的resultMap

2、编写SQL语句,查询出实体类A和实体类B的数据,并在Mybatis配置文件中定义对应的映射关系。例如:



3、调用Mapper接口的方法来查询结果。具体代码示例可参考第二部分中的实现。

九、Mybatis一对多查询语句

一对多查询语句指的是查询出实体类A对应的所有数据,以及实体类B对应的所有数据,并将两个结果集合并起来。这种方式不需要定义一对多映射关系,但需要对结果集进行特殊处理。具体步骤如下:

1、编写SQL语句,查询出实体类A和实体类B的数据。例如:


SELECT s.id, s.name, sc.id, sc.stu_id, sc.subject, sc.score 
 FROM student s 
 LEFT JOIN score sc ON s.id = sc.stu_id

2、在Mybatis的接口中定义方法,并使用@ResultMap注解标注在映射文件中定义的resultMap。例如:


public interface StudentMapper {
     @Select({
         "SELECT s.id, s.name, sc.id, sc.stu_id, sc.subject, sc.score",
         "FROM student s LEFT JOIN score sc ON s.id = sc.stu_id"
     })
     @ResultMap("studentMap")
     public List<Student> getStudentWithScores();
}

3、调用Mapper接口的方法来查询结果。具体代码示例可参考第二部分中的实现。