0
点赞
收藏
分享

微信扫一扫

SpringBoot+MyBatis实现一对多查询

b91bff6ffdb5 2022-04-04 阅读 45

使用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>
举报

相关推荐

0 条评论