SpringBoot+MyBatis实现一对多查询

使用Navicat创建MySQL表

info表(包括id和title, id为主键且自动递增); info_content表(包括id, info_id, content, id为主键且自动递增)。info表为主表,info表中的一条数据对应info_content表中的多条数据:
在这里插入图片描述
在这里插入图片描述

Springboot编写接口

编写实体类:
编写 Info 实体类(entity):

package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

import java.util.List;

@TableName("user")
@Data
public class Info {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private String title;
    //表示以下数据并不是在数据库中存在
    @TableField(exist = false)
    private List<InfoContent> contentList;
}

编写 InfoContent 实体类(entity):

package com.example.demo.entity;

import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;
import lombok.Data;

@TableName("info_content")
@Data
public class InfoContent {
    @TableId(type = IdType.AUTO)
    private Integer id;
    private Integer info_id;
    private String content;
}

Info 中的 contentList 就包含一个或多个 InfoContent 实体。

编写xml文件:
Info.xml 用于定义 SQL查询语句 及 返回结果:

<!DOCTYPE mapper PUBLIC "-//mybatis.org// DTD Mapper 3.0//EN"
        "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.demo.mapper.InfoMapper">

    <resultMap id="infoMap" type="com.example.demo.entity.Info">
        <result property="id" column="id"/>
        <result property="title" column="title"/>
        <collection property="contentList" javaType="ArrayList" ofType="com.example.demo.entity.InfoContent">
            <!-- column对应查询返回的列,property对应返回的对象的属性-->
            <result column="if_content" property="content"/>
        </collection>
    </resultMap>

    <!-- SQL 查询-->
    <select id="findPage" resultMap="infoMap">
        SELECT info.*, info_content.content if_content from info
        left join info_content on info.id = info_content.info_id
    </select>
</mapper>

编写Mapper:
编写 InfoMapper (mapper),在其中定义findPage一对多查询方法(xml文件中select部分的id):

package com.example.demo.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.entity.Info;

public interface InfoMapper extends BaseMapper<Info> {
    //一对多查询
    Page<Info> findPage(Page<Info> page);
}

编写Controller:
编写 UserInfoController (controller)

package com.example.demo.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.example.demo.common.Result;
import com.example.demo.entity.Info;
import com.example.demo.mapper.InfoMapper;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import javax.annotation.Resource;

@RestController
@RequestMapping("/info") //在Vue中引用时需要声明
public class InfoController {
    @Resource
    InfoMapper infoMapper;

    //后台分页模糊查询
    @GetMapping
    public Result<?> findPage(@RequestParam(defaultValue = "1") Integer pageNum,
                              @RequestParam(defaultValue = "10") Integer pageSize,
                              @RequestParam(defaultValue = "") String search){
        LambdaQueryWrapper<Info> wrapper = Wrappers.<Info>lambdaQuery();
        if(StringUtils.isNotBlank(search)){
            wrapper.like(Info::getId,search);
        }
        Page<Info> infoPage = infoMapper.findPage(new Page<>(pageNum,pageSize));
        return Result.success(infoPage);
    }
}

在编写开以上文件之后,运行Spring boot项目,可以通过localhost:****(端口号)/xxxx(接口)查看输出结果
在这里插入图片描述
可以看出取出的contentList是对象数组,但是其实我们真正需要的只是由content值组成的字符串数组,虽然返回的结果不影响使用,但是还是可以进一步优化!

Vue调用接口,读取数据

<template>
    <div>
        <el-card class="box-card">
            <div slot="header" class="clearfix">
                <span>卡片名称</span>
                <el-button style="float: right; padding: 3px 0" type="text" @click="dialogVisible = true">操作按钮</el-button>
            </div>
            <el-collapse v-model="activeNames" accordion> <!-- @change="handleChange"-->
                <el-collapse-item  v-for="item in items" :key="item.id"  :title="item.title" :name="item.id">
                    <div v-for="(v,i) in item.contentList" :key="i">{{v.content}}</div>
                </el-collapse-item>
            </el-collapse>
        </el-card>

        <!--对话框-->
        <el-dialog
        title="提示"
        :visible.sync="dialogVisible"
        width="30%"> <!--:before-close="handleClose"-->
            <span>这是一段信息</span>
            <span slot="footer" class="dialog-footer">
                <el-button @click="dialogVisible = false">取 消</el-button>
                <el-button type="primary" @click="submit()">确 定</el-button>
            </span>
        </el-dialog>
    </div>
