Mapper.xml中查询返回带有List属性的实体类结果问题

 更新时间:2023年06月26日 16:09:00   作者:cxy1109  
这篇文章主要介绍了Mapper.xml中查询返回带有List属性的实体类结果问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

刚入职公司,参与到一个项目中,由于是刚毕业的菜鸟,只能分配写一些查询的接口代码。

其中有一个就是需要返回一个实体类的信息,该实体类带有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得到结果如下

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

相关文章

  • 解决@Scheduled定时器使用@Thransactional事物问题

    解决@Scheduled定时器使用@Thransactional事物问题

    这篇文章主要介绍了解决@Scheduled定时器使用@Thransactional事物问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-08-08
  • 关于重写equals()方法和hashCode()方法及其简单的应用

    关于重写equals()方法和hashCode()方法及其简单的应用

    这篇文章主要介绍了关于重写equals()方法和hashCode()方法及其简单的应用,网上的知识有些可能是错误的,关于 equals() 方法的理解,大家讨论不一样,需要的朋友可以参考下
    2023-04-04
  • 在Java中如何比较两个对象浅析

    在Java中如何比较两个对象浅析

    在工作中我们经常会遇到这样的需求——比较两个对象是否相等,如果不相等的话,取出不相等的字段,这篇文章主要给大家介绍了关于在Java中如何比较两个对象的相关资料,需要的朋友可以参考下
    2021-11-11
  • mybatis-plus id主键生成的坑

    mybatis-plus id主键生成的坑

    这篇文章主要介绍了mybatis-plus id主键生成的坑,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2020-08-08
  • ThreadPoolExecutor参数含义及源码执行流程详解

    ThreadPoolExecutor参数含义及源码执行流程详解

    这篇文章主要为大家介绍了ThreadPoolExecutor参数含义及源码执行流程详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-11-11
  • Java毕业设计实战之在线网盘系统的实现

    Java毕业设计实战之在线网盘系统的实现

    这是一个使用了java+JSP+Springboot+maven+mysql+ThymeLeaf+FTP开发的在线网盘系统,是一个毕业设计的实战练习,具有网盘该有的所有功能,感兴趣的朋友快来看看吧
    2022-01-01
  • Java如何实现双向链表功能

    Java如何实现双向链表功能

    双向链表也叫双链表,是链表的一种,它的每个数据结点中都有两个指针,分别指向直接后继和直接前驱。所以,从双向链表中的任意一个结点开始,都可以很方便地访问它的前驱结点和后继结点。一般我们都构造双向循环链表
    2021-11-11
  • SpringBoot之@ConditionalOnProperty注解使用方法

    SpringBoot之@ConditionalOnProperty注解使用方法

    在平时业务中,我们需要在配置文件中配置某个属性来决定是否需要将某些类进行注入,让Spring进行管理,而@ConditionalOnProperty能够实现该功能,文中有详细的代码示例,需要的朋友可以参考下
    2023-05-05
  • Java设计模式之桥接模式

    Java设计模式之桥接模式

    这篇文章介绍了Java设计模式之桥接模式,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-09-09
  • 分析Java中的类加载问题

    分析Java中的类加载问题

    很多时候提到类加载,大家总是没法马上回忆起顺序,这篇文章会用一个例子为你把类加载的诸多问题一次性澄清
    2021-06-06

最新评论