阅读本博文需要有基础的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 的属性 ,这是慕课老师的解答印证了我的观点
原文:https://www.cnblogs.com/dypcd/p/12228412.html