</template>

<script>
    import request from '@/utils/request'
    export default{
        data(){
            return{
              dialogVisible:false,
              activeNames:"1",
              items:[]
            }
        },
        methods: {
            submit(){
                this.dialogVisible = false;
                let _id = this.items.length>0?Math.max(...this.items.map(v=>v.id))+1:1;
                this.items.push({
                    id:_id,
                    title:'这是新添加的数据 == '+_id,
                    contentList:[
                        {content:'这是新添加的数据'}
                    ]
                })
            },
            load(){
                request.get("/info",{
                    pageNum:1,
                    pageSize:10,
                    search:''
                    }).then(res=>{
                    console.log(res);
                    let {code,result,msg} = res;
                    if(code=="0"){
                        this.items = res.data.records;
                        this.activeNames = this.items[0].id || 1;
                    };
                    },err=>{
                    console.log(err)
                })
            }
        },
        mounted(){
            this.load()
        }
    }
</script>

页面展示效果:
在这里插入图片描述

  • 2
    点赞
  • 16
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
假设有两张表,一张是学生表(student),一张是课程表(course),一个学生可以选多门课程,一门课程也可以被多个学生选中。这种情况下,我们可以使用一对多的关系来实现。下面是一个简单的实现代码: 1. 定义学生表(student)和课程表(course)的实体类 ```java public class Student { private Long id; private String name; private List<Course> courses; //省略getter和setter方法 } public class Course { private Long id; private String name; //省略getter和setter方法 } ``` 2. 定义学生表(student)和课程表(course)的mapper接口 ```java public interface StudentMapper { Student selectStudentById(Long id); } public interface CourseMapper { List<Course> selectCoursesByStudentId(Long studentId); } ``` 3. 在StudentMapper.xml中定义一对多的关系 ```xml <mapper namespace="com.example.mapper.StudentMapper"> <resultMap id="studentMap" type="Student"> <id column="id" property="id" /> <result column="name" property="name" /> <collection property="courses" ofType="Course" resultMap="courseMap" /> </resultMap> <resultMap id="courseMap" type="Course"> <id column="id" property="id" /> <result column="name" property="name" /> </resultMap> <select id="selectStudentById" resultMap="studentMap"> SELECT s.id, s.name, c.id AS course_id, c.name AS course_name FROM student s LEFT JOIN student_course sc ON s.id = sc.student_id LEFT JOIN course c ON sc.course_id = c.id WHERE s.id = #{id} </select> </mapper> ``` 4. 在CourseMapper.xml中定义查询课程信息的SQL语句 ```xml <mapper namespace="com.example.mapper.CourseMapper"> <select id="selectCoursesByStudentId" resultType="Course"> SELECT c.id, c.name FROM course c LEFT JOIN student_course sc ON c.id = sc.course_id WHERE sc.student_id = #{studentId} </select> </mapper> ``` 5. 编写Controller和Service层代码 ```java @RestController public class StudentController { @Autowired private StudentService studentService; @GetMapping("/students/{id}") public Student getStudentById(@PathVariable Long id) { return studentService.getStudentById(id); } } @Service public class StudentServiceImpl implements StudentService { @Autowired private StudentMapper studentMapper; @Autowired private CourseMapper courseMapper; @Override public Student getStudentById(Long id) { Student student = studentMapper.selectStudentById(id); List<Course> courses = courseMapper.selectCoursesByStudentId(id); student.setCourses(courses); return student; } } ``` 以上就是一对多实现代码。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值