mybatis plus 一對多,多表聯查的使用小記


閱讀本博文需要有基礎的mybatis以及mybatis plus知識,如果沒有建議您了解相關的內容

本項目使用的是springboot構建的,數據庫字段命名不嚴謹僅做演示測試使用,本文不做相關源碼的解析只做功能使用講解

相對於mybatis來說 plus用起來真的很舒服,單表查詢crud,以及分頁功能真的如絲般順滑,使用方法就不再一一贅述獻丑了,因為查詢了很多資料各種方法都有甚至可以使用注解來進行查詢,但是我認為這樣不便於管理,因此沒有找到對我有用的相關連表,關聯查詢的方法,所以自己只能退而求次用mybatis的原始方法來做連表查詢僅供參考,如果您有更好的特別歡迎您分享。

本篇文章講的是如何來做一對多關系的查詢,使用的是xml來配置相關查詢語句。

我們單表查詢的時候BaseMapper<T>基本的功能都實現了,同時mybatis plus的條件構造器QueryWrapper 可以幫助我們構建各種條件,如果特別復雜那就得手寫了。

以學生,老師為例老師對學生為一對多,學生對老師也是一對多(這里只做老師的例子)

我的實體實現了Serializable接口這個看你個人的需求,在這里我重寫了toString 方法,目的是做測試打印的,實際開發當中作為一個有工作經驗的coder來說肯定知道不要重寫tostring 

老師實體的第4行代碼代碼我注釋了,具體原因后續會講。

 1 @TableName(value = "sys_teacher")
 2 public class Teacher  implements Serializable {
 3     @TableId(value = "pk_id" ,type = IdType.AUTO)
 4 //    @TableField(value = "pk_id")
 5     private long id;
 6     @TableField(value = "t_name")
 7     private String name;
 8     private String sex;
 9     private String  position;
10     @TableField(exist = false)
11     private List<Student>  studentList;
12 
13 
14     public Teacher() {
15     }
16 
17     public long getId() {
18         return id;
19     }
20 
21     public void setId(long id) {
22         this.id = id;
23     }
24 
25     public String getName() {
26         return name;
27     }
28 
29     public void setName(String name) {
30         this.name = name;
31     }
32 
33     public String getSex() {
34         return sex;
35     }
36 
37     public void setSex(String sex) {
38         this.sex = sex;
39     }
40 
41     public String getPosition() {
42         return position;
43     }
44 
45     public void setPosition(String position) {
46         this.position = position;
47     }
48 
49     @Override
50     public String toString() {
51         return "Teacher{" +
52                 "id=" + id +
53                 ", name='" + name + '\'' +
54                 ", sex='" + sex + '\'' +
55                 ", position='" + position + '\'' +
56                 ", studentList=" + studentList +
57                 '}';
58     }
59 }

 

學生實體

 1 @TableName(value = "sys_student")
 2 public class Student  implements Serializable {
 3     @TableId(type = IdType.AUTO)
 4     private long id;
 5 
 6     private String name;
 7     private String sex;
 8     @TableField(value = "class_no")
 9     private String classNo;
10     private int grade;
11 
12     public Student() {
13     }
14 
15     public int getGrade() {
16         return grade;
17     }
18 
19     public void setGrade(int grade) {
20         this.grade = grade;
21     }
22 
23     public long getId() {
24         return id;
25     }
26 
27     public void setId(long id) {
28         this.id = id;
29     }
30 
31     public String getName() {
32         return name;
33     }
34 
35     public void setName(String name) {
36         this.name = name;
37     }
38 
39     public String getSex() {
40         return sex;
41     }
42 
43     public void setSex(String sex) {
44         this.sex = sex;
45     }
46 
47     public String getClassNo() {
48         return classNo;
49     }
50 
51     public void setClassNo(String classNo) {
52         this.classNo = classNo;
53     }
54 
55     @Override
56     public String toString() {
57         return "Student{" +
58                 "id=" + id +
59                 ", name='" + name + '\'' +
60                 ", sex='" + sex + '\'' +
61                 ", classNo='" + classNo + '\'' +
62                 ", grade=" + grade +
63                 '}';
64     }
65 }

數據庫截圖

 

 

老師表

 

 

 

學生表

 

 

 

中間表

 

 

 

 

在這里我們需要查詢老師多對應的學生列表,因為數據庫字段里面不包含學生,如果單獨查詢老師我使用了@TableField(exist = false) 不讓屬性名作為數據庫字段查詢,否則映射會出錯

具體錯誤我就 不再演示了,下面是.xml的配置以教師的xml來舉栗子,大家可以看到,這里的配置其實和mybatis一樣,如果使用xml配置,字段名和屬性名一致可以 不做配置,如果不一樣那么就必須做關系映射

 1 <?xml version="1.0" encoding="UTF-8" ?>
 2 <!DOCTYPE mapper
 3         PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN"
 4         "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
 5 <mapper namespace="com.ls.springboot.mp.mapper.ITeacherMapper">
 6     <resultMap id="teacherRM" type="Teacher">
 7         <id property="id" column="pk_id"/>
 8         <!--<result property="name" column="name"/>
 9         <result property="sex" column="sex"/>
10         <result property="position" column="position"/>-->
11 
12         <collection property="studentList" column="pk_id" select="findStudentListById"></collection>
13     </resultMap>
14     這是關聯查詢的sql和mybatis一樣
15     <select id="findInfo" resultMap="teacherRM">
16 
17           select * from sys_teacher
18 </select>
19     <select id="findStudentListById"  parameterType="int" resultType="Student">
20 
21           SELECT s.* from  sys_teacher_student m   LEFT JOIN sys_student s
22 on s.id=m.student_id WHERE m.teacher_id=#{id}
23 </select>
24 </mapper>

這里和mybatis的查詢方式一樣,8-10行注釋的地方表示可以省略,如果實體的屬性名和數據庫表的字段不一致那么在xml里面就不能省略否則出現無法映射的情況

例如在xml未做name的映射則會出現這樣的情況

 

 而加上

<result property="name" column="t_name"/>
則會完成映射,我們使用單表查詢的時候是不用考慮映射的情況plus會自動去映射

 

 

 至於為什么要在xml里配置 <id property="id" column="pk_id"/>,因為如果不做配置的話 做連表查詢的時候會將id傳給studentList,而實體本身就不能獲取到id了

1 <!--<id property="id" column="pk_id"/>-->
2 注釋掉之后 查看結果

 

 

 如果恢復的話則可以完全查出相應的內容

 

 

3     @TableId(value = "pk_id" ,type = IdType.AUTO)
 4 //    @TableField(value = "pk_id")
由於我沒有仔細去閱讀相關文檔,在做主鍵的字段映射的時候以為TableId 和 TableField 可以同時使用,
結果在后續的測試當中發現兩者不能同時使用,即使使用之后TableField 也不會起作用,因為@TableId提供了value 的屬性 ,這是慕課老師的解答印證了我的觀點


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM