Mybatis3.5 教学笔记-3 一对多和多对一的实现

  • Post author:
  • Post category:其他


班级和学生是一对多(一个班级有多个学生),学生和班级是多对一(多个学生属于一个班级)。

多对一配置:(在多方中配置一个单方对象),一对多配置(在单方中配置一个多方的集合,页面需要嵌套循环获取数据!)

多对一和一对多的实现有多种实现方式:

1:通过DTO对象和表连接实现(不推荐,不方便进行管理、维护不方便)

2:通过resultMap配置级联关系

3:通过@Results 注解(无需xml文件)

先看一下多对一(resultMap)的实现:

实体类:

@Data
@Accessors(chain = true)
public class Student implements Serializable {
    private Integer sid;
    private String name;
    private Room room;//多对一:多方中配置一个单方的对象
}

@Data
@Accessors(chain = true)
public class Room implements java.io.Serializable {
    private Integer rid;
    private String rname;
}

接口:

public interface StudentMapper {

    @Select("select * from t_student")
    @ResultMap("stuMap")
    List<Student> findStudents();
    
    @Select("select * from t_room")
    List<Room> rooms();


    @Select("select * from t_room where rid=#{rid}")
    Room findRoomById(int rid);

    @Insert("insert into t_student(name,rid) values ( #{name},#{room.rid} )")
    int addStudent(Student student);


    //统计学生人数
    @Select("SELECT count(sid) from t_student")
    int findCounts();
}

sql映射文件:

<mapper namespace="com.song.mybatis.mapper.StudentMapper">
    
    <resultMap id="stuMap" type="com.song.mybatis.pojo.Student">
    <id property="sid" column="sid"/>
      <!---多对一-->
    <association property="room" javaType="com.song.mybatis.pojo.Room" column="rid" select="findRoomById">
        <id property="rid" column="rid"/>
    </association>
</resultMap>
    
</mapper>
public class AppTest {

    private SqlSession sqlSession;
    private StudentMapper studentMapper;
    @Before
    public void shouldAnswerWithTrue() {
        sqlSession= MybatisUtil.getSession();
        studentMapper= sqlSession.getMapper(StudentMapper.class);
    }
    @Test
    public void testList(){
        System.out.println("执行了第一次查询");
        List<Student> students1 = this.studentMapper.findStudents();
        System.out.println("执行了第二次查询");
        List<Student> students2 = this.studentMapper.findStudents();
        System.out.println("执行了第三次查询");
        List<Student> students3 = this.studentMapper.findStudents();
    }

 @Test
    public void testAdd(){
        //创建对象对象
        Student student=new Student();
        student.setName("孙丽丽");
        //指定班级: 模拟从下拉框获取值:rid
        Room room = this.studentMapper.findRoomById(2);
        student.setRoom(room);
        //完成添加
        int m = this.studentMapper.addStudent(student);
        if(m==1){
            this.sqlSession.commit();
        }
    }
}

再看一下通过@Results实现:(无需xml文件)

RoomMapper: 负责根据rid查询指定的班级

public interface RoomMapper {

       @Select("select * from t_room where rid=#{rid}")
       Room selectRoomById(int rid);
}

StudentMapper: 查询所有学生:

public interface StudentMapper {


    @Select("select * from t_student")
    @Results({
            @Result(column = "sid", property = "sid"),
            @Result(column = "sname", property = "sname"),
            @Result(
                    column = "rid",property ="room",javaType =Room.class,
                    one = @One(select ="com.song.mybatis.mapper.RoomMapper.selectRoomById")
            )
    })
    List<Student> getStudentList();

以上的@Results分别定义了Student的属性和表的字段的映射,one=@One(select…..)用于根据每个学生的班级外键rid关联查询(调用RoomMapper的selectRoomById方法执行查询),

测试:

    @Test
    public void testsss(){
        studentMapper.getStudentList().forEach(student->{
            System.out.println(student);
        });
    }
}

结果如下:

一对多

实体类:

@Data
@Accessors(chain = true)
public class Room {
    private Integer rid;
    private String rname;
    //单方(班级)中配置一个多方(学生)的集合
    private List<Student> students=new ArrayList<>();
}
@Data
@Accessors(chain = true)
public class Student {

    private Integer sid;
    private String name;
    private Integer rid;

}

resultMap的实现方式:

mapper.xml

<mapper namespace="com.song.ssm.mapper.StudentMapper">

      <resultMap id="roomMap" type="com.song.ssm.pojo.Room">
           <id property="rid" column="rid"/>

          <!--一对多:配置集合-->
          <collection property="students" ofType="com.song.ssm.pojo.Student" column="rid" select="findStudentByRid">
                <id property="sid" column="sid"/>
          </collection>
      </resultMap>

</mapper>

接口:

public interface StudentMapper {

    @Select("select * from t_room")
    @ResultMap("roomMap")
    List<Room> findAllRooms();

    @Select("select * from t_student where rid=#{rid}")
    List<Student> findStudentByRid(int rid);

    @Insert("insert into  t_student(name,rid) values(#{name},#{rid})")
    int addStudent(Student student);
}

@Results的实现方式(无需xml文件)

RoomMapper.java

public interface RoomMapper {

     @Select("select * from t_room")
     @Results({
             @Result(column = "rid",property = "rid"),
             @Result(column = "rname",property = "rname"),
             @Result(column = "rid",property ="students",javaType =List.class,
               many = @Many(select = "com.song.ssm.mapper.StudentMapper.findStudentByRid")
             )
     })
     List<Room> selectRoomList();
}

StudentMapper.java

public interface StudentMapper {
    
    @Select("select * from t_student where rid=#{rid}")
    List<Student> findStudentByRid(int rid);

    @Insert("insert into  t_student(name,rid) values(#{name},#{rid})")
    int addStudent(Student student); 
}

测试:

public class AppTest {
    @Test
    public void test(){
        RoomMapper roomMapper = MybatisUtil.getSession().getMapper(RoomMapper.class);
        roomMapper.selectRoomList().forEach(room -> {
            System.out.println(room);
        });
    }
}

输出:



版权声明:本文为tonysong111073原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。