mybatis mapper.xml 文件外键映射

文章讲述了在标签管理业务中,如何通过设计中间表和优化查询代码来提高性能,特别关注了当业务层级固定时的查询策略,以及数据库关联对查询效率的影响。

1.业务背景

        最近负责标签管理业务,因为设计打标签功能就需要用到中间表。在之前的写法,将符合的数据先查询出来在应用层做匹配封装。如果是大表关联性复杂考虑到之后的扩展性,这种写法符合要求的,唯一缺点就是让你代码看的很臃肿,常规做法就是循环匹配,但是代码看起很烦。更好的方法就是将查 出的数据转map,这样时间复杂度会快很多基本上是只需要便利一次。

        但是考虑我负责业务背景,他的层级是固定的是两层,虽然我表设计可以无限层,但业务就只需要用到两层。如果是层级不定的还是需要使用上面的方式。

 2.代码实现 

        这是实体类,childs 属性不是数据库字段,用来存放子节点的,

package com.f2bpm.system.models;

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 com.f2bpm.orm.mapper.BaseModel;
import lombok.Data;
import lombok.NonNull;
import lombok.experimental.Accessors;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Null;
import javax.validation.constraints.Size;
import java.time.LocalDateTime;
import java.util.Date;
import java.util.List;

/**
 * @author 作 者:ljl
 * @title 标   题: 标签
 * @date 创建日期:2023-09-06
 * @copyright 版 权:null
 * @description 描 述:null
 */
@Data
@TableName("tb_tag")
@Accessors(chain = true)
public class Tag /*extends BaseModel */{

    /**
     * 标签ID,自增主键
     */
    @NotBlank
    @TableId(type = IdType.ASSIGN_UUID)
    private String tagId;

    /**
     * 标签名称
     */
    private String tagName;

    /**
     * 标签状态,0表示正常,1表示禁用
     */
    @Null(message = "输入类型错误")
    private Integer tagStatus;

    /**
     * 标签类型,0表示标签,1表示分组
     */
    @Null(message = "输入类型错误")
    private Integer tagType;


    /**
     * 创建人
     */
    private String createdBy;

    /**
     * 修改人
     */
    private String updatedBy;

    /**
     * 备注
     */
    private String remark;

    /**
     * 分组
     */
    private String groupId;

    /**
     * 是否支持多选 0 支持 1 不支持
     */
    private Integer multiple;

    /**
     * 创建时间
     */
    private Date createdTime;

    /**
     * 修改时间
     */
    private Date updatedTime;


    /**
     * 子节点
     */
    @TableField(exist = false)
    private List<Tag> childs;

}

         之前关联的其他表,所有只要将其他类的实体类和字段名对应上即可,但是我是自关联,他有是按照查询列的名字进行关系映射,所以下面采用的是给列起别名的方式。他会将查询的数据映射到我childs 属性里,这样我的sever 层 看起来就简单不少。

<mapper namespace="com.f2bpm.system.mapper.TagMapper">

    <resultMap id="TagResult" type="com.f2bpm.system.models.Tag">
        <!--定义表列名和实体属性名之间的映射关系 -->
        <id property="tagId" column="tag_id"/>
        <result property="tagName" column="tag_name"/>
        <result property="tagStatus" column="tag_status"/>
        <result property="tagType" column="tag_type"/>
        <result property="createdBy" column="created_by"/>
        <result property="updatedBy" column="updated_by"/>
        <result property="remark" column="remark"/>
        <result property="createdTime" column="created_time"/>
        <result property="updatedTime" column="updated_time"/>
        <result property="groupId" column="group_id"/>
        <result property="multiple" column="multiple"/>

        <collection property="childs" ofType="com.f2bpm.system.models.Tag">
            <!-- 定义子标签的映射关系 -->
            <id property="tagId" column="childTagId"/>
            <result property="tagName" column="childTagName"/>
            <result property="tagStatus" column="childTagStatus"/>
            <result property="tagType" column="childTagType"/>
            <result property="createdBy" column="childCreatedBy"/>
            <result property="createdTime" column="childCreatedTime"/>
        </collection>
    </resultMap>


    <sql id="selectTagVo">
        SELECT t1.tag_id       as tag_id,
               t1.tag_name     as tag_name,
               t1.tag_status   as tag_status,
               t1.tag_type     as tag_type,
               t1.created_by   as created_by,
               t1.created_time as created_time,
               t1.multiple     as multiple,
               t1.group_id     as group_id,
               t2.tag_id       AS childTagId,
               t2.tag_name     AS childTagName,
               t2.tag_status   AS childTagStatus,
               t2.tag_type     AS childTagType,
               t2.created_by   AS childCreatedBy,
               t2.created_time AS childCreatedTime,
               t2.multiple     AS childIsMultiple
        FROM tb_tag t1
                 LEFT JOIN tb_tag t2 ON t1.tag_id = t2.group_id
    </sql>

    <select id="getList" resultMap="TagResult" parameterType="com.f2bpm.system.models.dto.TagDto">
        <include refid="selectTagVo"/>
        <where>
            t1.group_id IS NULL
            <if test="groupName != null and groupName != ''">
                AND t1.tag_name LIKE CONCAT('%', #{groupName}, '%')
            </if>
            <if test="multiple != null">
                AND t1.multiple = #{multiple}
            </if>
            <if test="state != null">
                AND t1.tag_status = #{state}
                AND t2.tag_status = #{state}
            </if>
            <if test="tagNames != null and tagNames.size() != 0 ">
                AND t2.tag_name = #{tagNames.get(0)}
            </if>
        </where>
        ORDER BY t1.created_time, t1.updated_time DESC
    </select>

        总结

        数据库 关联还是需要确定表的量级, 不然结果集过大必然导致查询数据变慢

根据Java,JavaScript,mysql,c语言,vue3,回答下列问题 1.什么是面向对象编程? 2.Java中的集合包括什么? 3.spring boot三个架构? mapper的作用 4.Mybatis mapper.xml的配置映射 5.Radis 数据结构 6.Redis数据一致性问题 7.Mysql 数据结构 char和varchar的区别 8.Vue生命周期,钩子函数,响应式变量,npm,常用的element -ui 9.springboot常用注解有哪些 10.Nnginx 11.Rocketmq消息延迟 12.Mybatis用法 13.Arralist用过哪些api 14.遍历集合有哪几种 15.MySQL数据类型用过哪些 16.Date和datetime的区别 17.Git常见命令 18.Html标签通常有哪些 css 19.数据采集与分析用的哪个库 20.可视化用的什么技术 21.拦截器 22.常见异常 23.事务 24.组件通信,父组件如何给子组件传递信息 25.路由组件 26.反射 27.线程池,多线程 28.什么是注解(标记) 29.Aop 30.Git 31.idea常用插件 32.什么是反向代理 33.第三方接口 34.Lombok用法 35.Vue3常用的api 36.列举vue3的常用生命周期 37.Vue router 38.遍历数组的方法 39.Foreach和map的区别(有返回值) 40.Radis数据类型? 41.多态 42.Hashmap遍历方式 43.Springboot配置文件的相关知识 44.前端三件套 45.数据库与其的主要内容 46.常见表的关系 47.若依框架 48.Nginx相关内容与配置文件 49.Linux命令 50.后端接口怎么定义的 51.前端如何搭建 52.数据库常见的相关命令语句 53.数据库表设计 54.V-if 55.V-show
最新发布
04-28
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值