Mapper.xml中查询返回带有List属性的实体类结果问题
作者:cxy1109
刚入职公司,参与到一个项目中,由于是刚毕业的菜鸟,只能分配写一些查询的接口代码。
其中有一个就是需要返回一个实体类的信息,该实体类带有List属性,返回的结果类似于下图。
我的解决办法是将查询分成两步,第一步是查询到对应的表的实体类结果,第二部查询到一个List集合然后将这个集合通过set方法复制给实体类。
后来看了同事的代码豁然开朗,这里用学生的信息模拟一下。
1.建立学生关系表
建了五张表,分别是school(学院)class(班级)student(班级)course(课程)stu_course(学生选课表),表结构如下
学院表
班级表
学生表
课程表
学生选课表
班级表通过school_id与学院表关联,学生表通过class_id与班级表关联,学生选课表关联学生表和课程表。
2.建立springboot项目
在STS中新建springboot项目,application.properties配置如下
pom.xml文件如下
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.1.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.cheng</groupId> <artifactId>testspringboot</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>war</packaging> <name>testspringboot</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <!-- <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-tomcat</artifactId> <scope>provided</scope> </dependency> --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>org.apache.tomcat.embed</groupId> <artifactId>tomcat-embed-jasper</artifactId> <scope>provided</scope> </dependency> <dependency> <groupId>javax.servlet</groupId> <artifactId>jstl</artifactId> <scope>provided</scope> </dependency> <!-- https://mvnrepository.com/artifact/com.alibaba/druid-spring-boot-starter --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus-boot-starter --> <!-- <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus-boot-starter</artifactId> <version>3.1.0</version> </dependency> --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatisplus-spring-boot-starter</artifactId> <version>1.0.5</version> </dependency> <!-- https://mvnrepository.com/artifact/com.baomidou/mybatis-plus --> <dependency> <groupId>com.baomidou</groupId> <artifactId>mybatis-plus</artifactId> <version>2.3</version> </dependency> <!--MySQL --> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> </dependency> <dependency> <groupId>org.apache.velocity</groupId> <artifactId>velocity</artifactId> <version>1.7</version> </dependency> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.20</version> </dependency> <!-- lombok需要的jar包 --> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
项目建好后使用mybatis plus自动生成实体类service和controller以及Mapper,生成好的如下图。
并创建要返回的学生详细信息的实体类StudentDto,该实体类包含List类型的学生选课的课程信息
package com.example.chapter3.dto; import java.io.Serializable; import java.util.List; import com.baomidou.mybatisplus.activerecord.Model; import com.example.chapter3.model.Course; public class StudentDto extends Model<StudentDto>{ private static final long serialVersionUID = 1L; /** * 学生ID */ private String studentId; /** * 学生姓名 */ private String studentName; /** * 学生年龄 */ private Integer studentAge; /** * 学生性别 */ private String studentSex; /** * 学校ID */ private String schoolId; /** * 班级ID */ private String classId; private String shcoolName; private String className; private List<Course> courses; @Override protected Serializable pkVal() { // TODO Auto-generated method stub return studentId; } public String getStudentId() { return studentId; } public void setStudentId(String studentId) { this.studentId = studentId; } public String getStudentName() { return studentName; } public void setStudentName(String studentName) { this.studentName = studentName; } public Integer getStudentAge() { return studentAge; } public void setStudentAge(Integer studentAge) { this.studentAge = studentAge; } public String getStudentSex() { return studentSex; } public void setStudentSex(String studentSex) { this.studentSex = studentSex; } public String getSchoolId() { return schoolId; } public void setSchoolId(String schoolId) { this.schoolId = schoolId; } public String getClassId() { return classId; } public void setClassId(String classId) { this.classId = classId; } public String getShcoolName() { return shcoolName; } public void setShcoolName(String shcoolName) { this.shcoolName = shcoolName; } public String getClassName() { return className; } public void setClassName(String className) { this.className = className; } public List<Course> getCourses() { return courses; } public void setCourses(List<Course> courses) { this.courses = courses; } public static long getSerialversionuid() { return serialVersionUID; } @Override public String toString() { return "StudentDto [studentId=" + studentId + ", studentName=" + studentName + ", studentAge=" + studentAge + ", studentSex=" + studentSex + ", schoolId=" + schoolId + ", classId=" + classId + ", shcoolName=" + shcoolName + ", className=" + className + ", courses=" + courses + "]"; } }
3.编写要查询的studentMapper.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.example.chapter3.mapper.StudentMapper"> <!-- 通用查询映射结果 --> <resultMap id="BaseResultMap" type="com.example.chapter3.model.Student"> <id column="student_id" property="studentId" /> <result column="student_name" property="studentName" /> <result column="student_age" property="studentAge" /> <result column="student_sex" property="studentSex" /> <result column="school_id" property="schoolId" /> <result column="class_id" property="classId" /> </resultMap> <!-- 通用查询结果列 --> <sql id="Base_Column_List"> student_id, student_name, student_age, student_sex, school_id, class_id </sql> <resultMap type="com.example.chapter3.dto.StudentDto" id="stuDtoResultMap"> <id column="student_id" property="studentId" /> <result column="student_name" property="studentName" /> <result column="student_age" property="studentAge" /> <result column="student_sex" property="studentSex" /> <result column="school_id" property="schoolId" /> <result column="class_id" property="classId" /> <result column="shcool_name" property="shcoolName" /> <result column="class_name" property="className" /> <collection property="courses" ofType="com.example.chapter3.model.Course" column="student_id" select="com.example.chapter3.mapper.CourseMapper.selectCourseByStuId"> </collection> </resultMap> <select id="selectStudentDetails" resultMap="stuDtoResultMap"> SELECT sc.school_name, sc.school_id, sc.adress, cl.class_id, cl.class_name, stu.student_id, stu.student_name, stu.student_age, stu.student_sex FROM school sc LEFT JOIN class cl ON sc.school_id = cl.school_id LEFT JOIN student stu ON stu.class_id = cl.class_id WHERE stu.student_id = #{studentId} </select> </mapper>
其对应的StudentMapper.class文件如下
该Mapper有一个查询学生信息的方法对应studentMapper.xml里的selectStudentDetails。
通过联合查询返回stuDtoResultMap,这是个resulMap类型,type="com.example.chapter3.dto.StudentDto"是学生的详细信息实体类,其中的
<collection property="courses" ofType="com.example.chapter3.model.Course" column="student_id" select="com.example.chapter3.mapper.CourseMapper.selectCourseByStuId"> </collection>
表示的是StudentDto的List集合,返回的是List<Course>,property是StudentDto类中的集合属性名,也就是courses,ofType是集合中的类型,是Course, column是查询传递的参数,select是要查询的语句,同一个Mapper直接使用id,不同Mapper使用查询方法的全类名,这里把student_id作为参数传递给Course表的查询函数selectCourseByStuId。
CourseMapper如下。
其对应的Mapper文件如下
4.查询学生详细信息的service和controller
5.测试
访问请求localhost:8081/student/studentDetails/st001得到结果如下
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。