mybatis一對多&&多對一處理

啊~小 l i發表於2020-10-31

多對一的處理

多對一的理解:

  • 多個學生對應一個老師
  • 如果對於學生這邊,就是一個多對一的現象,即從學生這邊關聯一個老師!

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`) VALUES (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. 搭建測試環境
    1. IDEA安裝Lombok外掛
    2. 引入Maven依賴
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
 <groupId>org.projectlombok</groupId>
 <artifactId>lombok</artifactId>
 <version>1.18.12</version>
</dependency>

3. 在程式碼中增加註解在程式碼中增加註解
@Data //GET,SET,ToString,有參,無參構造
public class Teacher {
   private int id;
   private String name;
}
@Data
public class Student {
   private int id;
   private String name;
   //多個學生可以是同一個老師,即多對一
   private Teacher teacher;
}
  1. 編寫實體類對應的Mapper介面 【兩個】
public interface StudentMapper {
}

public interface TeacherMapper {
}
  1. 編寫Mapper介面對應的 mapper.xml配置檔案 【兩個】
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.mapper.StudentMapper">

</mapper>
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.mapper.TeacherMapper">

</mapper>

按查詢巢狀處理

1、給StudentMapper介面增加方法
public List<Student> getStudents();
2、編寫對應的Mapper檔案

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE mapper
       PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
       "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.kuang.mapper.StudentMapper">

   <!--
   需求:獲取所有學生及對應老師的資訊
   思路:
       1. 獲取所有學生的資訊
       2. 根據獲取的學生資訊的老師ID->獲取該老師的資訊
       3. 思考問題,這樣學生的結果集中應該包含老師,該如何處理呢,資料庫中我們一般使用關聯查詢?
           1. 做一個結果集對映:StudentTeacher
           2. StudentTeacher結果集的型別為 Student
           3. 學生中老師的屬性為teacher,對應資料庫中為tid。
              多個 [1,...)學生關聯一個老師=> 一對一,一對多
           4. 檢視官網找到:association – 一個複雜型別的關聯;使用它來處理關聯查詢
   -->
   <select id="getStudents" resultMap="StudentTeacher">
    select * from student
   </select>
   <resultMap id="StudentTeacher" type="Student">
       <!--association關聯屬性 property屬性名 javaType屬性型別 column在多的一方的表中的列名-->
       <association property="teacher"  column="tid" javaType="Teacher" select="getTeacher"/>
   </resultMap>
   <!--
   這裡傳遞過來的id,只有一個屬性的時候,下面可以寫任何值
   association中column多引數配置:
       column="{key=value,key=value}"
       其實就是鍵值對的形式,key是傳給下個sql的取值名稱,value是片段一中sql查詢的欄位名。
   -->
   <select id="getTeacher" resultType="teacher">
      select * from teacher where id = #{id}
   </select>

</mapper>

編寫完畢去Mybatis配置檔案中,註冊Mapper!
注意點

<resultMap id="StudentTeacher" type="Student">
   <!--association關聯屬性 property屬性名 javaType屬性型別 column在多的一方的表中的列名-->
   <association property="teacher"  column="{id=tid,name=tid}" javaType="Teacher" select="getTeacher"/>
</resultMap>
<!--
這裡傳遞過來的id,只有一個屬性的時候,下面可以寫任何值
association中column多引數配置:
   column="{key=value,key=value}"
   其實就是鍵值對的形式,key是傳給下個sql的取值名稱,value是片段一中sql查詢的欄位名。
-->
<select id="getTeacher" resultType="teacher">
  select * from teacher where id = #{id} and name = #{name}
</select>

測試

@Test
public void testGetStudents(){
   SqlSession session = MybatisUtils.getSession();
   StudentMapper mapper = session.getMapper(StudentMapper.class);

   List<Student> students = mapper.getStudents();

   for (Student student : students){
       System.out.println(
               "學生名:"+ student.getName()
                       +"\t老師:"+student.getTeacher().getName());
  }
}

按結果巢狀處理

1、介面方法編寫
public List<Student> getStudents2();
2、編寫對應的mapper檔案

<!--
按查詢結果巢狀處理
思路:
   1. 直接查詢出結果,進行結果集的對映
-->
<select id="getStudents2" resultMap="StudentTeacher2" >
  select s.id sid, s.name sname , t.name tname
  from student s,teacher t
  where s.tid = t.id
</select>

<resultMap id="StudentTeacher2" type="Student">
   <id property="id" column="sid"/>
   <result property="name" column="sname"/>
   <!--關聯物件property 關聯物件在Student實體類中的屬性-->
   <association property="teacher" javaType="Teacher">
       <result property="name" column="tname"/>
   </association>
</resultMap>

測試

@Test
public void testGetStudents(){
   SqlSession session = MybatisUtils.getSession();
   StudentMapper mapper = session.getMapper(StudentMapper.class);

   List<Student> students = mapper.getStudents();

   for (Student student : students){
       System.out.println(
               "學生名:"+ student.getName()
                       +"\t老師:"+student.getTeacher().getName());
  }
}

一對多處理

一對多的理解:

  • 一個老師擁有多個學生
  • 如果對於老師這邊,就是一個一對多的現象,即從一個老師下面擁有一群學生(集合)!

實體類編寫

@Data
public class Student {
   private int id;
   private String name;
   private int tid;
}


@Data 
public class Teacher {
   private int id;
   private String name;
   //一個老師多個學生
   private List<Student> students;
}

… 和之前一樣,搭建測試的環境!

按結果巢狀處理

1、 TeacherMapper介面編寫方法
public Teacher getTeacher(int id);
2、編寫介面對應的Mapper配置檔案

<mapper namespace="com.kuang.mapper.TeacherMapper">

   <!--
   思路:
       1. 從學生表和老師表中查出學生id,學生姓名,老師姓名
       2. 對查詢出來的操作做結果集對映
           1. 集合的話,使用collection!
               JavaType和ofType都是用來指定物件型別的
               JavaType是用來指定pojo中屬性的型別
               ofType指定的是對映到list集合屬性中pojo的型別。
   -->
   <select id="getTeacher" resultMap="TeacherStudent">
      select s.id sid, s.name sname , t.name tname, t.id tid
      from student s,teacher t
      where s.tid = t.id and t.id=#{id}
   </select>

   <resultMap id="TeacherStudent" type="Teacher">
       <result  property="name" column="tname"/>
       <collection property="students" ofType="Student">
           <result property="id" column="sid" />
           <result property="name" column="sname" />
           <result property="tid" column="tid" />
       </collection>
   </resultMap>
</mapper>

3、將Mapper檔案註冊到MyBatis-config檔案中

<mappers>
   <mapper resource="mapper/TeacherMapper.xml"/>
</mappers>

4、測試

@Test
public void testGetTeacher(){
   SqlSession session = MybatisUtils.getSession();
   TeacherMapper mapper = session.getMapper(TeacherMapper.class);
   Teacher teacher = mapper.getTeacher(1);
   System.out.println(teacher.getName());
   System.out.println(teacher.getStudents());
}

按查詢巢狀處理

1、TeacherMapper介面編寫方法
public Teacher getTeacher2(int id);
2、編寫介面對應的Mapper配置檔案

<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id = #{id}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
   <!--column是一對多的外來鍵 , 寫的是一的主鍵的列名-->
   <collection property="students" javaType="ArrayList" ofType="Student" column="id" select="getStudentByTeacherId"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
  select * from student where tid = #{id}
</select>

3、將Mapper檔案註冊到MyBatis-config檔案中
4、測試

@Test
public void testGetTeacher2(){
   SqlSession session = MybatisUtils.getSession();
   TeacherMapper mapper = session.getMapper(TeacherMapper.class);
   Teacher teacher = mapper.getTeacher2(1);
   System.out.println(teacher.getName());
   System.out.println(teacher.getStudents());
}

相關文章