閱讀本博文需要有基礎的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 的屬性 ,這是慕課老師的解答印證了我的觀點