班级和学生是一对多(一个班级有多个学生),学生和班级是多对一(多个学生属于一个班级)。
多对一配置:(在多方中配置一个单方对象),一对多配置(在单方中配置一个多方的集合,页面需要嵌套循环获取数据!)
多对一和一对多的实现有多种实现方式:
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);
});
}
}
输出: