Mybatis的多對一和一對多
1.Lombok
首先我們來看下Lombok,百度搜以下Lombok,找到官網:https://projectlombok.org/
官網有這么一句話:
Project Lombok is a java library that automatically plugs into your editor and build tools, spicing up your java.
Never write another getter or equals method again, with one annotation your class has a fully featured builder, Automate your logging variables, and much more.
使用步驟:
1.在IDEA中安裝Lombok插件!

2.在專案中匯入lombok的jar包
直接去maven倉庫官網搜 Lombok maven
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.20</version>
<scope>provided</scope>
</dependency>
3.在物體類上加注解即可
Lombok有以下的注解可供使用:
@Getter and @Setter
@FieldNameConstants
@ToString
@EqualsAndHashCode
@AllArgsConstructor, @RequiredArgsConstructor and @NoArgsConstructor
@Log, @Log4j, @Log4j2, @Slf4j, @XSlf4j, @CommonsLog, @JBossLog, @Flogger, @CustomLog
@Data
@Builder
@SuperBuilder
@Singular
@Delegate
@Value
@Accessors
@Wither
@With
@SneakyThrows
@val
@var
說明:
@Data: 無參構造、getter、setter、toString、hashcode、equals
@AllArgsConstructor:有參構造
@NoArgsConstructor:無參構造
@ToString:生成toString方法
@EqualsAndHashCode:生成equeals和hashcode方法
2.多對一處理
多對一

- 多個學生,對應一個老師
- 對于學生這邊而言,和老師存在關聯關系,多個學生關聯一個老師【多對一】
- 對于老師而言,和學生存在集合關系,一個老師有很對學生【一對多】
搭建復雜環境用的SQL:
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.匯入Lombok
2.新建物體類Teacher、Student
3.建立Mapper介面
4.建立Mapper.xml檔案
5.在核心組態檔中系結注冊我們的mapper介面或者檔案
6.測驗查詢是否能夠成功
以上不走不用多說,前面搭建過很多次
這里主要注意一點:mapper介面檔案放在src/main/java的某個目錄(com/kuang/dao)下面和mapper.xml檔案放在src/main/resource的對應目錄下面,在打包后都會被打包到classpath下面,也就是classes目錄下面,并且會被合并到同一目錄下(因為目錄都是com/kuang/dao),如圖:

現在我們來寫一下多對一
按照查詢嵌套處理
<!--
思路:
1.查詢所有的學生資訊
2.根據查詢出來的學生的tid,尋找對應的老師!
-->
<resultMap id="StudentTeacher" type="Student">
<result property="id" column="id"/>
<result property="name" column="name"/>
<!--復雜的屬性,我們需要單獨處理
物件:association
集合:collection
-->
<association property="teacher" column="tid" javaType="Teacher" select="getTeacher"/>
</resultMap>
<select id="getStudent" resultMap="StudentTeacher">
select * from student;
</select>
<select id="getTeacher" resultType="Teacher">
select * from teacher where id = #{id}
</select>

按照結果嵌套查詢
<!--按照結果嵌套處理-->
<select id="getStudent2" 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">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<association property="teacher" javaType="Teacher">
<result property="name" column="tname"/>
</association>
</resultMap>

回顧Mysql多對一查詢方式:
- 子查詢: 相當于按照查詢嵌套處理
- 聯表查詢:相當于按照結果嵌套處理
3.一對多處理
比如:一個老師擁有多個學生!
對于老師而言,就是一對多的關系!
1.環境搭建
環境搭建和剛才一樣
物體類
@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;
}
按照結果嵌套處理
就是相當于復雜sql寫完了,本身資料查詢出來就是一個集合的形式,最終我們要封裝成一個物體類Teacher的形式,但是屬性名和sql查出來的欄位名不一致,用collection標簽做如下處理即可:
<!--按結果嵌套查詢-->
<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=#{tid}
</select>
<resultMap id="TeacherStudent" type="Teacher">
<result property="id" column="tid"/>
<result property="name" column="tname"/>
<!--
復雜型別我們需要單獨處理:
物件:association
集合:collection
javaType="" 指定屬性的型別
集合中的泛型資訊,我們使用ofType獲取
-->
<collection property="students" ofType="Student">
<result property="id" column="sid"/>
<result property="name" column="sname"/>
<result property="tid" column="tid"/>
</collection>
</resultMap>

按照查詢嵌套處理
按照查詢嵌套處理的話:這是另一種思路,就是先查老師,由于第一個sql只查出了老師的id和name,需要用collection標簽用如下方法將老師的id傳給下面另一個sql陳述句,就能夠查詢改老師下所有的學生并封裝到物體類list集合當中,
這里須注意如果resultMap中不加
<!--按照查詢嵌套處理-->
<select id="getTeacher2" resultMap="TeacherStudent2">
select * from teacher where id=#{tid}
</select>
<resultMap id="TeacherStudent2" type="Teacher">
<result property="id" column="id"/>
<collection property="students" javaType="ArrayList" ofType="Student"
select="getStudentByTeacherId" column="id"/>
</resultMap>
<select id="getStudentByTeacherId" resultType="Student">
select * from student where tid=#{id}
</select>

4.小結
1.關聯 - association 【多對一】
2.集合 - collection 【一對多】
3.javaType :用來指定物體類中屬性的型別,ofType:用來指定映射到list或者集合中的pojo型別,泛型中的約束型別!
綜合:無論是多對一還是一對多,都建議使用按結果嵌套處理的方式來做,因為出了問題,按查詢嵌套處理并不好除錯!(想想,按結果嵌套處理的方式還可以除錯下sql,但按查詢嵌套處理怎么調呢?)
注意點:
- 保證SQL的可讀性,盡量保證通俗易懂
- 注意一對多和多對一中,屬性名和欄位的問題!
- 如果問題不好排查錯誤,可以使用日志!
這篇文章的原始碼在Mybatis-study工程的mybatis-06和mybatis-07模塊下!,后面會給出碼云地址,
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/282217.html
標籤:Java
